Configure a color_detector
The color_detector vision service is a heuristic detector that draws boxes around connected regions of a specified hue. It runs entirely on the machine with no ML model. Use it for any task where the target stands out by color: red objects on a conveyor, green plants against soil, a blue marker against a wall.
The detector cannot detect black, white, or perfect grays (pixels whose red, green, and blue values are equal). It only detects hues on the color wheel.
Tip
Object colors vary dramatically with lighting. Verify your target color value under actual lighting conditions. Tools like Color Picker for Chrome can extract a hex color from a screenshot of the camera feed. If the color is not reliably detected, increase hue_tolerance_pct.
Configure
- Navigate to the CONFIGURE tab of your machine’s page.
- Click the + icon next to your machine part and select Configuration block.
- In the search field, type
color detectorand select thevision/color_detectorresult. - Click Add component, enter a name, and click Add component again to confirm.
- Choose a color and a hue tolerance, then set a segment size in pixels.
- Select a default camera.

"services": [
{
"name": "<service_name>",
"api": "rdk:service:vision",
"model": "color_detector",
"attributes": {
"detect_color": "#RRGGBB",
"hue_tolerance_pct": <number>,
"segment_size_px": <integer>,
"saturation_cutoff_pct": <number>,
"value_cutoff_pct": <number>,
"label": "<label>",
"camera_name": "<camera-name>"
}
}
]
"services": [
{
"name": "blue_square",
"api": "rdk:service:vision",
"model": "color_detector",
"attributes": {
"detect_color": "#1C4599",
"hue_tolerance_pct": 0.07,
"segment_size_px": 100,
"value_cutoff_pct": 0.15,
"label": "blue",
"camera_name": "camera-1"
}
},
{
"name": "green_triangle",
"api": "rdk:service:vision",
"model": "color_detector",
"attributes": {
"detect_color": "#62963F",
"hue_tolerance_pct": 0.05,
"segment_size_px": 200,
"value_cutoff_pct": 0.20,
"label": "green",
"camera_name": "camera-1"
}
}
]
Attributes
| Attribute | Type | Required? | Description |
|---|---|---|---|
detect_color | string | Required | The target color in hex format (#RRGGBB). Must not be black, white, or any grayscale value. |
hue_tolerance_pct | float | Required | How much hue variation to accept, between 0.0 (exact match) and 1.0 (any color). Start at 0.05 and increase if detection is unreliable. Values outside (0.0, 1.0] fail at startup. |
segment_size_px | int | Required | Minimum pixel area of a connected color region for it to count as a detection. Filters out small noise blobs. |
saturation_cutoff_pct | float | Optional | Pixels with HSV saturation below this are treated as gray and ignored. Must be in [0.0, 1.0].Default: 0.2 |
value_cutoff_pct | float | Optional | Pixels with HSV value (brightness) below this are treated as black and ignored. Must be in [0.0, 1.0].Default: 0.3 |
label | string | Optional | Label applied to detected bounding boxes. If unset, detections have no label. |
camera_name | string | Optional | Default camera for calls such as GetDetectionsFromCamera. Must name a configured camera. |
Info
hue_tolerance_pct, saturation_cutoff_pct, and value_cutoff_pct describe cutoff thresholds using the HSV color model. They do not specify the absolute saturation or brightness of the target color. hue_tolerance_pct controls how strictly the detector matches your detect_color; the saturation and value cutoffs filter out pixels that are too gray or too dark before matching.
Test your detector
Live camera footage
- Open your machine in the Viam app and either click the vision service’s Test area or navigate to the CONTROL tab and select the vision service.
- In the Camera dropdown, select the camera whose feed you want the detector to run on. Detections appear as bounding boxes on the live camera feed and refresh automatically.

For a continuous overlay, configure a transform camera:
{
"pipeline": [
{
"type": "detections",
"attributes": {
"confidence_threshold": 0.5,
"detector_name": "<vision-service-name>",
"valid_labels": ["<label>"]
}
}
],
"source": "<camera-name>"
}
Code
from viam.components.camera import Camera
from viam.services.vision import VisionClient
robot = await connect()
camera_name = "camera-1"
cam = Camera.from_robot(robot, camera_name)
my_detector = VisionClient.from_robot(robot, "blue_square")
# Get detections from the camera in one call
detections = await my_detector.get_detections_from_camera(camera_name)
# Or capture an image first, then run detections on it
images, _ = await cam.get_images()
img = images[0]
detections_from_image = await my_detector.get_detections(img)
await robot.close()
import (
"go.viam.com/rdk/components/camera"
"go.viam.com/rdk/services/vision"
)
cameraName := "camera-1"
myCam, err := camera.FromProvider(machine, cameraName)
if err != nil {
logger.Fatalf("cannot get camera: %v", err)
}
myDetector, err := vision.FromProvider(machine, "blue_square")
if err != nil {
logger.Fatalf("cannot get vision service: %v", err)
}
// Get detections from the camera in one call
detections, err := myDetector.DetectionsFromCamera(context.Background(), cameraName, nil)
if err != nil {
logger.Fatalf("could not get detections: %v", err)
}
if len(detections) > 0 {
logger.Info(detections[0])
}
// Or capture an image first, then run detections on it
img, err := camera.DecodeImageFromCamera(context.Background(), myCam, nil, nil)
if err != nil {
logger.Fatalf("could not decode image: %v", err)
}
detectionsFromImage, err := myDetector.Detections(context.Background(), img, nil)
if err != nil {
logger.Fatalf("could not get detections: %v", err)
}
if len(detectionsFromImage) > 0 {
logger.Info(detectionsFromImage[0])
}
Troubleshooting
Next steps
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!
