前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用python3+opencv3实现的识别答题卡的例子(02)

使用python3+opencv3实现的识别答题卡的例子(02)

原创
作者头像
我是攻城师
发布于 2018-05-22 13:13:06
发布于 2018-05-22 13:13:06
1.2K2
举报
文章被收录于专栏:我是攻城师我是攻城师

answer_sheet_scan

使用python3+opencv3实现的一些识别答题卡的例子

识别例子02

例子02是ayoungprogrammer博客上参考作者原版C++代码和思路,然后改造成python版本的,先在本地运行成功之后,然后加上自己的理解,给大多数核心代码加上了详细的中文注释,并在每一个关键阶段都会弹出具体的窗体展示识别流程,这样便于大家更能详细的看到核心部分的细节,感兴趣的同学,可以自己在再尝试加一些更细部分的debug弹窗。

本地PyCharm运行后一些截图:

(1)原图

01.jpg
01.jpg

(2)灰度后的图

02.jpg
02.jpg

(3)自适应二值化后的图

03.jpg
03.jpg

(4)标记轮廓后的原图

04.jpg
04.jpg

(5)提取答题内容区后的图

05.jpg
05.jpg

(6)对答题内容区进行自适应二值化后的图

06.jpg
06.jpg

(7)标记答案后的图

07.jpg
07.jpg

代码如下:

代码语言:txt
AI代码解释
复制
# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
from imutils.perspective import four_point_transform
from imutils import contours
import numpy as np
import imutils

import cv2 as cv

# 加载原图,可在项目imgs/example02目录下找到
img=cv.imread("E:\\tmp\\test6.jpg")

# 打印原图
cv.imshow("orgin",img)

# 灰度化
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)

# 打印灰度图
cv.imshow("gray",gray)

# 高斯滤波,清除一些杂点
blur=cv.GaussianBlur(gray,(3,3),0)

# 自适应二值化算法
thresh2 = cv.adaptiveThreshold(blur,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV,131,4)

# 打印二值化后的图
cv.imshow("thresh2",thresh2)

# 寻找轮廓
image, cts, hierarchy = cv.findContours(thresh2, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

# 打印找到的轮廓
print("轮廓数:",len(cts))

# 对拷贝的原图进行轮廓标记
contour_flagged=cv.drawContours(img.copy(), cts, -1, (0, 0, 255), 3)
# 打印轮廓图
cv.imshow("contours_flagged", contour_flagged)
# 按像素面积降序排序
list = sorted(cts, key=cv.contourArea, reverse=True)

# 遍历轮廓
for ct in list:
    # 周长,第1个参数是轮廓,第二个参数代表是否是闭环的图形
    peri = 0.01 * cv.arcLength(ct, True)
    # 获取多边形的所有定点,如果是四个定点,就代表是矩形
    approx = cv.approxPolyDP(ct, peri, True)
    # 只考虑矩形
    if len(approx) == 4:





        # 从原图中提取所需的矫正图片
        ox = four_point_transform(img, approx.reshape(4, 2))
        # 从原图中提取所需的矫正图片
        tx = four_point_transform(gray, approx.reshape(4, 2))

        # 打印矫正后的灰度图
        cv.imshow("tx",tx)

        # 对矫正图进行高斯模糊
        blur = cv.GaussianBlur(tx, (3, 3), 0)

        # 对矫正图做自适应二值化
        thresh2 = cv.adaptiveThreshold(blur, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 131, 4)

        # 打印矫正后的二值化图
        cv.imshow("tx_thresh2", thresh2)

        # 获取轮廓
        r_image, r_cts, r_hierarchy = cv.findContours(thresh2, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

        # 打印得到轮廓数量
        print("第二层轮廓数:", len(r_cts))

        # 用于存储答案的python list变量
        question_list=[]
        for r_ct in r_cts :
            # 转为矩形,分别获取 x,y坐标,及矩形的宽和高
            x, y, w, h = cv.boundingRect(r_ct)

            # 过滤掉不符合答案坐标和长宽的选项
            if x>2 and y>2 and w>20 and h>20 :
                # cv.drawContours(ox, r_ct, -1, (0, 0, 255), 1)
                question_list.append(r_ct)

        print("答案总数:",len(question_list))

        # 按坐标从上到下排序
        questionCnts = contours.sort_contours(question_list, method="top-to-bottom")[0]

        #  使用np函数,按5个元素,生成一个集合
        for (q, i) in enumerate(np.arange(0, len(questionCnts), 5)):

            # 每一个行5个答案,从左到右排序
            cnts = contours.sort_contours(questionCnts[i:i + 5])[0]

            # 存储一行题里面的每个答案
            ans_list = []
            for (j, cc) in enumerate(cnts):

                # 生成全黑画布
                mask = np.zeros(thresh2.shape, dtype="uint8")
                # 将每一个答案按轮廓写上去,并将填充颜色设置成白色
                tpp = cv.drawContours(mask, [cc], -1, 255, -1)
                # 两个图片做位运算
                mask = cv.bitwise_and(thresh2, thresh2, mask=mask)
                # 统计每个答案的像素
                total = cv.countNonZero(mask)

                # 添加到集合里面
                ans_list.append( (total,j) )

            # 按像素大小排序
            ans_list=sorted(ans_list,key=lambda  x:x[0],reverse=True)

            max_ans_num=ans_list[0][1]
            max_ans_size=ans_list[0][0]
            print("答案序号:",max_ans_num,"列表:",ans_list)

            # 给选中答案,标记成红色
            cv.drawContours(ox, cnts[max_ans_num], -1, (0, 0, 255), 2)




        cv.imshow("answer_flagged", ox)


        # 最大的轮廓就是我们想要的,之后的就可以结束循环了
        break



# 阻塞等待窗体关闭
cv.waitKey(0)

源码已经上传我的github上,欢迎大家fork学习.

https://github.com/qindongliang/answer_sheet_scan

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
2 条评论
热度
最新
这个不错,先处理图片然后再找答案吗?
这个不错,先处理图片然后再找答案吗?
11点赞举报
对的
对的
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
使用python3+opencv3实现的识别答题卡的例子(02)
例子02是ayoungprogrammer博客上参考作者原版C++代码和思路,然后改造成python版本的,先在本地运行成功之后,然后加上自己的理解,给大多数核心代码加上了详细的中文注释,并在每一个关键阶段都会弹出具体的窗体展示识别流程,这样便于大家更能详细的看到核心部分的细节,感兴趣的同学,可以自己在再尝试加一些更细部分的debug弹窗。
我是攻城师
2018/07/23
9310
使用python3+opencv3实现的识别答题卡的例子(02)
使用python3+opencv3实现的识别答题卡的例子(01)
由于工作需要,最近在研究关于如何通过程序识别答题卡的客观题的答案,之前虽然接触过python,但对于计算机视觉这一块却完全是一个陌生的领域,经过各种调研,发现网上大多数的例子都是采用的OpenCV这个开源库来做的,OpenCV是计算机视觉领域的处理的一个非常优秀的开源库,原生由C++编写,也提供了各个主流编程语言的接口支持,这里选择python完全是因为python在计算机科学领域有着压倒性的优势和生态系统,所以使用它毫无疑问,最快上手的方式莫过于直接阅读网上已有的例子或者轮子了,通过阅读源码以问题驱动的方
我是攻城师
2018/05/15
2.2K0
OpenCV二值图像案例分析精选 | 第二期
大家好,之前发过一篇文章是知识星球上问题,选择了几个经典的二值图像分析问题,从思路到代码实现给大家分析一波,最近又总结收录了知识星球上的提问,实现了从思路分析到代码实现的完整,下面我们就来看看这几个案例思路分析、运行效果、实现的相关API说明等。
OpenCV学堂
2019/09/12
9840
OpenCV二值图像案例分析精选 | 第二期
OpenCV-简易答题卡识别
参考自:https://www.pyimagesearch.com/2016/10/03/bubble-sheet-multiple-choice-scanner-and-test-grader-using-omr-python-and-opencv/
xxpcb
2020/08/04
1.4K0
Python OpenCV4趣味应用系列(九)---划痕缺陷检测实例
比如Canny边缘检测也可以,只是阈值难于调节。当然,实现方法不唯一,大家可以自己尝试一下。
Color Space
2020/01/13
8.5K0
Python OpenCV4趣味应用系列(九)---划痕缺陷检测实例
基于OpenCV的手掌检测和手指计数
OpenCV(开源计算机视觉库)是一个开源计算机视觉和机器学习软件库。OpenCV的构建旨在为计算机视觉应用程序提供通用的基础结构,并加速在商业产品中使用机器感知。
小白学视觉
2020/09/22
2K0
基于OpenCV的手掌检测和手指计数
python 基于opencv 绘制图像轮廓
这篇文章主要介绍了python 基于opencv 绘制图像轮廓的示例,帮助大家更好的利用python的opencv库处理图像,感兴趣的朋友可以了解下
python学习教程
2021/01/04
2K0
python 基于opencv 绘制图像轮廓
OpenCV学习+常用函数记录③:霍夫变换与轮廓提取
OpenCV 霍夫变换与轮廓提取 3. 霍夫变换 3.1 霍夫直线 3.2 霍夫圆 4. 轮廓提取 4.1 查找轮廓 4.2 绘制轮廓 3. 霍夫变换 首先放上霍夫变换官方文档:[霍夫直线变换官网文档] 3.1 霍夫直线 import cv2 as cv import matplotlib.pyplot as plt import numpy as np # 1. 将图片以灰度的方式读取进来 img = cv.imread("../img/weiqi.jpg", cv.IMREAD_COLOR) gr
小黑鸭
2020/11/24
1K0
利用Python开发智能阅卷系统(附源代码)
随着现代图像处理和人工智能技术的快速发展,不少学者尝试讲CV应用到教学领域,能够代替老师去阅卷,将老师从繁杂劳累的阅卷中解放出来,从而进一步有效的推动教学质量上一个台阶。
统计学家
2019/12/10
2.2K0
利用Python开发智能阅卷系统(附源代码)
二值分析 | OpenCV + skimage如何提取中心线
显然OpenCV中常见的轮廓分析无法获得上面的中心红色线段,本质上这个问题是如何提取二值对象的骨架,提取骨架的方法在OpenCV的扩展模块中,另外skimage包也支持图像的骨架提取。这里就分别基于OpenCV扩展模块与skimage包来完成骨架提取,得到上述图示的中心线。
OpenCV学堂
2020/10/27
4.9K0
二值分析 | OpenCV + skimage如何提取中心线
实战 | OpenCV两种不同方法实现粘连大米分割计数(步骤 + 代码)
本文主要介绍基于OpenCV的两种不同方法实现粘连大米分割计数,并给详细步骤和代码。
Color Space
2024/01/18
1K0
实战 | OpenCV两种不同方法实现粘连大米分割计数(步骤 + 代码)
opencv-python图像处理常用方法整理(一)
在完成毕业设计后我再也没有碰过图像处理相关的东西,进入公司后也是作为前端开发学习和工作(于是乎才有了Vue的学习笔记),但是当我再开始做图像处理相关的事情时,我发现自己全然忘却了怎么调用函数,于是乎决定整理一份。
月落星河Tsukistar
2022/02/18
5410
opencv-python图像处理常用方法整理(一)
OpenCV中几何形状识别与测量
OpenCV中几何形状识别与测量 ---- 写有代码的文章、做有情怀的人 ---- 经常看到有学习OpenCV不久的人提问,如何识别一些简单的几何形状与它们的颜色,其实通过OpenCV的轮廓发现与几何分析相关的函数,只需不到100行的代码就可以很好的实现这些简单几何形状识别与对象测量相关操作。本文就会演示给大家如何通过OpenCV 轮廓发现与几何分析相关函数实现如下功能: 几何形状识别(识别三角形、四边形/矩形、多边形、圆) 计算几何形状面积与周长、中心位置 提取几何形状的颜色 在具体代码实现与程序演示之前
OpenCV学堂
2018/04/18
7.7K0
OpenCV中几何形状识别与测量
二值图像分析案例精选
最近一直有人在知识星球上向我提问很多二值图像分析相关的问题,特别选择了两个典型的轮廓分析问题。进行分析与编码实现与演示,废话不多说,先看第一个问题。
OpenCV学堂
2019/05/31
7920
Halcon缺陷检测实例转OpenCV实现(一)
Halcon中对应的例子为novelty_detection_dyn_threshold.hdev,如下:
Color Space
2020/12/08
1.4K0
Python+OpenCV检测灯光亮点
本篇博文分享一篇寻找图像中灯光亮点(图像中最亮点)的教程,例如,检测图像中五个灯光的亮点并标记,项目效果如下所示:
不脱发的程序猿
2021/01/20
1.2K0
opencv实现银行卡号识别
总体的过程就是将图片转换为二值图像,然后直接把所有的外轮廓都提取出来,然后根据这些轮廓的左上角坐标来进行排序,在排序之后我们就获得了单独的数字图像,如下图
小王不头秃
2024/06/19
3410
opencv实现银行卡号识别
Halcon转OpenCV实例--复杂背景下缺陷检测(附源码)
导读 本文主要介绍一个复杂背景下缺陷检测的实例,并将Halcon实现转为OpenCV。 实例来源 实例来源于51Halcon论坛的讨论贴: https://www.51halcon.com/foru
Color Space
2021/07/01
2.2K0
【OpenCV入门之九】轮廓查找和多边形包围轮廓
学习计算机视觉最重要的能力应该就是编程了,为了帮助小伙伴尽快入门计算机视觉,小白准备了【OpenCV入门】系列。新的一年文章的内容进行了很大的完善,主要是借鉴了更多大神的文章,希望让小伙伴更加容易理解。如果小伙伴觉得有帮助,请点击一下文末的“好看”鼓励一下小白。
小白学视觉
2019/06/02
1.9K0
分水岭算法实现图像分割
https://pyimagesearch.com/2015/11/02/watershed-opencv/
小锋学长生活大爆炸
2022/03/29
4690
分水岭算法实现图像分割
相关推荐
使用python3+opencv3实现的识别答题卡的例子(02)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档