【问题标题】:How to find the RED color regions using OpenCV?如何使用 OpenCV 找到红色区域?
【发布时间】:2018-12-16 04:02:30
【问题描述】:

我正在尝试制作一个检测红色的程序。但是有时它比平时更暗,所以我不能只使用一个值。 检测不同深浅的红色的最佳范围是多少? 我目前使用的范围是 128、0、0 - 255、60、60,但有时它甚至没有检测到我放在它前面的红色物体。

【问题讨论】:

    标签: python opencv colors


    【解决方案1】:

    您可以检查红色分量是最大值,而其他分量都明显较低:

    def red(r, g, b):
        threshold = max(r, g, b)
        return (
            threshold > 8          # stay away from black
            and r == threshold     # red is biggest component
            and g < threshold*0.5  # green is much smaller
            and b < threshold*0.5  # so is b
        )
    

    这可以使用 numpy 非常有效地实现。

    “正确的方法”是完全转换为 HSV 并在那里检查,但它会更慢而且有点棘手(色调是一个角度,所以你不能只取差异的绝对值,而且颜色像 ( 255, 254, 254) 将被认定为“红色”,即使它们被认为是人类的白色)。

    另请注意,人类视觉系统倾向于补偿平均值,因此即使最大的分量确实是红色,也可以将某些东西视为“蓝色”,但图像中的所有内容都是红色的,因此“不算数”我们的大脑。

    在下图中,如果你问一个人,圆圈区域中的部分是什么颜色,大多数人会说“蓝色”,而实际上最大的部分是红色:

    【讨论】:

      【解决方案2】:

      请使用 HSV 或 HSL(色调、饱和度、亮度)而不是 RGB,在 HSV 中,使用 hue 的值在某个阈值内可以轻松检测到红色。

      【讨论】:

      • 只检查 hue 是行不通的,除非您认为 (255, 254, 254) 是完美的“红色”。
      • @6502 它比绿色或其他任何东西更红。此外,OP 存在颜色较深的问题。
      【解决方案3】:

      RGB不是用于特定颜色检测的良好颜色空间。 HSV 会是一个不错的选择。

      对于 RED,您可以使用以下颜色图选择 HSV 范围 (0,50,20) ~ (5,255,255)(175,50,20)~(180,255,255)。当然,RED range 不是那么精确,但还可以。

      代码取自我的另一个答案:Detect whether a pixel is red or not

      #!/usr/bin/python3
      # 2018.07.08 10:39:15 CST
      # 2018.07.08 11:09:44 CST
      import cv2
      import numpy as np
      ## Read and merge
      img = cv2.imread("ColorChecker.png")
      img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
      
      ## Gen lower mask (0-5) and upper mask (175-180) of RED
      mask1 = cv2.inRange(img_hsv, (0,50,20), (5,255,255))
      mask2 = cv2.inRange(img_hsv, (175,50,20), (180,255,255))
      
      ## Merge the mask and crop the red regions
      mask = cv2.bitwise_or(mask1, mask2 )
      croped = cv2.bitwise_and(img, img, mask=mask)
      
      ## Display
      cv2.imshow("mask", mask)
      cv2.imshow("croped", croped)
      cv2.waitKey()
      

      相关答案:

      1. Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)
      2. How to define a threshold value to detect only green colour objects in an image :Opencv
      3. How to detect two different colors using `cv2.inRange` in Python-OpenCV?
      4. Detect whether a pixel is red or not

      当然,对于具体的问题,也许其他色彩空间也可以。

      How to read utility meter needle with opencv?

      【讨论】:

      • 为什么将 BGR 转换为 HSV 似乎会改变颜色?为什么它看起来和基于原始图像的 HSV 值匹配?
      • 这类似于来自 opencv docs.opencv.org/master/df/d9d/tutorial_py_colorspaces.html 的回答他们还建议使用 opencv 从 RGB 转换为 HSV,并使用色调 +/- 10 和 [50, 255] 的范围来表示饱和度和值看来。
      • 为什么所有其他颜色选择器使用 [0, 360] 范围内的度数值作为色调,而您使用 [0, 180] 的标量?对于那些看过答案的人来说,有点细微的差别是所有颜色选择器都使用(百分比)值 [0, 100]% 来表示饱和度和值。
      【解决方案4】:

      红色表示红色值高于蓝色和绿色。

      因此您可以检查红色和蓝色、红色和绿色之间的差异。

      您可以简单地将 RGB 拆分为单独的通道并像这样应用阈值。

      b,g,r = cv2.split(img_rgb)
      rg = r - g
      rb = r - b
      rg = np.clip(rg, 0, 255)
      rb = np.clip(rb, 0, 255)
      
      mask1 = cv2.inRange(rg, 50, 255)
      mask2 = cv2.inRange(rb, 50, 255)
      mask = cv2.bitwise_and(mask1, mask2)
      

      希望它可以解决您的问题。

      谢谢。

      【讨论】:

        猜你喜欢
        • 2012-02-19
        • 2021-10-09
        • 2015-05-30
        • 1970-01-01
        • 2019-12-07
        • 1970-01-01
        • 2015-07-31
        • 1970-01-01
        • 2012-05-03
        相关资源
        最近更新 更多