2012-06-08 118 views
48

我有一个咖啡罐的图像,我想找到一个橙色的盖子位置。 这是它image使用`cv :: inRange`(OpenCV)为颜色检测选择正确的上下HSV边界

gcolor2实用程序显示盖子中心的HSV为(22,59,100)。 问题是如何选择颜色的限制呢?我试图分钟=(18,40,90)和max =(27,255,255),但是已经得到意想不到result

这里是Python代码:

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() 
+0

我检查的数值(22,59,100)HSV,而且他们似乎并不匹配类似的那些相同的任何颜色盖子。但是作为BGR,它们是有道理的。你是如何检索这些值的? – karlphillip

+0

这是gcolor2的截图http://imageshack.us/photo/my-images/23/rgb2hsv.png/。然后,我检查颜色编号#FFA069的http://www.yafla.com/yaflaColor/ColorRGBHSL.aspx?RGB =&Colors = ,,,,,,,,,并且转换是相同的。 –

+2

这可能是由于OpenCV中的HSV范围不同,即H:0-180,S:0-255,V:0-255。 –

回答

101

问题1:不同应用程序使用不同比例的HSV。例如,gimp使用H = 0-360, S = 0-100 and V = 0-100。但OpenCV使用H: 0 - 180, S: 0 - 255, V: 0 - 255。在这里,我得到了瘸子22的色相值。所以我拿了一半,11,并为此定义了范围。即(5,50,50) - (15,255,255)

问题2:而且,OpenCV使用BGR格式,而不是RGB。所以改变你的代码,将RGB转换为HSV如下:

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

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

enter image description here

希望这是你想要的。有一些错误的检测,但它们很小,所以你可以选择最大的轮廓,这是你的盖子。

编辑:

由于卡尔·菲利普在他的评论中说,这将有利于增加新的代码。但是只有一条线的变化。因此,我想添加新的cv2模块中实现的相同代码,以便用户可以比较新cv2模块的易用性和灵活性。

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) 

它给出了与上述相同的结果。但代码要简单得多。

+0

+1优秀,再一次。如果你可以在你的修改中添加完整的源代码,那就太棒了。 – karlphillip

+0

谢谢。但我认为这里没有太多优点:)(OK,我会做) –

+1

@karlphillip:编辑答案 –

17

我建立这个简单的程序来获得实时HSV代码

import cv2 
import numpy as np 


cap = cv2.VideoCapture(0) 

def nothing(x): 
    pass 
# Creating a window for later use 
cv2.namedWindow('result') 

# Starting with 100's to prevent error while masking 
h,s,v = 100,100,100 

# Creating track bar 
cv2.createTrackbar('h', 'result',0,179,nothing) 
cv2.createTrackbar('s', 'result',0,255,nothing) 
cv2.createTrackbar('v', 'result',0,255,nothing) 

while(1): 

    _, frame = cap.read() 

    #converting to HSV 
    hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) 

    # get info from track bar and appy to result 
    h = cv2.getTrackbarPos('h','result') 
    s = cv2.getTrackbarPos('s','result') 
    v = cv2.getTrackbarPos('v','result') 

    # Normal masking algorithm 
    lower_blue = np.array([h,s,v]) 
    upper_blue = np.array([180,255,255]) 

    mask = cv2.inRange(hsv,lower_blue, upper_blue) 

    result = cv2.bitwise_and(frame,frame,mask = mask) 

    cv2.imshow('result',result) 

    k = cv2.waitKey(5) & 0xFF 
    if k == 27: 
     break 

cap.release() 

cv2.destroyAllWindows() 
+3

大声笑,我写了相同的代码打印最终的HSV值使用https://github.com/saurabheights/ImageProcessingExperimentScripts/blob/master/AnalyzeHSV/hsvThresholder.py – saurabheights

1

OpenCV的HSV范围是: H:0至179 S:0〜255 五:0到255

在Gimp(或其他照片处理sw)色调范围从0到360,因为opencv将颜色信息放在单个字节中,所以单个字节中的最大数值为255,因此openCV色调值等于来自gimp的色相值除以2。

当我尝试基于HSV颜色空间进行对象检测时发现,范围为5(opencv范围)足以过滤出特定颜色。我建议您使用HSV色板来找出最适合您应用的范围。

HSV color palate with color detection in HSV space

2

好了,找颜色HSV空间是一个古老而又常见的问题。我做了一个hsv-colormap来快速查找特殊颜色。在这里它是:

enter image description here

的x轴表示在[0180 Hue)中,y轴1表示[0255] Saturation中,y的axis2表示S = 255,同时保持V = 255

要查找颜色,通常只需查找HS的范围,并将范围设置为v(20,255)。

要查找橙色,我们查找地图,并找到最佳范围:H :[10, 25], S: [100, 255], and V: [20, 255]。所以,掩码为cv2.inRange(hsv,(10, 100, 20), (25, 255, 255))

然后我们用找到的范围来寻找橙色,这是结果:

enter image description here


的方法很简单,但通常使用:

#!/usr/bin/python3 
# 2018.01.21 20:46:41 CST 
import cv2 

img = cv2.imread("test.jpg") 
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 
mask = cv2.inRange(hsv,(10, 100, 20), (25, 255, 255)) 
cv2.imshow("orange", mask);cv2.waitKey();cv2.destroyAllWindows() 

类似的答案:

  1. How to define a threshold value to detect only green colour objects in an image :Opencv

  2. Choosing correct HSV values for OpenCV thresholding with InRangeS