Welcome to K230 Vision Module repository
15. Color Segmentation
Color Segmentation
Color SegmentationPrefaceExample ResultsPrinciple ExplanationHSV Threshold SegmentationRed Hue WraparoundCode OverviewInitialize Camera and Display ModuleSet Color Thresholds and ModeConvert Color and Generate MaskOpening Operation for DenoisingHighlight Target RegionResource ReleaseParameter Adjustment Notes
Preface
This tutorial applies to firmware version: CanMV_K230_YAHBOOM_micropython_v1.8-13. You can download it from the Jianan website https://download.kendryte.com/developer/releases/canmv_k230_micropython/daily_build/

Example Results
Run the example code for this section 13.camera_inRange_color.py.
This section converts live BGR images to HSV space, uses inRange() to segment red, green, blue, and yellow colors, applies opening operation to remove small noise, and overlays the mask onto the green channel to create a highlight effect.




Principle Explanation
HSV Threshold Segmentation
HSV separates hue, saturation, and value. inRange() checks whether each pixel's three components are simultaneously between the lower and upper limits, outputting 255 within the range and 0 outside.
The thresholds used in the source code are as follows:
| mode | Color | H Range | S Range | V Range |
|---|---|---|---|---|
| 0 | Red | 0~10 | 100~255 | 100~255 |
| 1 | Green | 35~85 | 60~255 | 60~255 |
| 2 | Blue | 100~130 | 100~255 | 100~255 |
| 3 | Yellow | 20~35 | 100~255 | 100~255 |
The S and V lower limits can exclude low-saturation grayish-white areas and overly dark pixels.
Red Hue Wraparound
In 8-bit OpenCV HSV, H is typically 0~179. Red is at both ends of the hue axis. The source code only covers the low hue segment of 0~10, so reddish-purple or red in the 170~179 range may be missed. Complete red segmentation should establish two mask segments and merge them.
Code Overview
Initialize Camera and Display Module
W, H = 640, 480sensor = Sensor(width=1280, height=960, fps=90)sensor.reset()sensor.set_framesize(width=W, height=H)sensor.set_pixformat(Sensor.RGB888)Display.init(Display.ST7701, width=640, height=480, to_ide=True)sensor.run()time.sleep(0.5)Set Color Thresholds and Mode
xxxxxxxxxxcth = [ [0, 100, 100, 10, 255, 255], [35, 60, 60, 85, 255, 255], [100, 100, 100, 130, 255, 255], [20, 100, 100, 35, 255, 255]]mode = 0k = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))The source code defaults to detecting red. The morphological kernel is created outside the main loop to avoid per-frame reallocation.
Convert Color and Generate Mask
xxxxxxxxxxhsv = cv2.cvtColor(img_np, cv2.COLOR_BGR2HSV)threshold = cth[mode]low = np.array([threshold[0], threshold[1], threshold[2]])high = np.array([threshold[3], threshold[4], threshold[5]])mask = cv2.inRange(hsv, low, high)Both upper and lower limit arrays contain H, S, and V components. If any component is outside the range, the output mask pixel is 0.
Opening Operation for Denoising
xxxxxxxxxxmask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, k)The 3×3 elliptical kernel removes small white spots. If the target region has internal holes, you can add closing operation after opening, but it increases computation.
Highlight Target Region
xxxxxxxxxximg_np[:, :, 1] = cv2.add(img_np[:, :, 1], mask)Display.show_image(img)The mask is added to channel 1, making detected regions more greenish. cv2.add() uses saturation addition; results exceeding 255 remain 255 without 8-bit wraparound.
Resource Release
xxxxxxxxxxfinally: sensor.stop() Display.deinit() os.exitpoint(os.EXITPOINT_ENABLE_SLEEP) time.sleep_ms(100)Parameter Adjustment Notes
- Sample First Then Set Threshold: Read the target HSV under actual camera, lighting, and material conditions, then set the range around the sample.
- S Lower Limit: Increasing can exclude grayish-white background but may miss low-saturation targets.
- V Lower Limit: Increasing can exclude shadows and dark areas but leads to more missed detections in low light.
- Red Dual Range: Call inRange() separately for 0~10 and 170~179, then merge with bitwise_or().
- Morphological Kernel: When noise points are larger than 3×3, you can use 5×5, but confirm it does not erode small targets.
- Result Statistics: When you need area or target count, use countNonZero(), findContours(), or connected component analysis on mask.