【问题标题】:opencv - python - confused when using HSV color in cv2.inRangeopencv - python - 在 cv2.inRange 中使用 HSV 颜色时感到困惑
【发布时间】:2017-04-09 09:39:30
【问题描述】:

我正在尝试使用 cv2.inRange (python 2.7) 基于颜色执行对象检测。使用 BGR 颜色时,一切似乎都正常。但是,当我将 BGR 颜色映射到 HSV 时,我无法获得正确的蒙版。请看下面的例子:

1) bgr 中的阈值

img_test = cv2.imread("test_img/mario.jpeg")
#define color range for object detection
step = 10
r,g,b = 203, 31, 25 #red
lower_bgr = np.uint8([b-step, g-step, r-step])
upper_bgr = np.uint8([b + step, g + step, r + step])

# plot mario in BGR and corresponding mask
plt.figure(figsize=(20,10))
plt.subplot(1,2,1)
plt.imshow(cv2.cvtColor(img_test, cv2.COLOR_BGR2RGB))


mask = cv2.inRange(img_test, lower_bgr, upper_bgr)
plt.subplot(1,2,2)
plt.imshow(mask, cmap='gray')

mario_bgr

2) hsv 中的阈值(无法正常工作)

# first convert the img, and the associated lower and upper bound to HSV
hsv_img_test = cv2.cvtColor(img_test, cv2.COLOR_BGR2HSV)
lower_hsv = cv2.cvtColor(np.uint8([[[b-step,g-step,r-step]]]), cv2.COLOR_BGR2HSV)
upper_hsv = cv2.cvtColor(np.uint8([[[b+step,g+step,r+step]]]), cv2.COLOR_BGR2HSV)


plt.figure(figsize=(20,10))
plt.subplot(1,2,1)
plt.imshow(cv2.cvtColor(hsv_img_test, cv2.COLOR_BGR2RGB))

# apply threshold on hsv image
mask = cv2.inRange(hsv_img_test, lower_hsv, upper_hsv)
plt.subplot(1,2,2)
plt.imshow(mask, cmap='gray')

mario_hsv

...这显然是不正确的。我无法弄清楚代码中有什么问题,任何帮助将不胜感激!

【问题讨论】:

    标签: python opencv hsv bgr


    【解决方案1】:

    似乎意外行为来自 uint8 数组格式。我没有弄清楚确切的原因,但您应该谨慎使用无符号整数的运算(例如:0 - 1 = 255)。

    我想我终于得到了你可能想要的结果:

    # first convert the img to HSV
    img_test_hsv = cv2.cvtColor(img_test, cv2.COLOR_BGR2HSV)
    
    # convert the target color to HSV
    target_color = np.uint8([[[b, g, r]]])
    target_color_hsv = cv2.cvtColor(target_color, cv2.COLOR_BGR2HSV)
    
    # boundaries for Hue define the proper color boundaries, saturation and values can vary a lot
    target_color_h = target_color_hsv[0,0,0]
    tolerance = 2
    lower_hsv = np.array([max(0, target_color_h - tolerance), 10, 10])
    upper_hsv = np.array([min(179, target_color_h + tolerance), 250, 250])
    
    plt.figure(figsize=(20,10))
    plt.subplot(1,2,1)
    plt.imshow(cv2.cvtColor(img_test_hsv, cv2.COLOR_HSV2RGB));
    
    # apply threshold on hsv image
    mask = cv2.inRange(img_test_hsv, lower_hsv, upper_hsv)
    plt.subplot(1,2,2)
    plt.imshow(mask, cmap='gray');
    

    另一点要考虑的是不同颜色空间RGB和HSV的拓扑差异。 RGB 空间中的框不会转换为 HSV 坐标中的框。请参阅以下维基百科文章: HSL ans HSV Color Spaces

    【讨论】:

    • 如果target_color_h 是签名类型,则此方法有效。为了节省开支,也许可以使用max(tolerance, target_color_h) - tolerance
    猜你喜欢
    • 1970-01-01
    • 2018-06-15
    • 2019-11-19
    • 2012-06-29
    • 2018-10-21
    • 2012-06-12
    • 1970-01-01
    相关资源
    最近更新 更多