![](/img/trans.png)
[英]What color space are the lower/upper arguments for cv2.inRange?
[英]Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)
我有一张带有橙色盖子的咖啡罐 position 的图像,我想找到它。 就这个 .
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()
问题 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)
它给出了与上面相同的结果。 但是代码要简单得多。
好的,在HSV
空间中查找颜色是一个古老但常见的问题。 我制作了一个hsv-colormap
来快速查找特殊颜色。 这里是:
x 轴表示 [0,180) 中的Hue
,y 轴 1 表示 [0,255] 中的Saturation
,y 轴 2 表示S = 255
,同时保持V = 255
。
要查找颜色,通常只需查找H
和S
的范围,并将 v 设置在 range(20, 255) 中。
为了找到橙色,我们查找地图,并找到最佳范围: 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()
类似的答案:
这是一个简单的 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 下限/上限颜色阈值范围
(hMin = 0 , sMin = 164, vMin = 0), (hMax = 179 , sMax = 255, vMax = 255)
一旦确定了 HSV lower
和upper
颜色范围,您可以像这样分割所需的颜色:
import numpy as np
import cv2
image = cv2.imread('1.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 164, 0])
upper = np.array([179, 255, 255])
mask = cv2.inRange(hsv, lower, upper)
result = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow('result', result)
cv2.waitKey()
我创建了这个简单的程序来实时获取 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()
为此,我使用 opencv-python 创建了一个简单(更合适)的工具。 认为这对像我今年早些时候一样在这里偶然发现的人很有用
由于该工具本身是使用 python cv2 编写的,因此可以保证使用相同的范围。 还有一个用于erode
和dilate
的滑块,因为通常计算机视觉项目需要这两个功能
您可以从这里克隆工具https://github.com/hariangr/HsvRangeTool
要查找 Green 的 HSV 值,请尝试在 Python 终端中执行以下命令
green = np.uint8([[[0,255,0 ]]])
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
print hsv_green
[[[ 60 255 255]]]
您可以使用 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)
例如,您可以像这样使用它:
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)
上面提到的大多数方法通常需要对特定颜色的颜色范围有一些了解,然后通过反复试验来获得正确的范围。 但是 OpenCV 的官方文档提出了一种更好的方法来找到 HSV 下限和上限,即使对于不常见的颜色也是如此。
如何找到要跟踪的 HSV 值?
这是在 stackoverflow.com 中发现的一个常见问题。 它非常简单,您可以使用相同的函数 cv.cvtColor()。 您只需传递所需的 BGR 值,而不是传递图像。 例如,要查找 Green 的 HSV 值,请在 Python 终端中尝试以下命令:
您可以找到所需对象的确切像素值 (BGR) 并使用它们,例如绿色 (0, 255, 0)
green = np.uint8([[[0,255,0 ]]])
hsv_green = cv.cvtColor(green,cv.COLOR_BGR2HSV)
print(hsv_green)
[[[60 255 255]]]
现在您将[H-10, 100,100]和[H+10, 255, 255]分别作为下限和上限。 除了这种方法,您可以使用任何图像编辑工具,如 GIMP 或任何在线转换器来查找这些值,但不要忘记调整 HSV 范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.