Python OpenCV颜色跟踪

7hiiyaii  于 2023-10-24  发布在  Python
关注(0)|答案(2)|浏览(187)

下面是我跟踪白色物体的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()
ozxc1zmp

ozxc1zmp1#

好吧,首先你应该知道你使用的是什么颜色空间。只是一个小教程的颜色空间在OpenCV为CV_8UC3类型的Mat。(图片来自维基百科)

HSV

在HSV(Hue,Saturation,Value)颜色空间中,H给出了颜色的主色,S给出了颜色的饱和度,V给出了亮度。在OpenCV中,范围是不同的。S,V在[0,255]中,而H在[0,180]中。通常H在范围[0,360](完整的圆圈)中,但为了适应一个字节(256个不同的值),它的值被减半。
在HSV空间中更容易分离单一颜色,因为您可以简单地为H设置适当的范围,并且只需注意S不要太小(它几乎是白色),V也不要太小(它会很暗)。
例如,如果你需要几乎 * 蓝色 * 的颜色,你需要H值在120左右(比如在[110,130]中),S,V不能太小(比如在[100,255]中)。
白色不是一种色调(彩虹中没有白色),而是多种颜色的组合。
在HSV中,你需要取H的所有范围(H在[0,180]中),非常小的S值(比如S在[0,25]中),以及非常高的V值(比如V在[230,255]中)。这基本上对应于圆锥中心轴的上部。
因此,要使其跟踪HSV空间中的白色对象,您需要:

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(mask_0, mask_1)

现在你应该可以跟踪任何颜色!

z31licg0

z31licg02#

您可以使用HSV颜色阈值脚本来确定带有轨迹条的范围,而不必猜测和检查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()

相关问题