保护私人版权,尊重他人版权。转载请注明出处并附带页面链接
使用到的工具/库
- OpenCV:OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。可用于开发实时的图像处理、计算机视觉以及模式识别程序。
- imutils:imutils是Adrian Rosebrock开发的一个python工具包,它整合了opencv、numpy和matplotlib的相关操作,主要是用来进行图形图像的处理,如图像的平移、旋转、缩放、骨架提取、显示等等
识别过程
以下面这张答题卡为例
预处理
1 | import imutils |
gray
blurred
边缘检测
1 | edged = imutils.auto_canny(blurred) |
edged
关于canny边缘检测算法原理和用法,可查看下面几篇文章
透视变换
1 | from imutils.perspective import four_point_transform |
warped
变换后得到了答题卡需要识别的区域
关于findContours的用法,参考文章:Opencv轮廓检测findContours分析(层次结构)
提取选择题答案
1 | # 固定大小 |
得到二值图像
thresh
接下来继续使用轮廓提取答案
1 | # 在二值图像中查找轮廓,然后初始化题目对应的轮廓列表 |
paper
成功识别到选择题部分答案
接下来根据坐标计算题号和对应答案
1 | def judge(x, y): |
1 | [{"id": 1, "option": "B", "c": [120, 349]}, {"id": 2, "option": "C", "c": [170, 374]}, {"id": 3, "option": "A", "c": [70, 398]}, {"id": 4, "option": "C", "c": [169, 423]}, {"id": 5, "option": "D", "c": [219, 447]}, {"id": 6, "option": "A", "c": [309, 349]}, {"id": 7, "option": "A", "c": [310, 374]}, {"id": 8, "option": "A", "c": [308, 398]}, {"id": 9, "option": "C", "c": [409, 423]}, {"id": 10, "option": "C", "c": [408, 449]}, {"id": 11, "option": "B", "c": [597, 348]}, {"id": 12, "option": "D", "c": [697, 373]}, {"id": 13, "option": "A", "c": [546, 399]}, {"id": 14, "option": "C", "c": [647, 422]}, {"id": 15, "option": "B", "c": [597, 449]}, {"id": 16, "option": "D", "c": [938, 348]}, {"id": 17, "option": "C", "c": [887, 373]}, {"id": 18, "option": "B", "c": [836, 399]}, {"id": 19, "option": "B", "c": [834, 424]}, {"id": 20, "option": "A", "c": [785, 447]}, {"id": 21, "option": "B", "c": [121, 480]}, {"id": 22, "option": "C", "c": [169, 505]}, {"id": 23, "option": "D", "c": [220, 530]}, {"id": 24, "option": "A", "c": [69, 554]}, {"id": 25, "option": "C", "c": [170, 580]}, {"id": 26, "option": "B", "c": [358, 481]}, {"id": 27, "option": "D", "c": [458, 505]}, {"id": 28, "option": "C", "c": [405, 530]}, {"id": 29, "option": "D", "c": [458, 554]}, {"id": 30, "option": "A", "c": [309, 579]}, {"id": 31, "option": "C", "c": [646, 482]}, {"id": 32, "option": "D", "c": [698, 506]}, {"id": 33, "option": "B", "c": [595, 530]}, {"id": 34, "option": "C", "c": [646, 555]}, {"id": 35, "option": "A", "c": [546, 580]}, {"id": 36, "option": "A", "c": [782, 482]}, {"id": 37, "option": "B", "c": [835, 506]}, {"id": 38, "option": "D", "c": [936, 531]}, {"id": 39, "option": "C", "c": [888, 556]}, {"id": 41, "option": "B", "c": [120, 612]}, {"id": 42, "option": "D", "c": [219, 638]}, {"id": 43, "option": "B", "c": [120, 662]}, {"id": 44, "option": "D", "c": [218, 687]}, {"id": 45, "option": "A", "c": [70, 711]}, {"id": 46, "option": "C", "c": [408, 612]}, {"id": 47, "option": "D", "c": [458, 638]}, {"id": 48, "option": "B", "c": [358, 662]}, {"id": 49, "option": "D", "c": [458, 687]}, {"id": 50, "option": "A", "c": [308, 712]}, {"id": 55, "option": "C", "c": [885, 582]}] |
成功得到了答案,id为题号,option为选项,c为答案的坐标