使用 cv::inRange (OpenCV) 为颜色检测选择正确的 HSV 上下边界

问题描述

我有一张带有橙色盖子位置的咖啡罐的图像,我想找到它.这是 .

I have an image of a coffee can with an orange lid position of which I want to find. Here is it .

gcolor2 实用程序显示盖子中心的 HSV 为 (22, 59, 100).问题是如何选择颜色的界限呢?我尝试了 min = (18, 40, 90) 和 max = (27, 255, 255),但得到了意外

gcolor2 utility shows HSV at the center of the lid to be (22, 59, 100). The question is how to choose the limits of the color then? I tried min = (18, 40, 90) and max = (27, 255, 255), but have got unexpected

这是 Python 代码:

Here is the Python code:

import cv

in_image = 'kaffee.png'
out_image = 'kaffee_out.png'
out_image_thr = 'kaffee_thr.png'

ORANGE_MIN = cv.Scalar(18, 40, 90)
ORANGE_MAX = cv.Scalar(27, 255, 255)
COLOR_MIN = ORANGE_MIN
COLOR_MAX = ORANGE_MAX

def test1():
    frame = cv.LoadImage(in_image)
    frameHSV = cv.CreateImage(cv.GetSize(frame), 8, 3)
    cv.CvtColor(frame, frameHSV, cv.CV_RGB2HSV)
    frame_threshed = cv.CreateImage(cv.GetSize(frameHSV), 8, 1)
    cv.InRangeS(frameHSV, COLOR_MIN, COLOR_MAX, frame_threshed)
    cv.SaveImage(out_image_thr, frame_threshed)

if __name__ == '__main__':
    test1()


解决方案

问题一: 不同的应用程序对 HSV 使用不同的尺度.例如 gimp 使用 H = 0-360, S = 0-100 和 V = 0-100.但是 OpenCV 使用 H: 0-179, S: 0-255, V: 0-255.在这里,我在 gimp 中得到了 22 的色调值.所以我拿了一半,11,并为此定义了范围.即(5,50,50) - (15,255,255).

Problem 1 : Different applications use different scales for HSV. For example gimp uses H = 0-360, S = 0-100 and V = 0-100. But OpenCV uses H: 0-179, S: 0-255, V: 0-255. Here i got a hue value of 22 in gimp. So I took half of it, 11, and defined range for that. ie (5,50,50) - (15,255,255).

问题 2: 而且,OpenCV 使用 BGR 格式,而不是 RGB.因此,如下更改将 RGB 转换为 HSV 的代码:

Problem 2: And also, OpenCV uses BGR format, not RGB. So change your code which converts RGB to HSV as follows:

cv.CvtColor(frame, frameHSV, cv.CV_BGR2HSV)

现在运行它.我得到如下输出:

Now run it. I got an output as follows:

希望这是您想要的.有一些错误检测,但它们很小,因此您可以选择最大的轮廓即您的盖子.

Hope that is what you wanted. There are some false detections, but they are small, so you can choose biggest contour which is your lid.

正如 Karl Philip 在他的评论中所说,添加新代码会很好.但是只有一行的变化.因此,我想在新的 cv2 模块中添加相同的代码,以便用户可以比较新的 cv2 模块的易用性和灵活性.

As Karl Philip told in his comment, it would be good to add new code. But there is change of only a single line. So, I would like to add the same code implemented in new cv2 module, so users can compare the easiness and flexibility of new cv2 module.

import cv2
import numpy as np

img = cv2.imread('sof.jpg')

ORANGE_MIN = np.array([5, 50, 50],np.uint8)
ORANGE_MAX = np.array([15, 255, 255],np.uint8)

hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

frame_threshed = cv2.inRange(hsv_img, ORANGE_MIN, ORANGE_MAX)
cv2.imwrite('output2.jpg', frame_threshed)

它给出与上面相同的结果.但是代码要简单得多.

It gives the same result as above. But code is much more simpler.

相关文章