You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV Python中HSV图像颜色过滤原理及单颜色过滤实现咨询

Hey Danny, let's tackle your OpenCV questions step by step—they're super common for computer vision projects like your field object recognition task!

1. How to Implement HSV Color Filtering in OpenCV Python

HSV (Hue, Saturation, Value) is way more intuitive for color-based filtering than BGR because it separates color information from brightness. Here's a straightforward workflow:

  • Step 1: Convert your image to HSV
    First, read your image and switch from BGR (OpenCV's default format) to HSV using cv2.cvtColor():

    import cv2
    import numpy as np
    
    img = cv2.imread('your_image.png')
    hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    
  • Step 2: Define your target color's HSV range
    This is the tricky part—you need to know the HSV values for the color you want to filter. You can:

    • Tweak values manually (remember OpenCV scales Hue from 0-179, not 0-360, and Saturation/Value from 0-255)
    • Build a quick interactive tool with trackbars to adjust ranges in real-time (I'll share a script for this below)
  • Step 3: Create a mask
    Use cv2.inRange() to generate a binary mask where pixels within your HSV range are white (255) and others are black (0):

    lower_bound = np.array([h_min, s_min, v_min])
    upper_bound = np.array([h_max, s_max, v_max])
    mask = cv2.inRange(hsv_img, lower_bound, upper_bound)
    
  • Step 4: Apply the mask to your image
    Use cv2.bitwise_and() to keep only the pixels that match the mask:

    filtered_img = cv2.bitwise_and(img, img, mask=mask)
    cv2.imshow('Filtered Result', filtered_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
2. Fixing Your Field Object Recognition Code & Single-Color Filtering

Let's start with why your current code removes green—you didn't actually set a green range! Your bounds [0,0,150] to [255,255,255] are selecting all bright pixels (since Value ranges from 150-255, covering full Hue and Saturation). Most field greenery is darker (lower Value), so those pixels get excluded from the mask—hence why green gets removed. That was a happy accident, not intentional green filtering!

How to Filter (or Keep) a Single Color

First, let's make a tool to find the right HSV ranges for your specific field images. Run this script, load your image, and adjust the sliders until the mask shows exactly the color you want to target:

import cv2
import numpy as np

def nothing(x):
    pass

# Load image
img = cv2.imread('pic1.png')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# Create window with trackbars
cv2.namedWindow('HSV Tuner')
cv2.createTrackbar('H Min', 'HSV Tuner', 0, 179, nothing)
cv2.createTrackbar('H Max', 'HSV Tuner', 179, 179, nothing)
cv2.createTrackbar('S Min', 'HSV Tuner', 0, 255, nothing)
cv2.createTrackbar('S Max', 'HSV Tuner', 255, 255, nothing)
cv2.createTrackbar('V Min', 'HSV Tuner', 0, 255, nothing)
cv2.createTrackbar('V Max', 'HSV Tuner', 255, 255, nothing)

while True:
    # Get trackbar values
    h_min = cv2.getTrackbarPos('H Min', 'HSV Tuner')
    h_max = cv2.getTrackbarPos('H Max', 'HSV Tuner')
    s_min = cv2.getTrackbarPos('S Min', 'HSV Tuner')
    s_max = cv2.getTrackbarPos('S Max', 'HSV Tuner')
    v_min = cv2.getTrackbarPos('V Min', 'HSV Tuner')
    v_max = cv2.getTrackbarPos('V Max', 'HSV Tuner')

    # Create mask and filtered image
    lower = np.array([h_min, s_min, v_min])
    upper = np.array([h_max, s_max, v_max])
    mask = cv2.inRange(hsv, lower, upper)
    res = cv2.bitwise_and(img, img, mask=mask)

    # Show results
    cv2.imshow('Original', img)
    cv2.imshow('Mask', mask)
    cv2.imshow('Filtered', res)

    # Exit on 'q' press
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

Option 1: Remove a Single Color

To remove a specific color (e.g., green), create a mask for that color, invert it, then apply to the image:

# Example: Remove green (adjust ranges based on your tuner results)
lower_green = np.array([40, 40, 40])
upper_green = np.array([70, 255, 255])
green_mask = cv2.inRange(hsv, lower_green, upper_green)
inverted_mask = cv2.bitwise_not(green_mask)
# Keep everything except green
no_green_img = cv2.bitwise_and(img, img, mask=inverted_mask)

Option 2: Keep Only a Single Color

To retain only one color (e.g., your target object color), use the mask directly. Note: For colors like red that wrap around the Hue scale, you'll need two ranges:

# Example: Keep only red
lower_red1 = np.array([0, 100, 100])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([160, 100, 100])
upper_red2 = np.array([179, 255, 255])
red_mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
red_mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
red_mask = cv2.bitwise_or(red_mask1, red_mask2)
only_red_img = cv2.bitwise_and(img, img, mask=red_mask)

For Your Field Project (Filter Green/Brown/Gray Background)

Combine masks for all three background colors, invert the combined mask, and apply to your image:

# Adjust these ranges using the HSV tuner tool!
# Green range
lower_green = np.array([40, 40, 40])
upper_green = np.array([70, 255, 255])
green_mask = cv2.inRange(hsv, lower_green, upper_green)

# Brown range
lower_brown = np.array([10, 100, 20])
upper_brown = np.array([30, 255, 200])
brown_mask = cv2.inRange(hsv, lower_brown, upper_brown)

# Gray range (low saturation)
lower_gray = np.array([0, 0, 50])
upper_gray = np.array([179, 30, 200])
gray_mask = cv2.inRange(hsv, lower_gray, upper_gray)

# Combine all background masks
background_mask = cv2.bitwise_or(green_mask, brown_mask)
background_mask = cv2.bitwise_or(background_mask, gray_mask)

# Invert to keep only non-background objects
object_mask = cv2.bitwise_not(background_mask)
final_img = cv2.bitwise_and(img, img, mask=object_mask)

cv2.imshow('Field Objects', final_img)
cv2.waitKey(0)

内容的提问来源于stack exchange,提问作者Danny Banany

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:44:53