Python OpenCV 颜色跟踪
Python OpenCV Color Tracking
下面是我的 python 跟踪白色物体的代码。它有效 - 但仅持续几秒钟,然后整个屏幕变黑,有时它不起作用。我尝试了蓝色并且它有效 - 但白色和绿色给我带来了问题:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
_, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of white color in HSV
# change it according to your need !
sensitivity = 15
lower_white = np.array([0,0,255-sensitivity])
upper_white = np.array([255,sensitivity,255])
# Threshold the HSV image to get only white colors
mask = cv2.inRange(hsv, lower_white, upper_white)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
嗯,首先你应该知道你使用的是什么颜色 space。
OpenCV 中 Mat
类型 CV_8UC3
的颜色 spaces 的小教程。 (图片来自维基百科)
单纯疱疹病毒
在HSV(色相、饱和度、明度)颜色space中,H给出颜色主色,S给出颜色的饱和度,V给出亮度。在 OpenCV 中,范围不同。 S,V 在 [0,255] 中,而 H 在 [0, 180] 中。通常 H 在 [0,360](整圈)范围内,但为了适应一个字节(256 个不同的值),它的值减半。
在HSV中space更容易分离单一颜色,因为你可以简单地为H设置合适的范围,并注意S不要太小(它会接近白色),并且V不算小(会黑)
因此,例如,如果您需要几乎 blue 颜色,则需要 H 值在 120 左右(比如 [110,130]),并且 S、V 不能太小(比如 [100,255])。
白色不是一种色调(彩虹中没有白色),而是一种颜色的组合。
在 HSV 中,您需要获取所有范围的 H(H 在 [0, 180] 中)、非常小的 S 值(例如 [0, 25] 中的 S)和非常高的 V 值(例如 V 在[230、255])。这个基本对应圆锥体中轴的上部
因此,要使其跟踪 HSV space 中的白色对象,您需要:
lower_white = np.array([0, 0, 230])
upper_white = np.array([180, 25, 255])
或者,由于您定义了敏感度值,例如:
sensitivity = 15
lower_white = np.array([0, 0, 255-sensitivity])
upper_white = np.array([180, sensitivity, 255])
其他颜色:
green = 60;
blue = 120;
yellow = 30;
...
sensitivity = 15
// Change color with your actual color
lower_color = np.array([color - sensitivity, 100, 100])
upper_color = np.array([color + sensitivity, 255, 255])
红色H值为0,所以需要取两个范围"OR"一起:
sensitivity = 15
lower_red_0 = np.array([0, 100, 100])
upper_red_0 = np.array([sensitivity, 255, 255])
lower_red_1 = np.array([180 - sensitivity, 100, 100])
upper_red_1 = np.array([180, 255, 255])
mask_0 = cv2.inRange(hsv, lower_red_0 , upper_red_0);
mask_1 = cv2.inRange(hsv, lower_red_1 , upper_red_1 );
mask = cv2.bitwise_or(mask1, mask2)
现在您应该可以追踪任何颜色了!
不必猜测和检查 HSV lower/upper 颜色范围,您可以使用 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(True):
# 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()
下面是我的 python 跟踪白色物体的代码。它有效 - 但仅持续几秒钟,然后整个屏幕变黑,有时它不起作用。我尝试了蓝色并且它有效 - 但白色和绿色给我带来了问题:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
_, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of white color in HSV
# change it according to your need !
sensitivity = 15
lower_white = np.array([0,0,255-sensitivity])
upper_white = np.array([255,sensitivity,255])
# Threshold the HSV image to get only white colors
mask = cv2.inRange(hsv, lower_white, upper_white)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
嗯,首先你应该知道你使用的是什么颜色 space。
OpenCV 中 Mat
类型 CV_8UC3
的颜色 spaces 的小教程。 (图片来自维基百科)
单纯疱疹病毒
在HSV(色相、饱和度、明度)颜色space中,H给出颜色主色,S给出颜色的饱和度,V给出亮度。在 OpenCV 中,范围不同。 S,V 在 [0,255] 中,而 H 在 [0, 180] 中。通常 H 在 [0,360](整圈)范围内,但为了适应一个字节(256 个不同的值),它的值减半。
在HSV中space更容易分离单一颜色,因为你可以简单地为H设置合适的范围,并注意S不要太小(它会接近白色),并且V不算小(会黑)
因此,例如,如果您需要几乎 blue 颜色,则需要 H 值在 120 左右(比如 [110,130]),并且 S、V 不能太小(比如 [100,255])。
白色不是一种色调(彩虹中没有白色),而是一种颜色的组合。
在 HSV 中,您需要获取所有范围的 H(H 在 [0, 180] 中)、非常小的 S 值(例如 [0, 25] 中的 S)和非常高的 V 值(例如 V 在[230、255])。这个基本对应圆锥体中轴的上部
因此,要使其跟踪 HSV space 中的白色对象,您需要:
lower_white = np.array([0, 0, 230])
upper_white = np.array([180, 25, 255])
或者,由于您定义了敏感度值,例如:
sensitivity = 15
lower_white = np.array([0, 0, 255-sensitivity])
upper_white = np.array([180, sensitivity, 255])
其他颜色:
green = 60;
blue = 120;
yellow = 30;
...
sensitivity = 15
// Change color with your actual color
lower_color = np.array([color - sensitivity, 100, 100])
upper_color = np.array([color + sensitivity, 255, 255])
红色H值为0,所以需要取两个范围"OR"一起:
sensitivity = 15
lower_red_0 = np.array([0, 100, 100])
upper_red_0 = np.array([sensitivity, 255, 255])
lower_red_1 = np.array([180 - sensitivity, 100, 100])
upper_red_1 = np.array([180, 255, 255])
mask_0 = cv2.inRange(hsv, lower_red_0 , upper_red_0);
mask_1 = cv2.inRange(hsv, lower_red_1 , upper_red_1 );
mask = cv2.bitwise_or(mask1, mask2)
现在您应该可以追踪任何颜色了!
不必猜测和检查 HSV lower/upper 颜色范围,您可以使用 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(True):
# 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()