Filter Image Using Morphological Hitmiss
SUMMARY
Filter Image Using Morphological Hitmiss applies the morphological hit-or-miss transform to a binary mask.
It matches a specific pattern by testing foreground and background pixels simultaneously with a structuring element defined by kernel_size/kernel_shape, keeping only pixels where the pattern matches and zeroing everything else. Unlike the other filter_image_using_morphological_* Skills (gradient, top-hat, black-hat, open, close), which reshape regions, hit-miss searches for a specific local pattern — useful for corner detection, endpoint/branch-point detection after thinning, and custom shape matching.
Use this Skill when you want to detect a specific local binary pattern, such as corners or endpoints, in a mask.
The Skill
from telekinesis import pupil
filtered_image = pupil.filter_image_using_morphological_hitmiss(
image=image,
kernel_size=5,
kernel_shape="ellipse",
iterations=1,
border_type="constant",
border_value=0,
)Example
No screenshot assets are available for this Skill yet. Given the example script's input — a photo of spanners on a workbench (spanners_arranged.jpg), first reduced to a binary mask via cornea.segment_image_using_threshold — the hit-or-miss transform with a 5px elliptical structuring element would zero out every pixel except the ones matching the configured hit/miss pattern (e.g. isolated points, corners, or endpoints along the spanner silhouettes), producing a sparse binary output the same shape as the input mask.
The Code
"""Demonstrates filter_image_using_morphological_hitmiss operation."""
from loguru import logger
import rerun as rr
from telekinesis import pupil, datatypes, cornea
def filter_image_using_morphological_hitmiss_example():
"""Applies filter_image_using_morphological_hitmiss operation."""
# ===================== Load Image ==========================================
image_url = "https://assets.telekinesis.ai/examples/v1/images/spanners_arranged.jpg"
image = datatypes.Image.from_url(image_url)
segmented_image = cornea.segment_image_using_threshold(image=image)
# ===================== Run Skill ==========================================
filtered_image = pupil.filter_image_using_morphological_hitmiss(
image=segmented_image,
kernel_size=5,
kernel_shape="ellipse",
iterations=1,
border_type="constant",
border_value=0,
)
# ===================== Log ================================================
logger.success(f"Applied filter_image_using_morphological_hitmiss on {image}")
logger.success(f"Result: {filtered_image}")
# ===================== Visualization (Optional) ======================
rr.init("filter_image_using_morphological_hitmiss_example", spawn=True)
datatypes.visualize(image, entity_path="1-Original")
datatypes.visualize(filtered_image, entity_path="2-Filtered")
if __name__ == "__main__":
filter_image_using_morphological_hitmiss_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_hitmiss.pyParameter Configuration
| Key | Type | Default | Description |
|---|---|---|---|
image | datatypes.SegmentationImage | np.ndarray | required | The input binary image/mask to process, shape (H, W), dtype uint8 |
kernel_size | datatypes.Int | int | 3 | The size of the structuring element, in pixels |
kernel_shape | datatypes.String | str | "ellipse" | The shape of the structuring element: ellipse, rectangle, cross, or diamond |
iterations | datatypes.Int | int | 1 | The number of times the hit-miss operation is applied |
border_type | datatypes.String | str | "default" | The border handling mode: default, constant, replicate, reflect, or reflect 101 |
border_value | datatypes.Float | float | int | 0.0 | The fill value used only when border_type is "constant" |
Returns
| Type | Description |
|---|---|
datatypes.Image | Same shape as image, with pixels matching the hit-miss pattern set and all others zeroed. |
Raises
| Exception | Condition |
|---|---|
TypeError | image, kernel_size, kernel_shape, iterations, border_type, or border_value has an invalid type, or image's dtype is not np.uint8 |
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_hitmiss Skill controls the size and shape of the pattern-matching structuring element, how many times it is applied, and how the image border is handled.
kernel_size
- Controls: The spatial extent of the structuring element used to test for a pattern match.
- Units: Pixels
- Default:
3 - Increase → matches larger-scale patterns, less sensitive to single-pixel noise
- Decrease → matches finer, more localized patterns
- Typical range: 3-15
kernel_shape
- Controls: The geometric shape of the structuring element.
- Default:
"ellipse" - Options:
ellipse– smooth, isotropic pattern matchingrectangle– axis-aligned, good for general-purpose morphologycross– thinner, useful for directional/line-like patternsdiamond– symmetric along diagonals, well suited to hit-miss and custom pattern detection
iterations
- Controls: How many times the hit-miss operation is applied sequentially.
- Units: Count
- Default:
1 - Increase → re-applies the pattern match to the previous result, useful for iterative pattern search
- Typical range: 1-10
border_type
- Controls: How pixels are synthesized when the structuring element extends past the image boundary.
- Default:
"default" - Options:
default– reflect 101 paddingconstant– pads withborder_value(recommended for hit-miss so a fixed background value doesn't trigger false pattern matches at the border)replicate– repeats the nearest edge pixelreflect– mirrors border pixels without repeating the edgereflect 101– mirror reflection without repeating the edge pixel
TIP
Best practice: Threshold or segment the input into a clean binary mask first (dtype uint8) — hit-miss is a strict pixel-pattern match, so noisy or non-binary input produces unpredictable, sparse results. Use border_type="constant" with border_value=0 to avoid spurious matches at the image edges.
Where to Use the Skill
Common pipelines include:
- Corner/endpoint detection – Find corners or line endpoints in a binary mask, often after
transform_mask_using_blob_thinning - Skeleton analysis – Detect branch points and endpoints on a thinned skeleton
- Custom pattern matching – Search a binary mask for a specific, hand-designed local pixel configuration
- Post-processing for measurement – Extract keypoints for downstream geometric analysis (e.g. counting endpoints)
Alternative Skills
| Skill | vs. Filter Image Using Morphological Hitmiss |
|---|---|
| transform_mask_using_blob_thinning | Reduces blobs to a 1-pixel-wide skeleton; commonly run before hit-miss so patterns like endpoints/branch points are well-defined. |
| filter_image_using_morphological_gradient | Extracts object outlines via dilation minus erosion rather than matching a specific pixel pattern. |
| filter_image_using_morphological_open | Removes small bright noise/protrusions instead of searching for a pattern; useful as a cleanup step before hit-miss. |
When Not to Use the Skill
Do not use Filter Image Using Morphological Hitmiss when:
- The input isn't a clean binary mask (coerce/threshold to a
uint8mask first — hit-miss raisesTypeErroron non-uint8input) - You need a general shape transform rather than a pattern match (use gradient/open/close/top-hat/black-hat instead)
- You don't know the exact pixel pattern you're looking for (hit-miss matches a fixed configuration; use contour or blob detection for general shape analysis instead)
- The mask is noisy or only loosely thresholded (spurious pixels will produce false pattern matches)

