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


77

我有一个想要找到橙色盖子位置的咖啡罐图像。就是这里图片

gcolor2实用程序显示盖中央的HSV为(22,59,100)。问题是如何选择颜色的界限呢?我尝试了min =(18,40,90)和max =(27,255,255),但是出乎意料结果

这是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()

我将值(22、59、100)检查为HSV,它们似乎与盖子上的任何颜色都不匹配。但是作为BGR,它们是有道理的。您如何检索这些值?
karlphillip 2012年

这是gcolor2 imageshack.us/photo/my-images/23/rgb2hsv.png的屏幕截图。然后,我在yafla.com/yaflaColor/ColorRGBHSL.aspx?RGB=&Colors = 、、、、、、、和上检查了颜色编号#FFA069,并且转换是相同的。
学生FourK 2012年

4
这可能是由于在OpenCV中,即H的HSV范围:0 - 180,S:0 - 255,V:0 - 255
学生FourK

Answers:


145

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

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

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

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

在此处输入图片说明

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

编辑:

正如卡尔·菲利普Karl Philip)在评论中所说,添加新代码会很好。但是只有一行是变化的。因此,我想添加在新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)

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


+1优秀,再一次。如果您可以添加完整的源代码并进行修改,那就太好了。
karlphillip 2012年

谢谢。但我不认为有很多大人在这里:)(好吧,我会做到这一点)。
阿比德·拉赫曼ķ

1
大!尽管我相信您的S和V最小-最大范围过于宽松,但它现在也对我有用。我也有很好的盖子覆盖范围,最小(5、100、255)和最大(15、200、255)。
学生FourK 2012年

很高兴知道。我采用S,V值只是为了显示结果,以证明该解决方案有效。好,你找到了更好的。同时尝试移至cv2界面。它更简单,更快。您可以在此处找到一些不错的教程:opencvpython.blogspot.com。如果它可以解决您的问题,请接受答案并结束本次会议。
阿比德·拉赫曼K

在这里,每个人都是OpenCv的新手时都会犯错。
13年

54

好的,在HSV太空中寻找颜色是一个古老而又普遍的问题。我做了一个hsv-colormap快速查找特殊颜色。这里是:

在此处输入图片说明

x轴代表Hue[0,180),y轴1代表Saturation[0,255],y轴2代表S = 255,而keep V = 255

为了找到一个颜色,通常只是查找的范围H,并S在范围内(20,255),并集V。

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

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

在此处输入图片说明


该方法很简单,但是很常用:

#!/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. 如何定义阈值以仅检测图像中的绿色对象:Opencv

  2. 使用InRangeS为OpenCV阈值选择正确的HSV值


第二个链接表现奇怪?
jtlz2

1
@ jtlz2:他们只是链接回此答案。也许是错误的。
马丁·彼得斯

28

我创建了这个简单的程序来实时获取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()

9
LOL,我写了相同的代码与印刷中使用的最终HSV值github.com/saurabheights/ImageProcessingExperimentScripts/blob/...
saurabheights

14

这是一个简单的HSV颜色阈值脚本,用于使用跟踪栏确定磁盘上任何图像的较低/较高颜色范围。只需更改图像路径cv2.imread()

在此处输入图片说明

import cv2
import numpy as np

def nothing(x):
    pass

# Load image
image = cv2.imread('1.jpg')

# Create a window
cv2.namedWindow('image')

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

while(1):
    # Get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin', 'image')
    sMin = cv2.getTrackbarPos('SMin', 'image')
    vMin = cv2.getTrackbarPos('VMin', 'image')
    hMax = cv2.getTrackbarPos('HMax', 'image')
    sMax = cv2.getTrackbarPos('SMax', 'image')
    vMax = cv2.getTrackbarPos('VMax', 'image')

    # Set minimum and maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(image, image, mask=mask)

    # Print if there is a change in HSV value
    if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

这非常有帮助。使确定合适的HSV范围的速度提高了20倍。许多玛哈洛!
DChaps

哇!正如已经评论过的,非常有帮助。感谢分享!
保罗

太棒了!非常感谢
Seminko

4

OpenCV HSV范围是:H:0至179 S:0至255 V:0至255

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

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

HSV色with具有HSV空间中的颜色检测


3

要查找Green的HSV值,请尝试在Python终端中执行以下命令

green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.