在我使用 OpenCV2 和 Python 3 通过摄像头 (omr) 纠正考试的程序中,它检测到 USB 摄像头,但不检测到笔记本电脑摄像头(内部)的程序:
import tkinter as tk
import cv2
from PIL import Image, ImageTk
from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import argparse
import imutils
import os
import time
import sys
# the time for results name
timestr = time.strftime("%Y%m%d-%H%M%S")
# video frame
width, height = 400, 600
if cv2.VideoCapture(-1) is True:
cap = cv2.VideoCapture(-1)
else:
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
sucess, frame = cap.read()
def process_bub():
## cam her
cv2.imwrite("images/test10.png", frame)
# load the image, convert it to grayscale, blur it
# slightly, then find edges
cap = cv2.imread("images/test10.png")
gray = cv2.cvtColor(cap, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 75, 200)
# find contours in the edge map, then initialize
# the contour that corresponds to the document
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
docCnt = None
# ensure that at least one contour was found
if len(cnts) > 0:
# sort the contours according to their size in
# descending order
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
# loop over the sorted contours
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
# if our approximated contour has four points,
# then we can assume we have found the paper
if len(approx) == 4:
docCnt = approx
break
# apply a four point perspective transform to both the
# original image and grayscale image to obtain a top-down
# birds eye view of the paper
paper = four_point_transform(cap, docCnt.reshape(4, 2))
warped = four_point_transform(gray, docCnt.reshape(4, 2))
# apply Otsu's thresholding method to binarize the warped
# piece of paper
thresh = cv2.threshold(warped, 0, 255,
cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
# find contours in the thresholded image, then initialize
# the list of contours that correspond to questions
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
questionCnts = []
# loop over the contours
for c in cnts:
# compute the bounding box of the contour, then use the
# bounding box to derive the aspect ratio
(x, y, w, h) = cv2.boundingRect(c)
ar = w / float(h)
# in order to label the contour as a question, region
# should be sufficiently wide, sufficiently tall, and
# have an aspect ratio approximately equal to 1
if w >= 20 and h >= 20 and ar >= 0.9 and ar <= 1.1:
questionCnts.append(c)
# sort the question contours top-to-bottom, then initialize
# the total number of correct answers
questionCnts = contours.sort_contours(questionCnts,
method="top-to-bottom")[0]
correct = 0
# each question has 5 possible answers, to loop over the
# question in batches of 5
for (q, i) in enumerate(np.arange(0, len(questionCnts), 4)):
# sort the contours for the current question from
# left to right, then initialize the index of the
# bubbled answer
cnts = contours.sort_contours(questionCnts[i:i + 4])[0]
bubbled = None
# loop over the sorted contours
for (j, c) in enumerate(cnts):
# construct a mask that reveals only the current
# "bubble" for the question
mask = np.zeros(thresh.shape, dtype="uint8")
cv2.drawContours(mask, [c], -1, 255, -1)
# apply the mask to the thresholded image, then
# count the number of non-zero pixels in the
# bubble area
mask = cv2.bitwise_and(thresh, thresh, mask=mask)
total = cv2.countNonZero(mask)
# if the current total has a larger number of total
# non-zero pixels, then we are examining the currently
# bubbled-in answer
if bubbled is None or total > bubbled[0]:
bubbled = (total, j)
# initialize the contour color and the index of the
# *correct* answer
color = (0, 0, 255)
k = ANSWER_KEY[q]
# check to see if the bubbled answer is correct
if k == bubbled[1]:
color = (0, 255, 0)
correct += 1
# draw the outline of the correct answer on the test
cv2.drawContours(paper, [cnts[k]], -1, color, 3)
# grab the test taker
score = (correct / 5.0) * 100
degree = correct
print("[INFO] score: {:.1f}/10".format(degree))
cv2.putText(paper, "{:.1f}/10".format(degree), (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
cv2.imshow("Ohod Resuls", paper)
cv2.imwrite("results/theResult" + timestr + ".png", paper)
cv2.waitKey(0)
# --- functions ---
ANSWER_KEY = {}
def on_button():
for i, var in enumerate(o_vars):
ANSWER_KEY[int(i)] = int(OPTIONS[var.get()])
print()
# --- main ---
OPTIONS = {
'A': '3',
'B': '2',
'C': '1',
'D': '0',
}
root = tk.Tk()
root.title('OhodO')
root.bind('<Escape>', lambda e: root.quit())
lmain = tk.Label(root)
lmain.pack(side ="left")
def show_frame():
_, frame = cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_frame)
show_frame()
def restart_program():
python = sys.executable
os.execl(python, python, *sys.argv)
def dic_clear():
ANSWER_KEY.clear()
# --- OptionMenu ---
tk.Label(root, text='Answer Keys', bg='#aaa').pack(fill='x')
o_vars = []
for i in range(10):
var = tk.StringVar(value='- select -')
o_vars.append(var)
o = tk.OptionMenu(root, var, *OPTIONS)
o.pack()
# --- others ---
b1 = tk.Button(root, text='Ok', command=on_button)
b1.pack(fill='x')
b2 = tk.Button(root, text='Clear', command=dic_clear)
b2.pack(fill='x')
b3 = tk.Button(root, text='Results', command=process_bub)
b3.pack(fill='x')
b4 = tk.Button(root, text='Close', command=root.destroy)
b4.pack(fill='x')
root.mainloop()
问题出在这段代码中:
b3 = tk.Button(root, text='Results', command=process_bub)
b3.pack(fill='x')
- 当我点击“结果”按钮时,程序完美运行,也就是说,它给了我放在相机前的学生论文的结果,并保存了一张带有结果的图像。但是,当我关闭带有结果的弹出窗口时,程序也会关闭吗?为什么是这样?
2-当我单击弹出窗口角落的 (x) 时,程序关闭而不是弹出窗口?!。
该程序(代码)在(GPL)中,因此您可以免费使用它。