如何使用opencv识别特定区域中的颜色,并使用它控制raspberry上的输出?

2024-03-29 11:07:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我是新来的,因为我是荷兰人,我的英语不是很好,所以我希望你不要责怪我。对于学校,我们有一个有远见的项目,只有我能做一点编程,但我还不太熟悉opencv。简言之,我的问题是,如果一种颜色的黑色出现在一个特定的区域,是否有可能​​例如,我可以用树莓pi点亮LED或发送高输出的相机。其优点是,实时图像是一张带有黑色圆圈的白纸。当纸张移动且黑圈出现在图像的特定区域时,树莓的输出必须发送到较高的位置。我知道如何在opencv中识别圆形或方形,只识别特定区域中的颜色,然后发送led high。我在互联网上找不到关于它的很多信息。希望你能帮我一个示例代码或帮助我获得信息。如果你只知道如何识别颜色,黑色会出现在你的特定区域​​相机和使用if-stament,我可以把代码放在那里,这也会有很大帮助。先谢谢你

我在opencv 4.5.1和python 3.7.3中使用raspberrypi 4

我拍了一张录像带的照片 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

Tags: 代码区域img颜色cv2opencvcolorint
1条回答
网友
1楼 · 发布于 2024-03-29 11:07:33

如果您提供迄今为止所编写的代码,以便更容易地回答问题,这将非常有用。请退房https://stackoverflow.com/help/how-to-ask

这就是说,让我们假设您的图像是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数组中数组的选定部分,然后可以使用{}对所有值求和以获得所有通道中的总强度

如果该值接近于零,则表示图像中的矩形为黑色

通常情况下,它不会精确为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

相关问题 更多 >