返回顶部
首页 > 资讯 > 后端开发 > Python >Python+Opencv答题卡识别用例详解
  • 122
分享到

Python+Opencv答题卡识别用例详解

2024-04-02 19:04:59 122人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

使用python3和OpenCV识别一张标准的答题卡。大致的过程如下: 1.读取图片 2.利用霍夫圆检测,检测出四个角的黑圆位置,从确定四个角的位置 3.利用透视变换和四个角的位置,

使用python3OpenCV识别一张标准的答题卡。大致的过程如下:

1.读取图片

2.利用霍夫圆检测,检测出四个角的黑圆位置,从确定四个角的位置

3.利用透视变换和四个角的位置,矫正图片(直接用的网上的图片,没有拍照,所以这一步没有实现)

4.裁剪四个边框,获取边框上小黑格的位置

5.根据小黑格的位置确定每个涂卡区域的位置

6.将答题卡腐蚀和膨胀,遍历所有的格子的区域,计算每个区域内像素值为0的个数,若数量达到某个值,那么就确认这个格子是被黑笔涂过,并记录该位置的题目选项。

具体的实现

一、读取图片,用是imread函数。

二、利用霍夫圆检测位置,这里注意的是HoughCircles的param参数,调的不准,所以检测出来还有其他的干扰圆,最后可以通过设置半径阈值,将四个角的圆筛选出来。最后这个函数返回四个圆的位置和半径。

#检测图中的圆,并返回每个圆的位置和半径
def detect_circles_demo(image):
    temp = image.copy()
    rows,cols,channels = temp.shape
    print(rows,cols)
    location_vcol = []
    dst = cv.pyrMeanShiftFiltering(image,10,100)
    cimage = cv.cvtColor(dst,cv.COLOR_BGR2GRAY)
    #不同的图片,Parmal的值是不一样的
    circles = cv.HoughCircles(cimage,cv.HOUGH_GRADIENT,1,20,param1= 27,param2=30,minRadius=0,maxRadius=0)
    circles = np.uint16(np.around(circles))
    for i in circles[0,:]:
        if i[2] < 20 and i[2] > 10:
            cv.circle(image,(i[0],i[1]),i[2],(0,0,255),2)
            location_vcol.append((i[0],i[1],i[2]))
    # 画出图中圆的位置
    cv.imshow("image",image)
    return location_vcol

三、先将图片整体二直化,再在二直化的图片将四个边框裁剪下来,直接根据四个边角的位置向外或者向里增加或者较少一个半径,确定边框矩形的对角位置。

#获取四个边角的位置
location_RT = location_vcol[0]
location_RB = location_vcol[1]
location_LT = location_vcol[2]
location_LB = location_vcol[3]
 
# 先将原图二值化,注意阈值的取范围,再将二值化图片转换成BGR,方便后面标出小方格的位置
gray = cv.cvtColor(temp, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 100, 255, cv.THRESH_BINARY_INV)
 Matimage = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)
 cv.imshow("Matimage",Matimage)
 
#将图片的四条边裁剪出来
 roilLeft = Matimage[location_LT[1] - location_LT[2]:location_LB[1] + location_LB[2],location_LT[0] -location_LT[2]:location_LB[0] + location_LB[2]]
 roilRight = Matimage[location_RT[1] - location_RT[2]:location_RB[1] + location_RB[2],location_RT[0] - location_RT[2]:location_RB[0]+location_RB[2]]
 roilTop = Matimage[location_LT[0] - location_LT[2]:location_RT[1]+location_RT[2],location_LT[0] - location_LT[2]:location_RT[0] +location_RT[2]]
 roilBottom = Matimage[location_RB[1]-location_RB[2]:location_RB[1] + location_RB[2],location_LB[0] -location_LB[2]:location_RB[0]+location_RB[2]]
 
# 展示四条边的图片
cv.imshow("left",roilLeft)
cv.imshow("right", roilRight)
cv.imshow("top", roilTop)
cv.imshow("bottom", roilBottom)

四、根据裁剪的边框确定边框上小白格的位置。每个方位的计算方式是一样的。每个函数返回的是小格子在源图中的位置。

先来说底部的。这个过程是把截图看成一个坐标系,以行长为横坐标,列高为中坐标,计算统计每个横坐标下,有多少个点是白色的,并将该数值存放于列表vcol中。根据这种算法,能够得出这个列表中应该是rows个元素,而且每个元素的值不超过列高,不低于0。

遍历vcol列表,如果某一个位置为0,后一个位置不为0,那么这个位置就是小白格的起始位置。并记录起始位置在原图中的位置,方便后期遍历整个涂卡区域。

其他的三个方向是同样的道理,

#计算底部小黑格的位置
def sure_bottom(roilBottom,src,a):
    rows, cols, channels = roilBottom.shape
    src_rows,src_cols,src_channels = src.shape
    itemp = 0
    vcol = []
    bottom_vcol = []
    for i in range(0, cols):
        for j in range(0, rows):
            if roilBottom[j, i][0] == 255 and roilBottom[j, i][1] == 255 and roilBottom[j, i][2] == 255:
                itemp = itemp + 1
        vcol.append(itemp)
        itemp = 0
    for i in range(vcol.__len__()):
        if 0 == vcol[i] and vcol[i + 1] > 0:
            cv.line(roilBottom, (i, 0), (i, rows), (0, 0, 255), 2)
            cv.line(src, (i + a, src_rows), (i + a, src_rows - rows), (0, 255, 0), 2)
            bottom_vcol.append(i + a)
    cv.imshow("src-1", roilBottom)
    return bottom_vcol
 
#计算右部小黑格的位置
def sure_Right(roilRight,src,a):
    rows, cols, channels = roilRight.shape
    src_rows, src_cols, src_channels = src.shape
    itemp = 0
    vcol = []
    right_vcol = []
    for i in range(0, rows):
        for j in range(0, cols):
            if roilRight[i, j][0] == 255 and roilRight[i, j][1] == 255 and roilRight[i, j][2] == 255:
                itemp = itemp + 1
        vcol.append(itemp)
        itemp = 0
    print(vcol)
    for i in range(vcol.__len__()):
        if vcol[i] == 0 and vcol[i + 1] > 0:
            cv.line(roilRight, (0, i), (cols, i), (0, 0, 255), 2)
            cv.line(src, (src_cols - cols, i + a ), (src_cols, i + a), (0, 0, 255), 2)
            right_vcol.append(i + a)
    cv.imshow("src", src)
    return right_vcol
 
#计算左边小黑格的位置
def sure_Left(roilLeft,src,a):
    rows, cols, channels = roilLeft.shape
    print(rows, cols)
    itemp = 0
    vcol = []
    left_vcol = []
    for i in range(0, rows):
        for j in range(0, cols):
            if roilLeft[i, j][0] == 255 and roilLeft[i, j][1] == 255 and roilLeft[i, j][2] == 255:
                itemp = itemp + 1
        vcol.append(itemp)
        itemp = 0
    for i in range(vcol.__len__()):
        if vcol[i] == 0 and vcol[i + 1] > 0:
            cv.line(roilLeft, (0, i), (cols, i), (0, 0, 255), 2)
            cv.line(src, (16, i + a), (16 + cols, i + a), (0, 0, 255), 2)
            left_vcol.append(i + a)
    cv.imshow("src", src)
    return left_vcol
 
# 确定顶部小黑格的位置
def sure_Top(roilTop,src,a):
    rows, cols, channels = roilTop.shape
    src_rows, src_cols, src_channels = src.shape
    itemp = 0
    vcol = []
    top_vcol = []
    for i in range(0, cols):
        for j in range(0, rows):
            if roilTop[j, i][0] == 255 and roilTop[j, i][1] == 255 and roilTop[j, i][2] == 255:
                itemp = itemp + 1
        vcol.append(itemp)
        itemp = 0
    for i in range(vcol.__len__()):
        if vcol[i] == 0 and vcol[i + 1] > 0:
            cv.line(roilTop, (i, 0), (i, rows), (0, 0, 255), 2)
            cv.line(src, (i + a, 12), (a + i,48), (0, 0, 255), 2)
            top_vcol.append(i + a)
    cv.imshow("src", src)
    return top_vcol
 
#获取原图位置
    bottom_vcol = sure_bottom(roilBottom,temp,location_LB[0] -location_LB[2])
    right_vcol = sure_Right(roilRight,temp,location_RT[1] - location_RT[2])
    left_vcol = sure_Left(roilLeft,temp,location_LT[1] - location_LT[2])
    top_vcol = sure_Top(roilTop,temp,location_LT[0] - location_LT[2])

五、在原图中全出每个小格子。在此之前要将图片做个预处理,腐蚀和膨胀。这个程序先圈出来的是答题区域的小格子,所以i和j 的范围分别是底部格子数和右边格子数。

先将每个格子的区域找出来,然后遍历这个格子的全部像素,判断是否为0 ,如果为0,那么就isum+1,最后遍历结束,看看isum的个数有没有达到总像素个数的10%,如果达到,那么就可以判定这个区域是被涂过的,记录这个区域对应的题号和选项,以备后面计分。

dst = sure_if_fill(temp)
    for i in range(0,20):
        for j in range(10,26):
            rect = dst[bottom_vcol[i]:bottom_vcol[i] + 9,right_vcol[i]:right_vcol[j] + 3]
            rect_up = (bottom_vcol[i],right_vcol[j])
            rect_down = (bottom_vcol[i] + 9,right_vcol[j] + 3)
 
            # 判断ROI区域是否被填充
            isum = 0
            for ii in range(rect.shape[0]):
                for jj in range(rect.shape[1]):
                    if dst[ii,jj] == 0:
                        isum = isum + 1
            # if isum > 0.1 * rect.shape[0] * rect.shape[1]:
            cv.rectangle(temp,rect_down,rect_up,(0,255,0),2)
            isum = 0
    cv.imshow("dst",temp)
 
 
#检查空格是否被填充
def sure_if_fill(image):
    temp = image.copy()
    gray = cv.cvtColor(temp,cv.COLOR_BGR2GRAY)
    ret,binary = cv.threshold(gray,100,255,cv.THRESH_BINARY)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,3))
    dst = cv.erode(binary,kernel= kernel)
    cv.imshow("dst",dst)
    return dst

这是腐蚀后的图片

这是圈出所有答题区域的图片

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Python+Opencv答题卡识别用例详解

本文链接: https://lsjlt.com/news/163400.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python+Opencv答题卡识别用例详解
    使用Python3和Opencv识别一张标准的答题卡。大致的过程如下: 1.读取图片 2.利用霍夫圆检测,检测出四个角的黑圆位置,从确定四个角的位置 3.利用透视变换和四个角的位置,...
    99+
    2024-04-02
  • 基于Opencv图像识别实现答题卡识别示例详解
    目录1. 项目分析2.项目实验3.项目结果总结在观看唐宇迪老师图像处理的课程中,其中有一个答题卡识别的小项目,在此结合自己理解做一个简单的总结。 1. 项目分析 首先在拿到项目时候,...
    99+
    2024-04-02
  • opencv实现答题卡识别
    本文实例为大家分享了opencv实现答题卡识别的具体代码,供大家参考,具体内容如下 """ 识别答题卡 """   import cv2 import numpy as np   d...
    99+
    2024-04-02
  • python OpenCV实现答题卡识别判卷
    本文实例为大家分享了python OpenCV实现答题卡识别判卷的具体代码,供大家参考,具体内容如下 完整代码: #导入工具包 import numpy as np import argparse import ...
    99+
    2022-06-02
    python OpenCV答题卡识别判卷 python答题卡识别判卷 python答题卡识别
  • 使用 OpenCV-Python 识别答题卡判卷功能
    任务 识别用相机拍下来的答题卡,并判断最终得分(假设正确答案是B, E, A, D, B) 主要步骤 轮廓识别——答题卡边缘识别 透视变换——提取答题卡主体 ...
    99+
    2024-04-02
  • 如何使用OpenCV-Python实现识别答题卡判卷功能
    这篇文章主要为大家展示了“如何使用OpenCV-Python实现识别答题卡判卷功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用OpenCV-Python实现识别答题卡判卷功能”这篇文章...
    99+
    2023-06-22
  • python计算机视觉opencv卡号识别示例详解
    目录一、模板预处理1.将模板设置为二值图2.检测模板的轮廓3.对模板轮廓排序,并将数字和轮廓一一对应,以字典存储4.备注二、图片预处理1.初始化卷积核2.图片预处理第一部分3.图像预...
    99+
    2024-04-02
  • 详解Python OpenCV数字识别案例
    目录前言一、案例介绍二、步骤1、模板读入,以及一些包的导入,函数定义等2、模板预处理,将模板数字分开,并排序3、输入图像预处理,将图像中的数字部分提取出来4、模板匹配总结前言 实践是检验真理的唯一标准。 因为觉得一板...
    99+
    2022-06-02
    python opencv opencv 数字识别
  • Python OpenCV实现识别信用卡号教程详解
    目录通过与 OpenCV 模板匹配的 OCR信用卡 OCR 结果总结今天的博文分为三个部分。 在第一部分中,我们将讨论 OCR-A 字体,这是一种专为辅助光学字符识别算法而创建的字体...
    99+
    2024-04-02
  • Python OpenCV卡号识别如何识别
    本篇内容主要讲解“Python OpenCV卡号识别如何识别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python OpenCV卡号识别如何识别”吧!学在前面从本篇博客起,我们将实际完成几个...
    99+
    2023-06-09
  • Python+OpenCV实现信用卡数字识别的方法详解
    目录一、模板图像处理 二、信用卡图片预处理一、模板图像处理 (1)灰度图、二值图转化 template = cv2.imread('C:/Users/bwy/Desktop...
    99+
    2024-04-02
  • Python答题卡识别并给出分数的实现代码
      哈喽大家好,这里是滑稽研究所。看过我们图像处理系列的朋友,应该知道识别答题卡那期文章。其中利用opencv框架,完美的实现了答题卡填涂区域的识别。在后台有...
    99+
    2024-04-02
  • Python OpenCV招商银行信用卡卡号识别的方法
    学在前面 从本篇博客起,我们将实际完成几个小案例,第一个就是银行卡号识别,预计本案例将写 5 篇左右的博客才可以完成,一起加油吧。 本文的目标是最终获取一套招商银行卡,0~9 数字的...
    99+
    2024-04-02
  • python利用opencv如何实现答题卡自动判卷
    目录1、设定答题卡模板2、读取答题卡图像并对图像进行灰度化处理3、高斯模糊图像去噪点4、使用大津法二值分割图像5、使用开运算去噪点6、使用canny边缘检测算法7、筛选答题区域轮廓,透视变换矫正目标区域使用摄像头实时...
    99+
    2022-06-02
    python opencv答题卡 python答题卡识别 python答题系统
  • Python如何使用opencv进行手势识别详解
    目录前言原理程序部分附另一个手势识别实例总结前言 本项目是使用了谷歌开源的框架mediapipe,里面有非常多的模型提供给我们使用,例如面部检测,身体检测,手部检测等。 原理 首先...
    99+
    2024-04-02
  • OpenCV实战案例之车道线识别详解
    目录一、首先进行canny边缘检测,为获取车道线边缘做准备二、进行ROI提取获取确切的车道线边缘(红色线内部)三、利用概率霍夫变换获取直线,并将斜率正数和复数的线段给分割开来四、离群...
    99+
    2024-04-02
  • OpenCV Python身份证信息识别过程详解
    目录前置环境识别过程身份证区域查找原始图像灰度处理中值滤波二值处理边缘检测边缘膨胀轮廓检测轮廓排序透视变换固定图像大小检测身份证文本位置极度膨胀轮廓查找文本区域筛选出文本区域对文本区...
    99+
    2024-04-02
  • python Opencv实现停车位识别思路详解
    目录1.实现的思路2.整体代码实战1.实现的思路 (1)首先使用一个处理画框的程序,将图片中的有车和无车的停车位给画出来,并且保存坐标(如果画错了,将鼠标移至要删除的框中,右击鼠标,...
    99+
    2024-04-02
  • Python OpenCV图像识别的示例分析
    小编给大家分享一下Python OpenCV图像识别的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、人脸识别主要有以下两种实现方法:哈尔(Haar)级联法:专门解决人脸识别而推出的传统算法;实现步骤:...
    99+
    2023-06-29
  • Python+OpenCV实现图像识别替换功能详解
    OpenCV-Python是一个Python库,旨在解决计算机视觉问题。 OpenCV是一个开源的计算机视觉库,1999年由英特尔的Gary Bradski启动。Bradski在访学...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作