问题描述
我想用相机阅读一些数字显示器。我在这里找到了检测和阅读显示内容的教程: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,(0,0): 1,(1,0): 2,1): 3,0): 4,1): 5,1): 6,0): 7,1): 8,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,2))
cv2.imshow('Birdeye',output)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
尽管在某些情况下它会检测到随机的矩形对象并在崩溃时发送此错误,但该程序还是运行良好的。
File "7segmentcam.py",line 63,in <module>
warped = four_point_transform(gray,2))
AttributeError: 'nonetype' object has no attribute 'reshape'
在第37和38行中调整了一些参数之后,该程序没有响应,并因上述相同错误而崩溃。当相机未检测到任何物体时,有没有更好的选择来运行程序而不会出错?
解决方法
之所以发生这种情况,是因为有时您的代码在approxPolyDP
之后找不到具有4个顶点的任何轮廓,因此,变量displayCnt
的值仍为None
,如在for循环之前设置的那样因此four_point_transform
函数显示错误,因为它没有使用None
作为输入。
为避免此错误,请在four_point_transform
函数之前,通过以下方法检查displayCnt
的值:if displayCnt is not None:
,如果该值为None,则不要运行该函数。
另外,根据我的说法,for循环中的if条件不正确,因为这种情况在极少数情况下就可以满足,并且在“图像处理”中,可以确信在以下情况下可以使用这种特定条件:至少有1个条件。因此,我认为,如果条件改变,就可以更改。