我正在为试卷实施OMR系统。但在确定实心圆圈时遇到问题。我成功地获得了这些灰度级区域。
问题是:
- 二进制阈值(自适应和固定)和计数非零像素会产生很多错误,因为圆圈中的字母和移动相机拍摄的照片亮度不同。
- 此survey中描述的尝试技术使用圆的平均灰度值做标记是否填充,但是当人们拍摄照片时,由于不同的光源,图像的亮度不均匀得到了很多错误的结果。
- 人们也不遵循我们填写整个圈子的规则,在这种情况下算法也需要健全
Sample images
我已经有大约10 GB的样本,因此机器学习或其他统计方法可能会有用
有没有人知道将圆圈分类为填充的其他方法?
答案 0 :(得分:0)
Since it is not a straight forward problem, it needs lot of tweaking to make it robust. But I would like suggest you a good starting point. You can play with it and try to make it work.
import numpy as np
import cv2
image_ori = cv2.imread("circle_opt.png")
lower_bound = np.array([0, 0, 0])
upper_bound = np.array([255, 255, 195])
image = image_ori
mask = cv2.inRange(image_ori, lower_bound, upper_bound)
masked_red = cv2.bitwise_and(image, image, mask=mask)
kernel = np.ones((3,3),np.uint8)
closing = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
contours = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)[0]
contours.sort(key=lambda x:cv2.boundingRect(x)[0])
print len(contours)
for c in contours:
(x,y),r = cv2.minEnclosingCircle(c)
center = (int(x),int(y))
r = int(r)
if 10 <= r <= 15:
cv2.circle(image,center,r,(0,255,0),2)
# cv2.imwrite('omr_processed.png', image_ori)
cv2.imshow("original",image_ori)
cv2.waitKey(0)
The result I got from my code on the image you shared was this
You can apply thresholds to these green circled patches and then count non-zeros to get if the circle is marked or not. You can play with lower and upper_bound to try to make the solution robust.
Hope this helps! Good luck on your problem solving :)