Skip to content

Filter Segments By Color

SUMMARY

Filter Segments By Color removes segments from an existing label map whose mean pixel intensity falls outside a given range.

It is a post-processing step, not a standalone segmenter: it takes the labels produced by a prior segmentation call (e.g. segment_image_using_felzenszwalb or segment_image_using_slic_superpixel) together with the original image, computes each segment's average intensity over that segment's pixels in image, and relabels as background any segment whose average intensity falls outside [min_color, max_color]. Use it to keep only bright or dark regions of interest, such as discarding superpixels that fall on a uniformly bright background.

Use this Skill when you want to discard segments from a label map whose average color intensity falls outside a given range.

The Skill

python
from telekinesis import cornea

filtered_image = cornea.filter_segments_by_color(
    image=image,
    labels=labels,
    min_color=0,
    max_color=125.0,
)
API Reference
Full parameter and return type documentation for filter_segments_by_color.
View Reference →

Example

Input Image

Input image

Original image with superpixels

Output Image

Output image

Filtered image - only superpixels within color range shown

The Code

python
"""
Demonstrates filtering superpixels based on color.
"""

from loguru import logger
import rerun as rr
import rerun.blueprint as rrb

from telekinesis import cornea, datatypes

def filter_segments_by_color_example():
    """Filters superpixels based on color criteria."""
    # ===================== Load Image ==========================================
    image_url = "https://assets.telekinesis.ai/examples/v1/images/eggs_carton.jpg"
    image = datatypes.Image.from_url(url=image_url)

    # ===================== Run Skill ==========================================
    superpixel_segmentation_image = cornea.segment_image_using_felzenszwalb(
        image=image, scale=500, sigma=1, min_size=200
    )
    filtered_image = cornea.filter_segments_by_color(
        image=image, labels=superpixel_segmentation_image,
        min_color=0, max_color=125.0
    )

    # ===================== Log ================================================
    logger.success(f"Filtered {image} superpixels by color.")
    logger.success(f"Results: {filtered_image}")
    logger.info(f"Filtered image label codes: {filtered_image.label_codes}")
    logger.info(f"Filtered image number of labels: {filtered_image.number_of_labels}")
    logger.info(f"Filtered image shape: {filtered_image.shape}")
    logger.info(f"Filtered image dtype: {filtered_image.dtype}")

    # ===================== Visualization  (Optional) ======================
    rr.init("filter_segments_by_color_example", spawn=True)
    blueprint = rrb.Horizontal(
        rrb.Spatial2DView(origin="/input_image", name="Input"),
        rrb.Spatial2DView(origin="/filtered_image", name="Output"),
    )
    rr.send_blueprint(blueprint)
    datatypes.visualize(image, entity_path="/input_image")
    datatypes.visualize(filtered_image, entity_path="/filtered_image")


if __name__ == "__main__":
    filter_segments_by_color_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:

bash
cd telekinesis-examples
python examples/segmentation/filter_segments_by_color.py

Parameter Configuration

ParameterTypeDefaultDescription
imagedatatypes.Image | np.ndarrayrequiredThe original image the segments were computed from, shape (H, W, 3)
labelsdatatypes.SegmentationImage | np.ndarrayrequiredThe label map to filter, typically the output of another Cornea segmentation skill, shape (H, W)
min_colordatatypes.Float | float0.0Minimum mean intensity, in [0.0, 255.0] for a standard 8-bit image, a segment must have to be kept
max_colordatatypes.Float | float255.0Maximum mean intensity a segment may have to be kept

Returns

TypeDescription
datatypes.SegmentationImageA per-pixel label map, shape (H, W), with the out-of-range segments removed. Use .data for the raw label array, .label_codes for the sorted array of unique ids remaining, .number_of_labels for how many segments survived the filter, and .shape/.dtype for its size and label dtype.

Raises

ExceptionCondition
TypeErrorA parameter's value does not match its expected type (see the Parameter Configuration table above)
ValueErrorimage is not shape (H, W, 3), min_color/max_color is outside [0.0, 255.0], or min_color is not less than max_color
ConfigurationErrorThe TELEKINESIS_API_KEY environment variable is not set
SerializationErrorThe request input failed to serialize, the response was not returned as an Arrow stream, or the response failed to deserialize
RequestTimeoutErrorThe request to the Cornea service timed out
TransportErrorA network failure occurred before a response was received
ClientErrorThe Cornea service rejected the request due to invalid or malformed input (HTTP 400/422), an unrecognized endpoint (HTTP 404), or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired (HTTP 401)
AuthenticationServiceErrorThe authentication service returned an invalid response, was temporarily unavailable, or timed out (HTTP 502/503/504)
ServerErrorThe Cornea service returned a 5xx or otherwise unexpected error response

How to Tune the Parameters

The filter_segments_by_color Skill exposes two thresholds that together define the mean-intensity range a segment must fall within to survive the filter.

min_color

  • Controls: The minimum mean intensity a segment must have, averaged over its pixels in image.
  • Units: Pixel intensity, [0.0, 255.0] for a standard 8-bit image
  • Default: 0.0
  • Increase → discards darker segments
  • Decrease → keeps darker segments that would otherwise be dropped
  • Typical range: 0–200

max_color

  • Controls: The maximum mean intensity a segment may have.
  • Units: Pixel intensity, [0.0, 255.0] for a standard 8-bit image
  • Default: 255.0
  • Decrease → discards brighter segments
  • Increase → keeps brighter segments that would otherwise be dropped
  • Typical range: 50–255

TIP

Sample the mean intensity of a few segments you want to keep (and a few you want to drop) before choosing min_color/max_color, so the range brackets your objects of interest rather than the background.

Where to Use the Skill

Common pipelines include:

  • Background removal – Drop background-colored superpixels produced by segment_image_using_felzenszwalb or segment_image_using_slic_superpixel
  • Color-based object filtering – Keep only segments whose intensity matches an object of interest, such as a darker component on a light conveyor
  • Material sorting – Retain segments whose average intensity corresponds to a specific material or finish
  • Pipeline cleanup – Narrow a superpixel map down to plausible object candidates before area or mask filtering

Alternative Skills

Skillvs. Filter Segments By Color
filter_segments_by_areaFilters the same kind of label map by each segment's pixel count instead of its mean intensity. Often chained after or before this filter.
filter_segments_by_maskFilters the label map by spatial overlap with a region-of-interest mask instead of color. Use together to combine color and location constraints.
segment_image_using_felzenszwalbA primary segmenter that produces the labels this Skill filters. Run it first.
segment_image_using_slic_superpixelAnother primary segmenter whose output labels this Skill can filter. Run it first.

When Not to Use the Skill

Do not use Filter Segments By Color when:

  • Color is not distinguishing between the segments you want and don't want - a size or location filter will be more reliable
  • The distinguishing property is size, not intensity - use filter_segments_by_area instead
  • The distinguishing property is spatial location, not intensity - use filter_segments_by_mask instead
  • You don't yet have a labels map - run a segmentation skill such as segment_image_using_felzenszwalb or segment_image_using_slic_superpixel first

TIP

min_color/max_color compare against each segment's average intensity, so a segment with strong internal contrast (e.g. half bright, half dark) may pass the filter even if neither of its halves individually sits inside the range.