You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Python-OpenCV的cv2.inRange检测并定义两种非相邻颜色范围?

Solution for Detecting Non-Adjacent Colors (Red & Blue) in OpenCV HSV Space

Hey there! I get why you might have hit a snag trying to detect red and blue together—since they’re non-adjacent in the HSV spectrum, you can’t use a single continuous range mask. Instead, we need to create separate masks for each color and combine them. Let’s break this down with a working Python-OpenCV implementation using the exact HSV ranges you provided.

Step-by-Step Implementation

1. Import Required Libraries

First, make sure you have numpy and opencv-python installed, then import them:

import cv2
import numpy as np

2. Load Image & Convert to HSV

OpenCV reads images in BGR format by default, so we need to convert it to HSV for reliable color detection:

# Load your image (replace 'input_image.jpg' with your actual image path)
img = cv2.imread('input_image.jpg')
# Convert BGR to HSV color space
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

3. Create Masks for Red and Blue

Use your predefined HSV ranges to generate binary masks—each mask will have white pixels (255) where the color matches, and black (0) elsewhere:

# Your provided HSV color ranges
lower_red = np.array([160, 20, 70])
upper_red = np.array([190, 255, 255])
lower_blue = np.array([101, 50, 38])
upper_blue = np.array([110, 255, 255])

# Generate masks for each color
mask_red = cv2.inRange(hsv_img, lower_red, upper_red)
mask_blue = cv2.inRange(hsv_img, lower_blue, upper_blue)

4. Combine the Masks

Since we want to detect either red or blue, we use a bitwise OR operation to merge the two masks into a single combined mask:

combined_mask = cv2.bitwise_or(mask_red, mask_blue)

5. (Optional) Clean Up Noise with Morphological Operations

If your mask has small unwanted noise dots, you can apply morphological operations to smooth it out:

# Create a small kernel for noise removal
kernel = np.ones((5, 5), np.uint8)
# Apply opening (erosion + dilation) to eliminate tiny noise spots
clean_mask = cv2.morphologyEx(combined_mask, cv2.MORPH_OPEN, kernel)

6. Visualize or Extract Detected Regions

You can either overlay the mask on the original image to see detected areas, or extract the color regions directly:

# Option 1: Overlay mask on original image to highlight detected colors
result = cv2.bitwise_and(img, img, mask=clean_mask)

# Display all windows for comparison
cv2.imshow('Original Image', img)
cv2.imshow('Combined Mask', clean_mask)
cv2.imshow('Detected Red & Blue', result)

# Wait for a key press to close all windows
cv2.waitKey(0)
cv2.destroyAllWindows()

Why Your Previous Attempts Might Have Failed

  • Using a single if condition to check pixel values against both ranges is inefficient and error-prone—OpenCV’s inRange is optimized for bulk pixel operations, and combining masks is the standard approach for multiple non-overlapping color ranges.
  • If you tried merging the HSV ranges into one continuous interval, you’d end up including unwanted colors between red and blue, which is why separate masks are necessary.

Pro Tips

  • If you notice your red detection misses some shades, remember red wraps around the HSV hue circle (0-10 and 160-180 are both valid red ranges). You can add the lower red range (lower_red2 = np.array([0,20,70]), upper_red2 = np.array([10,255,255])) and merge it with your existing red mask using cv2.bitwise_or(mask_red, mask_red2).
  • Adjust the HSV ranges slightly if detection isn’t perfect—lighting conditions drastically affect how colors appear in HSV. You can use an HSV color picker tool to fine-tune values for your specific scenario.

内容的提问来源于stack exchange,提问作者Nhiên Ngô Định

火山引擎 最新活动