1

我正在为试卷实施 OMR 系统。但是在确定实心圆时遇到问题。我已经成功地获得了这些感兴趣的灰度区域。

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

4

1 回答 1

1

由于这不是一个直截了当的问题,因此需要进行大量调整以使其健壮。但我想建议你一个好的起点。您可以使用它并尝试使其工作。

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)

我从您共享的图像上的代码中得到的结果是这样的

绿色圆圈

您可以将阈值应用于这些绿色圆圈的补丁,然后计算非零以获取圆圈是否被标记。您可以使用 lower 和 upper_bound 来尝试使解决方案健壮。

希望这可以帮助!祝你解决问题好运:)

于 2017-04-06T17:15:19.957 回答