使用带有网络摄像头的 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 条件。
我想用相机阅读一些数字显示。我在这里找到了检测和阅读显示的教程: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 条件。