OMR:评估实心圆圈

时间:2017-04-06 08:49:52

标签: opencv computer-vision emgucv optical-mark-recognition

我正在为试卷实施OMR系统。但在确定实心圆圈时遇到问题。我成功地获得了这些灰度级区域。

问题是:
  - 二进制阈值(自适应和固定)和计数非零像素会产生很多错误,因为圆圈中的字母和移动相机拍摄的照片亮度不同。
  - 此survey中描述的尝试技术使用圆的平均灰度值做标记是否填充,但是当人们拍摄照片时,由于不同的光源,图像的亮度不均匀得到了很多错误的结果。
- 人们也不遵循我们填写整个圈子的规则,在这种情况下算法也需要健全 Sample images
我已经有大约10 GB的样本,因此机器学习或其他统计方法可能会有用 有没有人知道将圆圈分类为填充的其他方法?

1 个答案:

答案 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

Green circles

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 :)

相关问题