Filter Image Using Morphological Open
SUMMARY
Filter Image Using Morphological Open applies morphological opening (erosion followed by dilation).
Opening first erodes the image to remove small bright objects and thin connections, then dilates the result back, restoring the approximate size of whatever survived the erosion. Net effect: small noise and protrusions smaller than the structuring element (kernel_size/kernel_shape) disappear, while larger objects keep close to their original size and shape. Compare with filter_image_using_morphological_close (dilation then erosion), which fills small holes/gaps instead of removing small objects.
Use this Skill when you want to remove small bright noise from an image while keeping larger objects at their original size.
The Skill
from telekinesis import pupil
filtered_image = pupil.filter_image_using_morphological_open(
image=image,
kernel_size=3,
kernel_shape="ellipse",
iterations=2,
border_type="constant",
border_value=0,
)Example
Input Image

Original image with noise and thin connections
Opened Image

Opened image — small noise removed, main objects preserved at their original size
The Code
"""Demonstrates morphological opening transformation."""
from loguru import logger
import rerun as rr
from telekinesis import pupil, datatypes
def filter_image_using_morphological_open_example():
"""Applies open morphological operation."""
# ===================== Load Image ==========================================
image_url = "https://assets.telekinesis.ai/examples/v1/images/broken_cables.png"
image = datatypes.Image.from_url(image_url)
# ===================== Run Skill ==========================================
filtered_image = pupil.filter_image_using_morphological_open(
image=image,
kernel_size=3,
kernel_shape="ellipse",
iterations=2,
border_type="constant",
border_value=0,
)
# ===================== Log ================================================
logger.success(f"Applied open morphological operation on {image}")
logger.success(f"Result: {filtered_image}")
# ===================== Visualization (Optional) ======================
rr.init("filter_image_using_morphological_open_example", spawn=True)
datatypes.visualize(image, entity_path="1-Original")
datatypes.visualize(filtered_image, entity_path="2-Opened")
if __name__ == "__main__":
filter_image_using_morphological_open_example()Runnable examples are available in the Telekinesis examples repository.
Follow the README in that repository to set up the environment, run this specific example with:
cd telekinesis-examples
python examples/image_processing/filter_image_using_morphological_open.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
image | datatypes.Image | np.ndarray | required | Input image to process, recommended to be a binary image/mask, shape (H, W) |
kernel_size | datatypes.Int | int | 3 | Size of the structuring element, in pixels |
kernel_shape | datatypes.String | str | "ellipse" | Shape of the structuring element: ellipse, rectangle, cross, or diamond |
iterations | datatypes.Int | int | 1 | Number of times opening is applied sequentially |
border_type | datatypes.String | str | "default" | Border handling mode: default, constant, replicate, reflect, or reflect 101 |
border_value | datatypes.Float | float | int | 0.0 | Value used for the "constant" border, only used when border_type is "constant"; can be negative depending on the image dtype |
Returns
| Type | Description |
|---|---|
datatypes.Image | Same shape as image, with small bright objects/noise removed |
Raises
| Exception | Condition |
|---|---|
TypeError | image, kernel_size, kernel_shape, iterations, border_type, or border_value has an invalid type |
ValueError | kernel_shape or border_type is not one of the supported options |
ConfigurationError | The TELEKINESIS_API_KEY environment variable is not set |
SerializationError | The request input failed to serialize, or the response failed to deserialize |
RequestTimeoutError | The request to the Pupil service timed out |
TransportError | A network failure occurred before a response was received |
ClientError | The Pupil service rejected the request due to invalid input, invalid data, or another unexpected 4xx response |
AuthenticationError | The API key was rejected as invalid or expired |
AuthenticationServiceError | The authentication service was unavailable |
ServerError | The Pupil service returned a 5xx or otherwise unexpected error response |
How to Tune the Parameters
The filter_image_using_morphological_open Skill exposes the structuring element's size and shape, an iteration count, and border handling. kernel_size is the key parameter: it determines what counts as "noise" versus "signal" — anything smaller than the structuring element gets removed by the erosion step and never comes back in the dilation step.
kernel_size
- Controls: The size of the structuring element used for both the erosion and dilation steps.
- Units: Pixels
- Default:
3 - Increase → removes larger noise and small objects
- Decrease → keeps more detail, removing only very small noise
- Typical range: 3-15 (use 3-5 for fine noise, 5-9 for moderate noise, 9-15 for larger speckles or thin connections)
kernel_shape
- Controls: The geometric shape of the structuring element.
- Default:
"ellipse" - Options:
ellipse– smooth, isotropic opening; the default for most casesrectangle– axis-aligned, isotropic in rows/columnscross– thinner, directionally sensitive to line-like structuresdiamond– symmetric along diagonals
iterations
- Controls: How many times opening is applied sequentially.
- Units: Count
- Default:
1 - Increase → removes progressively larger noise, but too many iterations can also strip valid small features
- Decrease → less aggressive removal
- Typical range: 1-10
border_type
- Controls: How pixels near image edges are handled when the structuring element extends past the boundary.
- Default:
"default" - Options:
default– same asreflect 101, the library's default for most operationsconstant– pads withborder_valuereplicate– replicates the edge pixelreflect– reflects without repeating the edge pixelreflect 101– reflects with the edge pixel repeated, often best for avoiding dark borders
TIP
Best practice: Opening is the default choice for binary mask cleanup. Set kernel_size slightly larger than the noise you want to remove but smaller than the smallest feature you need to keep.
Where to Use the Skill
Common pipelines include:
- Binary mask cleanup – Remove salt-noise speckles left over from thresholding
- Object separation – Break thin connections between objects that should be counted separately
- Preprocessing for counting – Clean up objects before a downstream counting or measurement step
- Segmentation refinement – Remove spurious small regions from a segmentation mask
Alternative Skills
| Skill | vs. Filter Image Using Morphological Open |
|---|---|
| filter_image_using_morphological_close | Dilation then erosion, fills holes instead of removing noise. Use opening for noise removal, closing for hole filling. |
| filter_image_using_morphological_erode | The erosion step alone, without the restorative dilation — shrinks objects rather than preserving their size. |
| filter_image_using_median_blur | Removes noise on grayscale images without a binary structuring-element model. Use opening for binary masks, median blur for grayscale noise. |
When Not to Use the Skill
Do not use Filter Image Using Morphological Open when:
- You need to fill holes instead of remove noise (use
filter_image_using_morphological_closeinstead) - Small features in the mask are meaningful, not noise (opening will remove them along with actual noise)
- The input is grayscale rather than a binary mask (use
filter_image_using_median_blurorfilter_image_using_gaussian_blurinstead) - You need to preserve thin structures (opening will erode them away in the first step)

