如何使用opencv识别特定区域中的颜色并使用它控制乌藨子的输出?

rxztt3cl  于 2023-11-22  发布在  其他
关注(0)|答案(1)|浏览(144)

对于学校我们有一个项目与视觉,只有我会做一点编程,但我不是很熟悉opencv还.我的问题是,简而言之,是否有可能,如果一个颜色黑色来在一个特定区域的相机,我可以,例如,点亮LED或发送输出高与树莓派。其优点是,现场图像的白色纸张与黑色圆圈。当纸张移位黑圈出现在图像的特定区域,乌藨子的输出必须发送高。我知道如何识别一个圆形或正方形在opencv只识别一个颜色在一个特定的区域,然后发送一个led高我找不到太多关于它的信息在互联网上。希望你能帮助我一个例子代码或帮助我得到的信息。如果你只知道如何识别颜色黑色来在相机的特定区域,并使用if语句,我可以把代码,这将帮助很多也.提前谢谢你.
我使用Raspberry Pi 4与opencv 4.5.1和Python 3.7.3
我已经做了一个图像的videocapture visualization of the videocapture我还采取了截图的代码应该如何工作.不幸的是,代码是不是真的工作,因为我自己添加的文本. color detectedcolor not detected

import cv2
#from gpiozero import LED
print("packege Imported")

cap = cv2.VideoCapture(0)
cap.set(3, 640)
cap.set(4, 480)

font = cv2.FONT_HERSHEY_SIMPLEX

IM_WIDTH = 640
IM_HEIGHT = 480

TL_Zone1 = (int(IM_WIDTH*0.2),int(IM_HEIGHT*0.4))
BR_Zone1 = (int(IM_WIDTH*0.3),int(IM_HEIGHT*0.6))

xmin, ymin = TL_Zone1
xmax, ymax = BR_Zone1

#led1 = LED(2)

def colorDetection(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 15, 255, cv2.THRESH_BINARY_INV)
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    img = cv2.drawContours(img, contours, -1, (0, 0, 255), 3)

    if #there is a few black pixels in the area then
        cv2.putText(img, "color detected",(TL_Zone1[0] + 10, TL_Zone1[1] - 10), font, 1, (0, 0, 255), 3, cv2.LINE_AA)
        #led1.on()
    else:
        cv2.putText(img, "color not detected",(TL_Zone1[0] + 10, TL_Zone1[1] - 10), font, 1, (0, 0, 255), 3, cv2.LINE_AA)
        #led1.off()

while True:
    success, img = cap.read()
    imgDetection = img.copy()

    colorDetection(imgDetection)

    cv2.rectangle(imgDetection, TL_Zone1, BR_Zone1, (0, 0, 255), 8)

    cv2.imshow("Video", img)
    cv2.imshow("Detection", imgDetection)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

字符串

6tqwzwtp

6tqwzwtp1#

假设你的图像是im,你感兴趣的区域是一个由[row_min, row_max, col_min, col_max]定义的矩形。一个图像被存储为一个维度数组:[rows, cols, channels]其中channels == 3,因为它们是RGB通道。
黑色通常由所有3个通道中的低值定义,因此例如,表达式:

im[row_min:row_max, col_min:col_max, :].reshape(-1).sum()

字符串
表示aoi中的总强度。reshape(-1)将阵列的选定部分转换为1D阵列,然后您可以使用.sum()对所有值求和以获得所有通道中的总强度。
如果这给你一个接近零的值,那么这意味着你在图像中的矩形是黑色的。
通常它不会正好为0,因为会有一些信号,所以你可能想找到一个好的阈值,适合你的设置,基于照明,所以你的条件可以是:

if im[row_min:row_max, col_min:col_max, :].reshape(-1).sum() <= threshold
    # do something here, the rectangle area is black


使用您的代码:

import cv2
#from gpiozero import LED

print("packege Imported")

cap = cv2.VideoCapture(1)
cap.set(3, 640)
cap.set(4, 480)

font = cv2.FONT_HERSHEY_SIMPLEX

IM_WIDTH = 640
IM_HEIGHT = 480

TL_Zone1 = (int(IM_WIDTH*0.2),int(IM_HEIGHT*0.4))
BR_Zone1 = (int(IM_WIDTH*0.3),int(IM_HEIGHT*0.6))

xmin, ymin = TL_Zone1
xmax, ymax = BR_Zone1

#led1 = LED(2)

def colorDetection(img, max_black_value=0.1, max_black_cover=0.2):
    
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)[ymin:ymax, xmin:xmax]
    
    # relative amount of pixels with value less than max_black_value in rectangle
    black_cover = gray[gray <= max_black_value].size / gray.size
    
    if black_cover >= max_black_cover:
        cv2.putText(img, "color detected",(TL_Zone1[0] + 10, TL_Zone1[1] - 10), font, 1, (0, 0, 255), 3, cv2.LINE_AA)
        #led1.on()
    else:
        cv2.putText(img, "color not detected",(TL_Zone1[0] + 10, TL_Zone1[1] - 10), font, 1, (0, 0, 255), 3, cv2.LINE_AA)
        #led1.off()

while True:
    success, img = cap.read()
    imgDetection = img.copy()
    
    # pixels with gray value less than 0.1 will be considered black
    max_black_value = 0.1 
    
    # if the rectangle has more than 20% of pixels detected as black
    # then the if statement will be true
    max_black_cover = 0.2 
    
    colorDetection(imgDetection, max_black_value, max_black_cover)

    cv2.rectangle(imgDetection, TL_Zone1, BR_Zone1, (0, 0, 255), 8)

    cv2.imshow("Video", img)
    cv2.imshow("Detection", imgDetection)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

相关问题