[英]Detect All Circles in an image (Optical Mark Recognition) using Python OpenCV
I need to make a OMR detection system using Python for my High School Vacation Project(which potentially might be used by the school to some extent if it is reliable enough) , I have done quite a bit of research on it , and have tried out everything from contours to template matching, I feel template matching works fine but it can only detect one circle out of many in the OMR sheet, can someone help me in figuring out how I can detect multiple(all) circles(irrespective of whether they are bubbled or not), in the omr sheet and their respective coordinates , that would be enough for me.我需要使用 Python 为我的高中假期项目制作一个 OMR 检测系统(如果它足够可靠,学校可能会在某种程度上使用它),我已经做了很多研究,并尝试过从轮廓到模板匹配的所有内容,我觉得模板匹配工作正常,但它只能从 OMR 表中的许多圆圈中检测一个,有人可以帮助我弄清楚如何检测多个(所有)圆圈(无论它们是否是冒泡与否),在 omr 表及其各自的坐标中,这对我来说就足够了。
What I have tried:我尝试过的:
import numpy as np
import cv2
img = cv2.resize(cv2.imread('assets/omr_match1.jpg', 0), (0, 0), fx=0.2, fy=0.5)
template = cv2.resize(cv2.imread('assets/circle.jpg', 0), (0, 0), fx=0.2, fy=0.5)
h, w = template.shape
methods = [cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED, cv2.TM_CCORR,
cv2.TM_CCORR_NORMED, cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]
methods=methods[0]
# This is one among the above which works perfectly
for method in methods:
img2 = img.copy()
result = cv2.matchTemplate(img2, template, method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
location = min_loc
else:
location = max_loc
bottom_right = (location[0] + w, location[1] + h)
cv2.rectangle(img2, location,bottom_right, 0, 1)
cv2.imshow('Match', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
See above, only one random circle is marked and not all circles.见上图,只标记了一个随机圆圈,而不是所有圆圈。
Here we go:开始了:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('/path/tabela_circle.jpg', 0)
template = cv2.imread('/path/circle.jpg', 0)
h, w = template.shape
res = cv2.matchTemplate(img,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
cv2.imwrite('res.png',img)
Also works to detect only answers:也适用于仅检测答案:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.