LESSON 12 · PERCEPTION

Find a colour region with OpenCV

Build an inspectable image pipeline before using detection models.

Environment and verification

Documented target: Ubuntu 24.04 · ROS 2 Jazzy · Gazebo Harmonic where used. Browser labs tested; ROS/Ubuntu/hardware execution not performed here.

What you will understand

  • Inspect BGR/HSV.
  • Generate a reproducible mask.
  • Explain false positives.

Prerequisites: Read sensors without guessing and its stated environment.

The idea, made clear.

A colour pipeline loads an image, converts it to HSV, thresholds a mask and measures selected pixels. HSV separates hue from brightness better than a simple channel comparison, but lighting and camera settings still influence the result. Always inspect intermediate outputs.

OpenCV reads ordinary colour images in BGR order. Conventional 8-bit HSV uses a hue range different from degree-based colour pickers. Red wraps across the boundary and commonly needs two threshold intervals. Verify representation before choosing limits.

A green wall and green marker may both pass the same mask. Thresholding does not uniquely identify an object. Add shape, context or a suitable model only after measuring false positives. Keep perception experiments disconnected from physical motor commands.

BGR imageHSV conversionThreshold maskPixel count
An original overview of the information or commissioning sequence.

Try it, step by step.

1

Prepare an isolated environment

Use Python 3. OpenCV 4.x is the documented target; record the installed version.

opencv-perception-1.py
python3 -m venv .venv
source .venv/bin/activate
python -m pip install "opencv-python>=4,<5"
python -c "import cv2; print(cv2.__version__)"

Expected: A recorded OpenCV version.

2

Generate a known input

Save colour_mask.py and run it. No external image is needed.

opencv-perception-2.py
import cv2
import numpy as np
image = np.zeros((100, 100, 3), dtype=np.uint8)
image[25:75, 25:75] = (0, 255, 0)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, np.array([40, 80, 80]), np.array([80, 255, 255]))
print(int(np.count_nonzero(mask)))
cv2.imwrite("mask.png", mask)

Expected: 2500 selected pixels and a white-square mask.png.

3

Challenge the threshold

Reduce brightness and vary threshold limits.

Expected: Selection reflects pixel values, not semantic identity.

If something goes wrong

Empty mask
Check conversion, hue range and saturation/value limits.
Background selected
Add validated context; colour alone is insufficient.

Check your understanding

Does colour identify a unique object?

Make it yours

Compare selected fractions at three brightness settings.

Your learning progress

Optional progress stays in this browser. No account needed.

Go to the source documentation

Commands are educational examples for the stated environment, not a transcript of local ROS execution. Verify actual behavior on your machine.

Look up a term · Version notes · Report an issue