Filter Image Using Morphological Close
SUMMARY
Filter Image Using Morphological Close applies morphological closing (dilation followed by erosion).
Closing first dilates the image to fill small holes and gaps and bridge nearby components, then erodes the result back, restoring the approximate original size of what remains. Net effect: holes and gaps smaller than the structuring element (kernel_size/kernel_shape) disappear while overall object shape and size stay close to the original. Compare with filter_image_using_morphological_open (erosion then dilation), which removes small bright noise/protrusions instead of filling holes.
Use this Skill when you want to fill small holes or gaps and connect nearby components while preserving overall object shape.
The Skill
from telekinesis import pupil
filtered_image = pupil.filter_image_using_morphological_close(
image=image,
kernel_size=5,
kernel_shape="ellipse",
iterations=5,
border_type="default",
)Example
Input Image

Original image with holes and gaps
Closed Image

Closed image — holes filled, nearby objects connected
The Code
"""Demonstrates morphological closing to fill small holes and close gaps."""
from loguru import logger
import rerun as rr
from telekinesis import pupil, datatypes
def filter_image_using_morphological_close_example():
"""Applies close morphological operation to fill holes and close gaps."""
# ===================== Load Image ==========================================
image_url = "https://assets.telekinesis.ai/examples/v1/images/nuts_scattered.jpg"
image = datatypes.Image.from_url(image_url)
# ===================== Run Skill ==========================================
filtered_image = pupil.filter_image_using_morphological_close(
image=image,
kernel_size=5,
kernel_shape="ellipse",
iterations=5,
border_type="default",
)
# ===================== Log ================================================
logger.success(f"Applied close morphological operation on {image}")
logger.success(f"Result: {filtered_image}")
# ===================== Visualization (Optional) ======================
rr.init("filter_image_using_morphological_close_example", spawn=True)
datatypes.visualize(image, entity_path="1-Original")
datatypes.visualize(filtered_image, entity_path="2-Closed")
if __name__ == "__main__":
filter_image_using_morphological_close_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_close.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 closing 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 holes/gaps closed |
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_close Skill exposes the structuring element's size and shape, an iteration count, and border handling. kernel_size is the key parameter: it determines the largest hole or gap that can be closed.
kernel_size
- Controls: The size of the structuring element used for both the dilation and erosion steps.
- Units: Pixels
- Default:
3 - Increase → fills larger holes and connects more distant components
- Decrease → less aggressive filling
- Typical range: 3-15 (use 3-5 for small holes, 5-9 for moderate gaps, 9-15 for large holes)
kernel_shape
- Controls: The geometric shape of the structuring element.
- Default:
"ellipse" - Options:
ellipse– smooth, isotropic closing; 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 closing is applied sequentially.
- Units: Count
- Default:
1 - Increase → fills progressively larger holes and bridges wider gaps
- Decrease → less aggressive filling
- 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: Closing is the default choice for filling holes in a segmented object. Set kernel_size slightly larger than the holes you want to fill — an oversized kernel will bridge gaps between objects that should stay separate.
Where to Use the Skill
Common pipelines include:
- Segmentation cleanup – Fill holes left inside a detected object's mask
- Region connection – Merge closely spaced regions that represent a single physical object
- Mask refinement – Clean up a segmentation mask before measuring area, contours, or centroid
- Feature completion – Complete a partially detected object outline before further processing
Alternative Skills
| Skill | vs. Filter Image Using Morphological Close |
|---|---|
| filter_image_using_morphological_open | Erosion then dilation, removes noise instead of filling holes. Use closing to fill small holes, opening to remove small objects. |
| filter_image_using_morphological_dilate | The dilation step alone, without the restorative erosion — expands objects rather than preserving their size. |
When Not to Use the Skill
Do not use Filter Image Using Morphological Close when:
- You need to remove noise instead of fill holes (use
filter_image_using_morphological_openinstead) - You need to separate touching objects (use
filter_image_using_morphological_erodeorfilter_image_using_morphological_openinstead) - The holes are meaningful features, not defects (closing will fill them away)
- You need to preserve fine boundary detail (closing smooths concave boundaries as a side effect)

