opencv cap.read 有一个属性错误。如何排除故障?

opencv cap.read has an Attribute error. How to troubleshoot?

我们目前正在整合两个代码: 1. mss抓屏录屏 2. opencv 颜色跟踪器

我们遇到了这个错误:

File "C:/Users/John Wong/Desktop/Test2.py", line 28, in <module>
_, img = cap.read()

AttributeError: 'NoneType' object has no attribute 'read'

我们想使用屏幕抓取作为颜色跟踪代码的输入。将会发生的情况是,在屏幕捕获代码发生的同时,颜色跟踪代码将在捕获的屏幕上同时生效。

我们不知道我们的代码有什么问题,下面是脚本:

import cv2
import numpy as np
import time
import mss
import numpy


with mss.mss() as sct:
    # Part of the screen to capture
    monitor = {'top': 80, 'left': 20, 'width': 800, 'height': 770}
    while 'Screen capturing':
        last_time = time.time()

        # Get raw pixels from the screen, save it to a Numpy array
        img = numpy.array(sct.grab(monitor))


        cap = cv2.imshow('OpenCV/Numpy normal', img)

        while(True):
            _, img = cap.read()
            hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

            red_lower = np.array([170,87,97],np.uint8)
            red_upper = np.array([180,255,255],np.uint8)

            blue_lower = np.array([23,59,119],np.uint8)
            blue_upper = np.array([54,255,255],np.uint8)

            yellow_lower = np.array([0,50,80],np.uint8)
            yellow_upper = np.array([20,255,255],np.uint8)

            red = cv2.inRange(hsv, red_lower, red_upper)
            blue = cv2.inRange(hsv, blue_lower, blue_upper)
            yellow = cv2.inRange(hsv, yellow_lower, yellow_upper)

            kernal = np.ones((5,5), "uint8")

            red = cv2.dilate(red,kernal)
            res = cv2.bitwise_and(img, img, mask = red)

            blue = cv2.dilate(blue, kernal)
            res1 = cv2.bitwise_and(img, img, mask = blue)

            yellow = cv2.dilate(yellow, kernal)
            res2 = cv2.bitwise_and(img, img, mask = yellow)

            (_,contours, heirarchy) = cv2.findContours(red,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

            for pic, contour in enumerate(contours):
                area = cv2.contourArea(contour)
                if(area>300):
                    x,y,w,h = cv2.boundingRect(contour)
                    img = cv2.rectangle(img,(x,y),(x+w,y+h),(61,26,76),2)
                    cv2.putText(img,"PRIORITY",(x,y),cv2.FONT_HERSHEY_SIMPLEX,0.7,(61,26,76))

            (_,contours, heirarchy) = cv2.findContours(blue,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
            for pic, contour in enumerate(contours):
                area = cv2.contourArea(contour)
                if(area>300):
                    x,y,w,h = cv2.boundingRect(contour)
                    img = cv2.rectangle(img,(x,y),(x+w,y+h), (255,0,0),2)
                    cv2.putText(img,"SECOND",(x,y),cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,0,0))

            (_,contours,heirarchy) = cv2.findContours(yellow,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
            for pic, contour in enumerate(contours):
                area = cv2.contourArea(contour)
                if(area>300):
                    x,y,w,h = cv2.boundingRect(contour)
                    img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,217),2)
                    cv2.putText(img,"ALERT",(x,y),cv2.FONT_HERSHEY_SIMPLEX,1.0, (0,255,217))

            cv2.imshow("Color Tracking", img)

            if cv2.waitKey(10) & 0xFF == ord('q'):
                cap.release()
                cv2.destroyAllWindows()
                break

提前致谢! :)

我不太明白这段代码中发生了什么,以及您期望 cap 是什么,但是:

此处的这一行将图像读入img

        img = numpy.array(sct.grab(monitor))

然后您使用此行在 window 中显示该图像:

        cap = cv2.imshow('OpenCV/Numpy normal', img)

cap 现在是 NoneType,如您的错误消息所示(感谢@DanMašek),因此在其余代码中不要使用 Cap 作为图像,而是使用 img。

while(True):
        # Remove this line: _, img = cap.read()
        # Get raw pixels from the screen, save it to a Numpy array
        img = numpy.array(sct.grab(monitor)) #Update the new image
        hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

        red_lower = np.array([170,87,97],np.uint8)
        red_upper = np.array([180,255,255],np.uint8)

        blue_lower = np.array([23,59,119],np.uint8)
        blue_upper = np.array([54,255,255],np.uint8)

        yellow_lower = np.array([0,50,80],np.uint8)
        yellow_upper = np.array([20,255,255],np.uint8)

        red = cv2.inRange(hsv, red_lower, red_upper)
        blue = cv2.inRange(hsv, blue_lower, blue_upper)
        yellow = cv2.inRange(hsv, yellow_lower, yellow_upper)

        cv2.imshow('Processed', img)
        cv2.waitKey(1)