使用带有网络摄像头的 OpenCV 进行 7 段检测

7 Segment Detection using OpenCV with Webcam

我想用相机阅读一些数字显示。我在这里找到了检测和阅读显示的教程:https://www.pyimagesearch.com/2017/02/13/recognizing-digits-with-opencv-and-python/

因为需要实时阅读,所以我设置了摄像头的视频输入。这是我的代码:

from imutils.perspective import four_point_transform
from imutils import contours
import imutils
import cv2

# creating a dictionary for 7-segment detection
DIGITS_LOOKUP = {
    (1, 1, 1, 0, 1, 1, 1): 0,
    (0, 0, 1, 0, 0, 1, 0): 1,
    (1, 0, 1, 1, 1, 1, 0): 2,
    (1, 0, 1, 1, 0, 1, 1): 3,
    (0, 1, 1, 1, 0, 1, 0): 4,
    (1, 1, 0, 1, 0, 1, 1): 5,
    (1, 1, 0, 1, 1, 1, 1): 6,
    (1, 0, 1, 0, 0, 1, 0): 7,
    (1, 1, 1, 1, 1, 1, 1): 8,
    (1, 1, 1, 1, 0, 1, 1): 9
}

# capturing from webcam
cap = cv2.VideoCapture(0)
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))

# define codec and create VideoWriter object
out = cv2.VideoWriter('out_videos/cam_blur.avi', 
                      cv2.VideoWriter_fourcc('M','J','P','G'), 
                      30, 
                      (frame_width,frame_height))

# continuous capture from webcam
while(cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        blurred = cv2.GaussianBlur(gray, (7, 7), 0)
        edged = cv2.Canny(blurred, 50, 200, 200)
        cv2.imshow('Video', edged)
                
        # find contours in the edge map, then sort them by their size in descending order
        cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
            cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours(cnts)
        cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
        displayCnt = None
        
        # loop over the contours
        for c in cnts:
            # approximate the contour
            peri = cv2.arcLength(c, True)
            approx = cv2.approxPolyDP(c, 0.02 * peri, True)
            
        # if the contour has four vertices, then we have found
        # the thermostat display
            if len(approx) == 4:
                 displayCnt = approx
                 break
        
        # extract the thermostat display, apply a perspective transform
        # to it
        warped = four_point_transform(gray, displayCnt.reshape(4, 2))
        output = four_point_transform(frame, displayCnt.reshape(4, 2))
        cv2.imshow('Birdeye', output)
        
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
       
cap.release()
cv2.destroyAllWindows()

第一次尝试时,程序 运行 很好,尽管有时它会检测到 运行dom 矩形对象并在崩溃时发送此错误:

File "7segmentcam.py", line 63, in <module>
    warped = four_point_transform(gray, displayCnt.reshape(4, 2))

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

我在第 37 行和第 38 行调整了一些参数后,程序没有响应并因上述相同错误而崩溃。 运行摄像头没有检测到任何物体时程序不报错有没有更好的选择?

发生这种情况是因为有时,您的代码在 approxPolyDP 之后找不到任何具有 4 个顶点的轮廓,因此,变量 displayCnt 的值保持 None 之前设置的值for 循环,因此 four_point_transform 函数显示错误,因为它没有将 None 作为输入。

为避免此错误,在four_point_transform函数之前,通过if displayCnt is not None:检查displayCnt的值,如果是None,则不要运行函数。

此外,根据我的说法,for 循环中的 if 条件不正确,因为它在极少数情况下会满足,而在图像处理中,当您确定它会满足时,您可以使用这些特定条件至少有 1 个条件为真。所以,在我看来,改变那个 if 条件。