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

时间:2012-06-08 12:09:30

标签: opencv hsv color-detection

我有一个咖啡罐的图像,橙色的盖子位置,我想找到。 这是image

gcolor2实用程序显示盖子中心的HSV为(22,59,100)。 问题是如何选择颜色的限制呢?我尝试了min =(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()

7 个答案:

答案 0 :(得分:124)

问题1:不同的应用程序对HSV使用不同的比例。例如,gimp使用H = 0-360, S = 0-100 and V = 0-100。但OpenCV使用H: 0 - 180, 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)

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

enter image description here

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

修改

正如 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 :(得分:23)

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

答案 2 :(得分:20)

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

enter image description here

x轴代表[0,180]中的Hue,y轴1代表[0,255]中的Saturation,y轴2代表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.   
  3. Choosing correct HSV values for OpenCV thresholding with InRangeS

  4.   

答案 3 :(得分:16)

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

中的图像路径

enter image description here

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

答案 4 :(得分:3)

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

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

我发现在尝试基于HSV色彩空间进行物体检测时,范围为5(opencv范围)足以滤除特定颜色。我建议你使用HSV颜色来确定最适合你应用的范围。

HSV color palate with color detection in HSV space

答案 5 :(得分:1)

您可以使用 GIMP 或 PaintDotNet 来获取 HSV 的确切范围。但问题是图形软件中的HSV范围与OpenCV中的相同范围不同,因此您需要一个函数来为您纠正此问题。为此,您可以使用以下功能。

def fixHSVRange(h, s, v):
    # Normal H,S,V: (0-360,0-100%,0-100%)
    # OpenCV H,S,V: (0-180,0-255 ,0-255)
    return (180 * h / 360, 255 * s / 100, 255 * v / 100)

enter image description here

例如,您可以像这样使用它:

im=cv2.imread("image.jpg",1)
im_hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
color1 = fixHSVRange(h=10, s=20, v=0)
color2 = fixHSVRange(h=30, s=70, v=100)
mask = cv2.inRange(im_hsv, color1, color2)
cv2.imwrite("mask.jpg",mask)

enter image description here

答案 6 :(得分:0)

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

green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]