网站怎么可以做视频播放做网站视频存储

当前位置: 首页 > news >正文

网站怎么可以做视频播放,做网站视频存储,互联网舆情监测,可以下载的网站模板目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境PyCharm安装OpenCV环境 模块实现1. 信息识别2. Excel导出模块3. 图形用户界面模块4. 手写识别模块 系统测试1. 系统识别准确率2. 系统识别应用 工程源代码下载其它资料下载 前言 本项目基于Python和OpenCV图像处… 目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境PyCharm安装OpenCV环境 模块实现1. 信息识别2. Excel导出模块3. 图形用户界面模块4. 手写识别模块 系统测试1. 系统识别准确率2. 系统识别应用 工程源代码下载其它资料下载 前言 本项目基于Python和OpenCV图像处理库在Windows平台下开发了一个答题卡识别系统。系统运用精巧的计算机视觉算法实现了批量识别答题卡并将信息导出至Excel表格的功能。这一解决方案使得答题卡的判卷过程变得轻便、高效且准确。 首先我们以Python语言作为开发基础结合OpenCV图像处理库为系统提供了强大的图像处理和分析能力。这使得我们能够在图像中准确地定位答题卡检测填涂区域以及识别填涂的内容。 在Windows平台下进行开发我们能够充分利用操作系统的功能确保系统在用户环境中的稳定性和兼容性。 系统中的计算机视觉算法经过精心设计可以可靠地识别答题卡上的填涂信息。从扫描的图像中我们能够确定哪些选项被填涂并将这些信息精准地提取出来。 一旦信息被提取系统能够将这些数据导出至Excel表格实现了高效的数据整理和统计功能。这使得判卷过程变得高度自动化减少了繁琐的手动工作同时也降低了错误的风险。 总结而言本项目的开发利用了Python语言和OpenCV图像处理库的强大功能实现了一个全面的答题卡识别系统。通过高效的图像处理和数据导出功能系统不仅减轻了判卷的负担还大幅度提高了识别的准确性和效率。这对于教育机构和考试机构来说都具有极大的实用价值。 总体设计 本部分包括系统整体结构图和系统流程图。 系统整体结构图 系统整体结构如图所示。 系统流程图 系统流程如图所示。 运行环境 本部分包括Python环境、OpenCV环境、图像处理工具包、requests、 base64和xlwt模块 。 Python 环境 需要Python 3.6及以上配置。在Windows环境下下载Anaconda完成Python所需配置下载地址为https://www.anaconda.com/。 PyCharm安装 在网站https://www.jetbrains.com/pycharm/中下载对应机器的安装包。采用免费社区版下载exe格式文件即可。 OpenCV环境 在PyCharm中安装OpenCV 3.4.15选择Settings下Project中的Interpreter单击右上角加号搜索需要添加的库选中Specifyversion和3.4.15单击OK按钮即可。 按如上方法安装imutils、requests和base64。 通过pip install xlwt安装xlwt模块实现数据写入Excel表格的功能。 模块实现 本项目包括4个模块信息识别、Excel导出、图形用户界面和手写识别下面分别介绍各模块的功能及相关代码。

  1. 信息识别 基于OpenCV算法实现对图片中选项信息、学生身份信息的检测。在开始编写系统前用Photoshop软件绘制用到的答题卡如图所示。 答题卡中共计50道单选题每选对1题得2分漏选提示“漏选”多选提示“多选”最后返回成绩和统计错误选项的字典。 学院、班级、学号等信息采用“涂出来”的方式相比初版系统中“写出来”的方式识别准确率更高代码更简单。 具体描述如下 1利用get_position函数通过上述信息识别算法拿到身份信息被涂轮廓的重心坐标数组Info和选项信息被涂轮廓重心坐标数组Answer。 图片预处理将图片做滤波去噪后进行透视变换并调整至2400X 2800的统一规格 如图1~图9所示。 相关代码如下: #导入相应数据包 import cv2 import matplotlib.pyplot as plt import imutils import numpy as np def cv_show(name, img): #展示图片cv2.namedWindow(name, 0)cv2.imshow(name, img)cv2.waitKey(0) cv2.destroyAllWindows() def order_points(pts): #对4点进行排序#共4个坐标点rect np.zeros((4, 2), dtype float32)#按顺序找到对应坐标0、1、2、3分别是左上、右上、右下、左下#计算左上和右下s pts.sum(axis 1)rect[0] pts[np.argmin(s)]rect[2] pts[np.argmax(s)]#计算右上和左下diff np.diff(pts, axis 1)rect[1] pts[np.argmin(diff)]rect[3] pts[np.argmax(diff)]return rect def toushi_transform(image, pts): #输入原始图像和4角点坐标#获取输入坐标点rect order_points(pts)(tl, tr, br, bl) rect#计算输入的w和h值widthA np.sqrt(((br[0] - bl[0]) ** 2) ((br[1] - bl[1]) ** 2))widthB np.sqrt(((tr[0] - tl[0]) ** 2) ((tr[1] - tl[1]) ** 2))maxWidth max(int(widthA), int(widthB))heightA np.sqrt(((tr[0] - br[0]) ** 2) ((tr[1] - br[1]) ** 2))heightB np.sqrt(((tl[0] - bl[0]) ** 2) ((tl[1] - bl[1]) ** 2))maxHeight max(int(heightA), int(heightB))#变换后对应坐标位置dst np.array([[0, 0],[maxWidth - 1, 0],[maxWidth - 1, maxHeight - 1],[0, maxHeight - 1]], dtype float32)#计算变换矩阵print(原始四点坐标:\n,rect,\n变换后四角点坐标\n,dst)M cv2.getPerspectiveTransform(rect, dst)print(变换矩阵,M)warped cv2.warpPerspective(image, M, (maxWidth, maxHeight))#返回变换后结果return warped def get_postion(image_name):#读入图片 image cv2.imread(image_name) #预处理 #转换为灰度图像 gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #高斯滤波 blurred cv2.GaussianBlur(gray, (3, 3), 0) #自适应二值化方法 blurredcv2.adaptiveThreshold(blurred,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,51,2) cv_show(blurred,blurred) edged cv2.Canny(blurred, 10, 100) #为透视变换做准备cnts cv2.findContours(edged, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts cnts[0] if imutils.is_cv2() else cnts[1]docCnt None#确保至少有一个轮廓被找到if len(cnts) 0:#将轮廓按大小降序排序cnts sorted(cnts, keycv2.contourArea, reverseTrue)#对排序后的轮廓循环处理for c in cnts:#获取近似的轮廓peri cv2.arcLength(c, True)approx cv2.approxPolyDP(c, 0.02 * peri, True)#如果近似轮廓有4个顶点认为找到了答题卡if len(approx) 4:docCnt approxbreaknewimageimage.copy()for i in docCnt:#circle函数为在图像上作图新建一个图像用来演示4角选取cv2.circle(newimage, (i[0][0],i[0][1]), 50, (255, 0, 0), -1)#透视变换paper toushi_transform(image, docCnt.reshape(4, 2))warped toushi_transform(gray, docCnt.reshape(4, 2))#cv_show(warped,warped)#对灰度图应用二值化算法 threshcv2.adaptiveThreshold(warped,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,53,2)#重塑可能用到的图像width12400height12800#转换成标准大小2400*2800thresh cv2.resize(thresh, (width1, height1), cv2.INTER_LANCZOS4)paper cv2.resize(paper, (width1, height1), cv2.INTER_LANCZOS4)warped cv2.resize(warped, (width1, height1), cv2.INTER_LANCZOS4) cv2.imwrite(warped.jpg, warped) 识别被涂选项轮廓的重心相关代码如下 #透视变换、resize成2400*2800的图片#均值滤波ChQImg cv2.blur(thresh, (23, 23))#二进制二值化ChQImg cv2.threshold(ChQImg, 100, 225, cv2.THRESH_BINARY)[1]#cv_show(ChQImg,ChQImg)#在二值图像中查找轮廓cnts cv2.findContours(ChQImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)cnts cnts[0] if imutils.is_cv2() else cnts[1]Answer[]Info[]for c in cnts:#计算轮廓的边界框利用边界框数据计算宽高比(x, y, w, h) cv2.boundingRect©if (x 1200 and y 1700): continue #排除右下角区域的误选#if (w 60 h 20)and y900 and y2000:if (95 w 60) and y 880 and y 2050:M cv2.moments©cX int(M[m10] / M[m00])cY int(M[m01] / M[m00])#绘制中心及其轮廓cv2.drawContours(paper, c, -1, (0, 0, 255), 5, lineType0)cv2.circle(paper, (cX, cY), 7, (255, 255, 255), -1)#保存题目坐标信息Answer.append((cX, cY))if ( 90 w 55) and y800 and x1750 :M cv2.moments©cX int(M[m10] / M[m00])cY int(M[m01] / M[m00])#绘制中心及其轮廓cv2.drawContours(paper, c, -1, (0, 255, 0), 5, lineType0)cv2.circle(paper, (cX, cY), 7, (255, 255, 255), -1)#保存题目坐标信息Info.append((cX, cY)) cv_show(paper,paper)cv2.imwrite(paper.jpg, paper)imm cv2.resize(paper, (180, 210), cv2.INTER_LANCZOS4)cv2.imwrite(imm.jpg, imm)print(Answer)print(len(Answer))print(Info) return Info,Answer图1 读取的图片 图2 灰度化处理后的图片 图3 利用高斯滤波去噪后的图片 图4 二值化处理后的图片 图5 Canny滤波后的图片 图6 透视变换、二值化后的图片 图7 透视变换后的灰度图 图8 调整尺寸后二值化处理结果图 图9 最终结果图 以测试图片为例返回选项轮廓重心坐标Answer [ (977, 1992)(165, 1992)(523, 1926)(8611925 )( 10971859 )(403,1853 )(978,1790),( 284, 1784 )(861,1717)(166,1716),(2239, 1643),( 1544, 1638),(978, 1631)(406, 1629)(2237, 1572)(1542, 1569)(286, 1557 ),( 8591561 )( 22381503 )(14221497)(167,1486 )(739,1490)( 1306, 1428 ),(2118, 1432)(1095, 1424)(523,1417)( 16571362) (19971360) (9761359) (4051347)(19991273)(14241264)( 7381264)(1651256) (1303 1200) (1877 1199) (10941199)( 521 1189) ( 22421130)(976 1129)(1660 1128) (4021118)(1542 1062)(21231060) (853 1058)( 2821049)( 2000990),(1423991) (161 976)(734 982) ] 共计50个与所涂的50个选项相匹配。 返回个人信息轮廓重心坐标Info: [ (1531 528) (1218238)(336 239)(889 235)(437 167)(992 165) (1428 162) (1634 96) ]共计8个点包括2个确定学院、2个确定班级、3个确定学号、1个学号确认点。 2使用explain ()函数对个人信息轮廓重心坐标进行解释。返回对应的学院、班级和学号。在预处理时通过透视变换从拍摄图片中取出答题卡将图片调整至2400 X 2800的规格如图10和图11所示。 图10 系统读入图片 图11 预处理后的图片 各信息所在位置基本不变用Photoshop查看像素位置坐标反复调整边界参数如下图所示。 图12 个人信息区域像素分割 判断上述信息数组中轮廓重心的图像像素坐标。根据重心x坐标所在区间判断信息类型(学号、班级或学院)根据重心y坐标所在区间判断数字大小 def judge(x,y):xt0[285,385,485, 850,940,1040, 1385,1480,1580,1680]yt0[60,120,195,265,340,410,480,555,625,700,756] flagy-1flagx-1for j in range(10):if yt0[j]y and yyt0[j1]:flagyjfor i in range(7):if i1:if xt0[i]x and xxt0[i1]:flagxielif i3:if xt0[i1]x and xxt0[i2]:flagxielse:if xt0[i2]x and xxt0[i3]:flagxi return flagx,flagy def explain(Info):id{}for item in Info:if item[0]!-1 or item[1]!-1:pos,numjudge(item[0],item[1])id[pos]numsch_numid[0]*10id[1]cls_numid[2]*10id[3]stu_numid[4]*100id[5]*10id[6]print(学号,sch_num,班级:,cls_num,学号:,stu_num) return sch_num,cls_num,stu_num以测试图片为例返回结果——学院: 21、班级: 21、学号: 160。 3使用calculate ()函数对选项轮廓重心坐标进行解释。返回包含对应的题号和选项的字典如果遇到多涂、漏涂情况则返回“多涂”“漏涂”的提示。同样使用Photoshop查看像素位置坐标反复调整边界参数如下图所示。 图13 答题卡像素区域分割 编写judgey0()函数判断题号和judgex0函数判断选项。根据选项每四个为一堆的特点做除法和取余数使用judge0()函数将题号与所涂选项匹配。 相关代码如下: def judgey0(y):if (y / 5 1):return y 1elif y / 5 2 and y/51:return y % 5 20 1else:return y % 5 40 1 def judgex0(x):if(x%51):return Aelif(x%52):return Belif(x%53):return Celif(x%54):return D def judge0(x,y): #返回题号和答案if x/51 :#print(judgey0(y))return judgey0(y),judgex0(x)elif x/52 and x/51:#print(judgey0(y)5)return judgey0(y)5,judgex0(x)elif x/53 and x/52:#print(judgey0(y)10)return judgey0(y)10,judgex0(x)else:#print(judgey0(y)15)return judgey0(y)15,judgex0(x) def calculate(Answer):xt1 [0, 90, 220, 350, 455, 575, 680, 800, 920, 1040, 1160, 1260, 1370, 1490, 1600, 1720, 1830, 1940, 2060, 2180, 2330]#横向划分点yt1 [960, 1027, 1100, 1165, 1235, 1300, 1385, 1465, 1536, 1600, 1655, 1755, 1820, 1885, 1960, 2040]#纵向划分点ans_dict {}for i in Answer:for j in range(0, len(xt1) - 1):if i[0] xt1[j] and i[0] xt1[j 1]:for k in range(0, len(yt1) - 1):if i[1] yt1[k] and i[1] yt1[k 1]:a, b judge0(j, k)if (a in ans_dict.keys()):ans_dict[a]多选 #之前有被选过判多选else:ans_dict[a] bbreakprint(ans:,ans_dict) return ans_dict根据重心坐标所在区间得到对应的题号和选项。以测试图片为例返回携带选项信息字典ans:{50: ‘C’ ,45: ‘A’,44: ‘D’,49: ‘B’ ,48: ‘D’,43: ‘C’ ,47: ‘C’, 42:‘B’,46: ‘B’, 41 : ‘A’, 40: ‘D’, 35: ‘C’ ,30:‘C’,25:‘C’,39: ‘D’,34: ‘C’,24:‘B’,29 :‘B’,38:‘D’,33: ‘B’ ,23: ‘A’,28: ‘A’,32: ‘A’,37: ‘C’ ,27:‘D’,22:‘D’,31 : ‘D’, 36: ‘B’,26: ‘C’,21: ‘C’,20: ‘B’, 15:‘B’,10: ‘A’,5:‘A’, 14: ‘A’, 19: ‘A’, 9 :‘D’,4:‘D’ ,18 :‘D’,8:‘C’,13 :‘D’,3:‘C’ ,12:‘C’,17:‘C’, 7:‘B’,2:‘B’,16 : ‘B’,11 : ‘B’,1:‘A’,6: ‘A’}。 其中ans[题号]所涂答案。 4使用sumall()函数对上述功能进行汇总并对比正确答案和学生涂写答案返回学院、班级、学号、分数、错题完成信息识别功能。 def sumall(image_name,true_anstrue_ans):Info,Answerget_postion(image_name) #拿到信息轮廓数组sch_num, cls_num, stu_numexplain(Info) #解释个人信息 anscalculate(Answer) #判断所涂选项score0false_ans{}for i in range(1,len(true_ans)1):if (i in ans.keys()):if(ans[i]true_ans[i]):score2else:false_ans[i]ans[i]else:false_ans[i]漏选print(false_ans) return sch_num,cls_num,stu_num,score,false_ans2. Excel导出模块 本系统用data字典记录每次识别的信息其中data字典初始化如下: data{序号: [学 院班级学号成绩错题]}使用xlwt将data字典中信息导出到当前路径下名为data.xls的Excel表格中。 相关代码如下: import xlrd,xlwt,os def set_stlye(name,height,boldFalse):#初始化样式style xlwt.XFStyle()#创建字体font xlwt.Font()font.bold boldfont.colour_index 4font.height heightfont.name namestyle.font font return style def write_excel(data):if os.path.exists(data.xls):os.remove(data.xls)book xlwt.Workbook(encodingutf-8) #创建Workbook相当于创建Excel#创建sheetSheet1为表的名字cell_overwrite_ok为覆盖单元格sheet1 book.add_sheet(uSheet1, cell_overwrite_okTrue)r 0for i, j in data.items(): #i表示data中的keyj表示data中的valuele len(j) #values返回的列表长度if r 0:sheet1.write(r, 0, i,set_stlye(Time New Roman,220,True))
    #添加第 0 行 0 列数据单元格背景设为黄色else:sheet1.write(r, 0, i,set_stlye(Time New Roman,220,True) )
    #添加第1列的数据for c in range(1, le 1): #values列表中索引if r 0:sheet1.write(r, c, j[c - 1],set_stlye(Time New Roman,220,True))
    #添加第 0 行2 列到第 5 列的数据单元格背景设为黄色else:sheet1.write(r, c, j[c - 1],set_stlye(Time New Roman,220,True))r 1 #行数#sheet_merge()合并单元格book.save(data.xls) print(已导出至data.xls)如果data.xls存在导出时将其覆盖。以测试为例结果如图所示。 3. 图形用户界面模块 利用Python标准GUI库Tkinter实现本模块功能如图14和图15所示。 图14 系统主界面 图15 初始化试卷主界面 读取图片时用户可以输入图片地址单击【选择文件】按钮批量处理本地图片文件。选择图片所在的文件夹系统将识别每个满足条件的图片。 在设置中用户可以自定义确定答案。单击【识别】按钮系统可识别所选中的图片文件并将识别后的学院、班级、学号、成绩、错题等信息显示在右边。单击【导出】按钮将本次系统识别的所有数据导出到data.xls表格中。 相关代码如下 import tkinter as tk from iidd import sumall from ooctest import getinfo from PIL import Image,ImageTk import cv2 from excel import write_excel data {序号: [学院, 班级, 学号, 成绩,错题] } cnt0 import os def walk(path):files[]if not os.path.exists(path):return -1for root, dirs, names in os.walk(path):for filename in names:fileos.path.join(root, filename)print(file) #路径和文件名连接构成完整路径files.append(file)return files #if namemain: #pathC:/Users/wanli/answer sheet/images #walk(path) def discern():global imgsprint(entry_img_name.get())global cntcnt1da[] sch_num,cls_num,stu_num,score,false_anssumall(entry_img_name.get(),true_anstrue_ans) da.append(sch_num);da.append(cls_num);da.append(stu_num);da.append(score);da.append(str(false_ans));data[cnt]daimm Image.open(imm.jpg) #将照片展示imgs ImageTk.PhotoImage(imm)print(score)l_info1.config(text学院 str(sch_num)班级: str(cls_num))l_info2.config(text学号: str(stu_num))l_info3.config(text错题str(false_ans))l_score.config(text成绩str(score))imLabel.config(imageimgs) def set_ans():def confirm():global ans_str,true_ansans_str new_ans.get()window_set_ans.destroy()true_anseval(ans_str)window_set_anstk.Toplevel(window)window_set_ans.geometry(350x200)window_set_ans.title(初始化试卷)new_ans tk.StringVar()new_ans.set(str(true_ans))tk.Label(window_set_ans, text输入正确答案).place(x10, y10)entry_new_ans tk.Entry(window_set_ans, textvariablenew_ans, justifyleft)entry_new_ans.place(x100, y10,width230,height150)btn_confirm tk.Button(window_set_ans, text确定, commandconfirm)btn_confirm.place(x150, y130)hbartk.Scrollbar(window_set_ans,orienthorizontal, commandentry_new_ans.xview)entry_new_ans.configure(xscrollcommandhbar.set)hbar.pack(sidebottom,fillx)entry_new_ans.columnconfigure(0, weight1) true_ans{1:A, 2:B, 3:C, 4:D, 5:A,6:A, 7:A, 8:C, 9:D, 10:A,11:B, 12:C, 13:D, 14:A, 15:B,16:B, 17:C,18:D, 19:A, 20:B,21:C, 22:D, 23:A, 24:B, 25:C,26:C, 27:D, 28:A, 29:B, 30:C,31:D, 32:A, 33:B, 34:C, 35:D,36:D, 37:A, 38:B, 39:C, 40:D,41:A, 42:B, 43:C, 44:D, 45:A,46:A, 47:B, 48:C, 49 :C, 50:C } def write():print(data)write_excel(data)tell.config(text已导入到data.xls) window tk.Tk() window.title(答题卡识别系统) window.geometry(550x400) menubartk.Menu(window) filemenu tk.Menu(menubar,tearoff0) menubar.add_cascade(label设置,menufilemenu) filemenu.add_cascade(label初始化试卷,commandset_ans) l_scoretk.Label(window,text成绩) l_score.place(x250,y350) l_info1tk.Label(window,text学院班级:) l_info1.place(x250,y250) l_info2tk.Label(window,text姓名学号) l_info2.place(x250,y300) l_info3tk.Label(window,text错题) l_info3.place(x330,y350) var_img_nametk.StringVar() var_img_name.set(new2.jpg) #var_nametk.StringVar() #var_idtk.StringVar() #var_classtk.StringVar() #var_schooltk.StringVar() l_entk.Label(window,text输出图片地址) l_en.place(x25,y225) entry_img_nametk.Entry(window,textvariablevar_img_name) entry_img_name.place(x30,y250) btn_testtk.Button(window,text识别,commanddiscern) btn_test.place(x40,y300) btn_exceltk.Button(window,text导出,commandwrite) btn_excel.place(x40,y350) #显示图片 #im Image.open(mario_star.jpg) #mario ImageTk.PhotoImage(im) imLabel tk.Label(window,text结果) imLabel.place(x270,y20) def choose_fiel():selectFileName tk.filedialog.askopenfilename(title选择文件) #选择文件var_img_name.set(selectFileName) def getall():selectFileName0 tk.filedialog.askdirectory() #选择文件#var_img_name.set(selectFileName0)fileswalk(selectFileName0)for filename in files:global cntcnt 1da []sch_num, cls_num, stu_num, score, false_ans sumall(filename, true_anstrue_ans)da.append(sch_num);da.append(cls_num);da.append(stu_num);da.append(score);da.append(str(false_ans));data[cnt] datell.config(text批量处理完毕) submit_button1 tk.Button(window, text 选择文件, command choose_fiel) submit_button1.place(x30,y180) submit_button1 tk.Button(window, text 批量处理, command getall) submit_button1.place(x100,y180) telltk.Label(window,text欢迎进入机读卡识别系统) tell.place(x30,y70) window.config(menumenubar) window.mainloop() print(data)4. 手写识别模块 初版系统答题卡如图所示。 与最终版系统相似对传入图片进行预处理、区域划分等操作。但这里让学生以“写出来”的方式填写个人信息针对个人信息部分调用百度API对学院、姓名进行手写文字识别对班级、学号进行数字识别如图所示。 在百度AI开放平台注册并创建调用手写文字识别和数字识别的应用如图所示。 使用API Key和Secret Key获得access_token, 对从答题卡中获取的学院、姓名做手写文字识别对班级、学号做数字识别将信息汇总到dict字典。 相关代码如下: #encoding:utf-8 import requests import base64 host https://aip.baidubce.com/oauth/2.0/token?grant_typeclient_credentialsclient_id client_secret response requests.get(host) if response:print(response.json()) request_url https://aip.baidubce.com/rest/2.0/ocr/v1/handwriting #二进制方式打开图片文件 school open(school.jpg, rb) school_img base64.b64encode(school.read()) name open(name.jpg, rb) name_img base64.b64encode(name.read()) params_s {image:school_img} params_n {image:name_img} #access_token “按上面方法获得” #print(access_token) request_url request_url ?access_token access_token headers {content-type: application/x-www-form-urlencoded} responseS requests.post(request_url, dataparams_s, headersheaders) dict{} if responseS:print(responseS.json())print (responseS.json()[words_result][0][words])dict[school]responseS.json()[words_result][0][words] responseN requests.post(request_url, dataparams_n, headersheaders) if responseN:print (responseN.json()[words_result][0][words])dict[name]responseN.json()[words_result][0][words] #数字识别 cls open(cls.jpg, rb) cls_img base64.b64encode(cls.read()) id open(id.jpg, rb) id_img base64.b64encode(id.read()) params_c {image:cls_img} params_i {image:id_img} ruhttps://aip.baidubce.com/rest/2.0/ocr/v1/numbers ru ru ?access_token access_token responseC requests.post(ru, dataparams_c, headersheaders) responseI requests.post(ru, dataparams_i, headersheaders) if responseS:print (responseC.json()[words_result][0][words])dict[class]responseC.json()[words_result][0][words] if responseN:print (responseI.json()[words_result][0][words]) dict[id]responseI.json()[words_result][0][words]初版系统运行结果如图所示。 由于这种方法准确率低、需联网、速度慢、有使用次数限制等原因已不在目前系统中使用。曾考虑搭建神经网络但准确率仍然达不到要求且代码烦琐违背构建轻量系统的初衷所以选择让学生把信息涂出来的方式按上述OpenCV算法进行识别准确率几乎达到100%。 系统测试 本部分包括系统识别准确率和系统识别应用。
  2. 系统识别准确率 通过绘制数张答题卡进行测试识别准确率达到100%。识别答题卡的原则是如果照片不规范则系统不识别如果系统可识别则需保证识别结果完全正确。每张答题卡测试效果如图16~图22所示。 图16 测试示例1 图17 测试示例2 图18 测试示例3 图19 测试示例4 图20 无效输入 图21 漏涂、多涂 图22 漏涂 前4张测试图正常随机填涂均准确无误。 针对不符合要求的图片系统提示不合法。 针对多涂、漏涂情况本系统能准确识别并在错题字典中反馈信息。 虽然不能通过大量数据验证系统的稳定性但至少说明程序是准确的对于符合要求的图片能够正确识别照片答题卡中学生信息和选项信息。
  3. 系统识别应用 配置环境后运行answer sheet中的turntogui.py文件即可成功进入本系统如图所示。 顶端为【设置】菜单单击将弹出【初始化试卷】窗口拖动滚动条修改标准答案的字典。单击【确定】按钮完成修改返回主界面如图所示。 菜单栏下方为提示信息。 单击【选择文件】可以选择本地文件识别;单击【批量处理】按钮可以选择指定文件夹识别文件夹内符合要求的图片。 手动输入图片地址单击【识别】 按钮识别图片单击【导出】按钮将信息导出为data.xls文件。 在启动识别后窗口右侧将展示识别得到的信息如图片、学院、学号、成绩和错题集等。 系统测试效果如图所示。 工程源代码下载 详见本人博客资源下载页 其它资料下载 如果大家想继续了解人工智能相关学习路线和知识体系欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线所有资料免关注免套路直接网盘下载》 这篇博客参考了Github知名开源平台AI技术平台以及相关领域专家DatawhaleApacheCNAI有道和黄海广博士等约有近100G相关资料希望能帮助到所有小伙伴们。