I want to read some digital displays using a camera. I found a tutorial to detect and read the display here: https://www.pyimagesearch.com/2017/02/13/recognizing-digits-with-opencv-and-python/
Because I need the reading real time, I set the video input from the webcam. Here's my code:
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()
At the first try, the program ran well although sometimes it detected random rectangle objects and sent this error when it crashed:
File "7segmentcam.py", line 63, in <module>
warped = four_point_transform(gray, displayCnt.reshape(4, 2))
AttributeError: 'NoneType' object has no attribute 'reshape'
After I tweaked some parameters in lines 37 and 38, the program wasn't responding and crashed with the same error above. Is there any better option to run the program without errors when the camera doesn't detect any object?