python - opencv - OMR -Python - 排序问题
问题描述
我编写了一个脚本,它应该拍摄一张扫描的图像并检查调查结果。我已经设法让它识别调查选项框并确定在页面上选中了哪个选项框。
问题:我希望能够根据索引确定哪个框已打勾。因此,在下面的示例中,我有选项 1-5,数字 2 被勾选,但是由于某种原因,我的框的顺序在我的列表中混淆了,在控制台输出中它表明复选框 5 是票。我需要这个来正确告诉我复选框 2 已选中,以便我可以继续存储/分析完整调查的信息
import os
import sys
import cv2
if os.path.isfile(file_path):
# read the image
img = cv2.imread(file_path, 1)
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# obtain inverse binary image
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# find contours
_, contours, hierarchy = cv2.findContours(binary, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
# select contours having a parent contour and append them to a list
contour_list = []
for h in hierarchy[0]:
if h[0] > -1 and h[2] > -1:
contour_list.append(h[2])
print str(len(contour_list))+" contours found"
# copy original image
img2 = img.copy()
a = 0
# calculate the average size of contour and use this rough size for assuming we have a checkbox
for j, i in enumerate(contour_list):
a = a + cv2.contourArea(contours[i])
mean_area = int(a / len(contour_list))
boxes_found = 0
options = 0
answer = 0
# draw those contours
for cnt in contour_list:
# if contour roughly matches our average size
if (cnt > 0) & (cv2.contourArea(contours[cnt]) > mean_area):
# print len(contours[cnt])
options += 1
answer += 1
if len(contours[cnt]) > 210:
# larger contour length signifies a tick
cv2.drawContours(img2, [contours[cnt]], -1, (0, 255, 0), 2)
print "option: "+str(options)+" ticked"
# print str(options) + " options"
# options = 0
else:
cv2.drawContours(img2, [contours[cnt]], -1, (0, 255, 255), 2)
boxes_found += 1
cv2.imshow('img2', img2)
cv2.waitKey(0)
print "Boxes found: " + str(boxes_found)
else:
print "no file"
控制台输出:
6 contours found
option: 5 ticked
Boxes found: 5
解决方案
这篇文章说findContours
从图像底部找到轮廓。因此,在这种情况下,对象从左到右排序,您需要根据它们的x
坐标来识别它们。
接受你所拥有的[contours[cnt]]
价值观
cv2.drawContours(img2, [contours[cnt]], -1, (0, 255, 0), 2)
并且订单中的位置应该很容易出现。
推荐阅读
- javascript - 使用点击处理程序修改段落的 JavaScript 类
- scala - 重写抽象类型成员
- c# - 使用 dotnet core 2.1 在 AWS Lambda 函数中进行依赖注入
- android - 如何淡化文本视图的某些字符?
- python - 为什么当客户端断开连接时,`select()` 会将客户端返回为可写的?
- python - 房屋贷款负担能力计算器?
- google-cloud-platform - 从本地主机到本地主机没有密码的gcp ssh连接失败
- angular - 如何验证具有材料形式字段的角度形式?
- javascript - 获取和显示时间线数据
- c++ - 如何使用 Visual Code 和 Platform IO 将环境变量注入 CPP 文件?