基于opencv的试卷检测识别(opencv,Tensorflow)

本文介绍了一个基于opencv的试卷识别项目,作者分享了如何识别试卷中的手写数字,并提供了数据集制作方法和源码。识别过程包括自动截取题目并保存,分数则保存在txt文本中。手写数字识别部分,作者建议使用自建数据集而非预训练的mnist,以提高识别准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做了一个基于opencv的试卷识别项目,在此分享一下。

文末附有源码。

视频观看:

20211212

主界面:
在这里插入图片描述
选择图片后:
在这里插入图片描述
识别以后:
在这里插入图片描述
识别完成以后会自动截取不同的题目,然后保持到不同的文件夹中,分数会单独的保存到一个txt文本中。

手写数字数据集:

手写数字识别代码,建议不要直接用mnist手写数字数据集,因为使用这个数据集训练出来的网络,根本识别不了我自己写的数字,亲身体验!没办法,我只好自己制作了手写数据集,其实很简单。数据集如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其余的都差不多是这样,就不过多展示了。需要注意的是图片上面只有数字是黑色的,这样方面提取出数字,如果写错了,可以用一些图像编辑的软件将错的部分涂成白色即可,就和上图一样。
手写数字识别代码:

import tensorflow as tf
import cv2 as cv
import numpy as np
from get_data import *

model=tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128,activation='relu'),
    tf.keras.layers.Dense(128,activation='relu'),
    tf.keras.layers.Dense(128,activation='relu'),
    tf.keras.layers.Dense(10,activation='softmax')
])
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])
model.fit(x_train,y_train,batch_size=32,epochs=10,validation_split=0.1,validation_freq=1)
model.save('mode_2.h5')

是不是很简单呢?请看第四行:

from get_data import *

关于图像处理的部分在get_data.py这个代码中,下面是get_data.py的代码。

get_data.py

import numpy as np
import cv2 as cv

x_train=[]
y_train=[]


aa=9
for aa in range(10):
    src=cv.imread('data/{}.jpg'.format(aa))
    gray=cv.cvtColor(src,cv.COLOR_BGR2GRAY)
    thred=np.where(gray>150,255,0).astype('uint8')
    thred=255-thred
    #开闭运算
    k = np.ones((3, 3), np.uint8)
    #thred=cv.dilate(thred,k)
    thred = cv.morphologyEx(thred, cv.MORPH_CLOSE, k)

    cnts=cv.findContours(thred,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)[0]
    print(len(cnts))

    for i in cnts:
        area = cv.contourArea(i)
        if aa!=1:
            b=20
        else:b=15
        if area>=b:
            x, y, w, h = cv.boundingRect(i)
            cv.rectangle(src,(x,y),(x+w,y+h),(0,0,255),2)
            lkuo=thred[y:y+h,x:x+w]
            da = max(h, w)
            rate = da / 40
            ro = cv.resize(lkuo, (int(w / rate), int(h / rate)))
            h, w = ro.shape
            t, b = int((43 - h) / 2), 43 - h - int((43 - h) / 2)
            l, r = int((43 - w) / 2), 43 - w - int((43 - w) / 2)

            ro = cv.copyMakeBorder(ro, t, b, l, r, cv.BORDER_CONSTANT, value=0)

            ro = cv.resize(ro, (40, 40))
            ro = np.where(ro > 0, 255, 0).astype('float32')
            ro = ro / 255
            x_train.append(ro)
            y_train.append(aa)

x_train=np.array(x_train).astype('float32')
y_train=np.array(y_train).astype('float32')
y_train=np.reshape(y_train,(y_train.shape[0],1))
np.random.seed(1)
np.random.shuffle(x_train)
np.random.seed(1)
np.random.shuffle(y_train)
print(y_train)
if __name__=='__main__':
    pass

好了,到这里手写数字识别的部分已经完结了,后面可以直接调用我们训练好的网络就可以识别了,下面是关于试卷检测的代码:

import time

import cv2 as cv
import numpy as np
from tensorflow.keras.models import load_model
import os

model =load_model('mode.h5')
def zb(img,a):
    # b=np.sort(a,axis=0)
    idx = np.argsort(a, axis=0)
    aa = a[idx[:, 0]]
    idx12=np.argsort(aa[:2],axis=0)
    idx34 = np.argsort(aa[2:], axis=0)
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值