Skip to content

Segment Image Using YCrCb

SUMMARY

Segment Image Using YCrCb segments an image by thresholding it in YCrCb color space.

The image is converted to YCrCb (Y = luma/brightness, Cr/Cb = red/blue chrominance) and only the pixels whose [Y, Cr, Cb] values fall within the inclusive [lower_bound, upper_bound] range are kept. Because brightness (Y) is separated from color (Cr, Cb), the chrominance range for a given color — most notably skin tone — stays fairly consistent across different lighting conditions.

Use this Skill when you want to segment objects by chrominance, such as skin-tone ranges, in a way that holds up across brightness changes.

The Skill

python
from telekinesis import cornea

segmented_image = cornea.segment_image_using_ycrcb(
    image=image,
    lower_bound=(0, 133, 77),
    upper_bound=(255, 173, 127),
)
API Reference
Full parameter and return type documentation for segment_image_using_ycrcb.
View Reference →

Example

Input Image

Input image

Original image for YCrCb color segmentation

Output Image

Output image

Segmented image by YCrCb color range

The Code

python
"""
Demonstrates YCrCb color space segmentation.
"""

from loguru import logger
import rerun as rr

from telekinesis import cornea, datatypes

def segment_image_using_ycrcb_example():
    """Segments an image using YCrCb color space range."""
    # ===================== Load Image ==========================================
    image_url = "https://assets.telekinesis.ai/examples/v1/images/David_Schwimmer.jpg"
    image = datatypes.Image.from_url(url=image_url)

    # ===================== Run Skill ==========================================
    segmented_image = cornea.segment_image_using_ycrcb(
        image=image, lower_bound=(0, 133, 77), upper_bound=(255, 173, 127)
    )

    # ===================== Log ================================================
    logger.success(f"Segmented {image} using YCrCb color space range.")
    logger.success(f"Results: {segmented_image}")
    logger.info(f"Segmented image label codes: {segmented_image.label_codes}")
    logger.info(f"Segmented image number of labels: {segmented_image.number_of_labels}")
    logger.info(f"Segmented image shape: {segmented_image.shape}")
    logger.info(f"Segmented image dtype: {segmented_image.dtype}")

    # ===================== Visualization  (Optional) ======================
    rr.init("segment_image_using_ycrcb_example", spawn=True)
    datatypes.visualize(image, entity_path="/input_image")
    datatypes.visualize(segmented_image, entity_path="/segmented_image")


if __name__ == "__main__":
    segment_image_using_ycrcb_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/segment_image_using_ycrcb.py

Parameter Configuration

These parameters control the input image and the inclusive YCrCb range used to decide which pixels are marked as foreground.

KeyTypeDefaultDescription
imagedatatypes.Image | np.ndarrayrequiredInput image to segment, shape (H, W, 3)
lower_boundlist[int] | tuple[int][0, 133, 77]Inclusive lower [Y, Cr, Cb] bound (a typical skin-tone lower bound)
upper_boundlist[int] | tuple[int][255, 173, 127]Inclusive upper [Y, Cr, Cb] bound (a typical skin-tone upper bound)

Returns

TypeDescription
datatypes.SegmentationImageA per-pixel label map, shape (H, W), where 0 marks pixels outside the YCrCb range and 1 marks pixels inside it. Use .data for the raw label array, .label_codes for the sorted array of unique ids present, .number_of_labels for how many distinct labels were found, 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)
ValueErrorlower_bound or upper_bound does not have exactly 3 elements
ConfigurationErrorThe TELEKINESIS_API_KEY environment variable is not set
SerializationErrorThe request input failed to serialize, 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 input, invalid data, or another unexpected 4xx response
AuthenticationErrorThe API key was rejected as invalid or expired
AuthenticationServiceErrorThe authentication service was unavailable
ServerErrorThe Cornea service returned a 5xx or otherwise unexpected error response

How to Tune the Parameters

The segment_image_using_ycrcb skill exposes two parameters that together define the accepted YCrCb range.

In general, a narrower range increases precision by excluding more unrelated pixels, while a wider range is more forgiving of variation in the target color but risks including background pixels that happen to fall inside it.

lower_bound

  • Controls: The inclusive lower [Y, Cr, Cb] bound; a pixel is excluded if any of its channels falls below the corresponding bound.
  • Units: Each channel on a 0–255 scale. Y is luma/brightness; Cr/Cb are red/blue chrominance, roughly centered near 128.
  • Default: [0, 133, 77] (a typical skin-tone lower bound)
  • Keep Y low (near 0) so the full brightness range stays included and the chrominance range remains valid across lighting
  • Narrow Cr/Cb to tighten the accepted chrominance band around the target color
  • Typical range: Y 0–255; Cr/Cb 0–255, tightened around values sampled from the target color

upper_bound

  • Controls: The inclusive upper [Y, Cr, Cb] bound; a pixel is excluded if any of its channels exceeds the corresponding bound.
  • Units: Same as lower_bound.
  • Default: [255, 173, 127] (a typical skin-tone upper bound)
  • Keep Y high (near 255) so the full brightness range stays included
  • Narrow Cr/Cb to tighten the accepted chrominance band around the target color
  • Typical range: Y 0–255; Cr/Cb 0–255, tightened around values sampled from the target color

TIP

Because Y spans its full range by default, adapting these bounds to a new target color mainly means narrowing or shifting Cr/Cb; changing Y mostly affects how much of the brightness range is retained, not which colors are matched.

Where to Use the Skill

Common pipelines include:

  • Skin-tone detection – e.g. locating a person's face or hands in a scene
  • Face-detection preprocessing – producing a coarse region-of-interest mask before a dedicated face detector
  • Human presence / human-robot interaction – detecting a person in frame using a consistent chrominance range
  • Any color-range task that needs to hold up as brightness changes – since Y is separated from Cr/Cb

Alternative Skills

Skillvs. Segment Image Using YCrCb
segment_image_using_hsvHSV is a general-purpose color space built around hue. Use HSV for general color-based segmentation; use YCrCb when the target is specifically skin-tone-like chrominance.
segment_image_using_labLAB is perceptually uniform across all colors rather than tuned to a specific range. Use LAB for perceptually-driven bounds in general; use YCrCb for the skin-tone-style chrominance ranges its defaults are built around.

When Not to Use the Skill

Do not use Segment Image Using YCrCb when:

  • The target isn't skin-tone-like in chrominance – the default bounds won't apply, and a general-purpose color space is a better starting point
  • You need general-purpose color segmentation – HSV is more directly suited
  • Color is not a distinguishing feature of the target – consider a non-color-based segmentation skill instead

TIP

The default bounds [0, 133, 77] to [255, 173, 127] are tuned for skin tones. For any other target color, sample a few known pixels in YCrCb and build the bounds from their Cr/Cb values rather than reusing the defaults.