首页 > 编程语言 >python cv2 答题卡检测

python cv2 答题卡检测

时间:2022-09-21 22:57:26浏览次数:75  
标签:python discren image cv2 答题卡 Label int Answer

import tkinter
import cv2 #
from PIL import Image,ImageTk
from tkinter import filedialog #打开文件需要
import imutils
import os
import numpy
root = tkinter.Tk()
root.geometry('1000x700')
root.title('答题卡识别系统')
Label_a = tkinter.Label(root)
Label_a.place(x=0,y=0)
Label_b = tkinter.Label(root)
Label_b.place(x=510,y=20)
Label_c = tkinter.Label(root)
Label_c.place(x=510, y=270)
Label_d = tkinter.Label(root)
Label_d.place(x=650,y=500)
def enter():
filename = tkinter.filedialog.askopenfilename() # 打开文件夹
#保存图片,方便识别
photo = Image.open(filename)
photo.save('img.jpg')
#展示图片
photo = Image.open(filename).resize((500, 500)) # 打开图片
photo = ImageTk.PhotoImage(photo)
Label_a.config(image=photo)
Label_a.image=photo
#将框选内容清除,以便于下张图显示清除,否则会造成显示错误
Range.clear()
Range = []
catch_Answer = []
def rectangle():
img = cv2.imread('img.jpg')
y,x,_ = img.shape
print('原图像大小:',x,y)
if x<=500:
img = cv2.resize(img,(int(x*2),int(y*2))) #将图片宽高各除与2
elif 1000<= x:
img = cv2.resize(img,(int(x/2),int(y/2))) #将图片宽高各除与2
x, y, w, h = cv2.selectROI(img, showCrosshair=True, fromCenter=False)
screenshot = img[y:y + h, x:x + w]
print('截图区域大小,判断条件:',x,y,w,h)
#展示图
screenshot = Image.fromarray(screenshot)
screenshot = ImageTk.PhotoImage(image=screenshot)
Label_b.config(image=screenshot)
Label_b.image = screenshot
# 截屏区域
if x<=30:
x1, x2, y1, y2 = x * 2.5, (x + w) * 2.5, y * 2.5, (y + h) * 2.5
elif 30 < x <35:
x1, x2, y1, y2 = x * 5, (x + w) * 5, y * 5, (y + h) * 5
elif 35 <= x:
x1, x2, y1, y2 = x * 10, (x + w) * 10, y * 10, (y + h) * 10
Range.append((x1, x2, y1, y2)) #360 5080 3640 5940
#调用识别模块
discren('img.jpg',0)
Answer = []
def discren(path,name):
#cv2读取
# image = cv2.imread(path)
# ay0,ax0,_ = image.shape
#PIL——Image 读取
image = Image.open(path)
ax0,ay0 = image.size
#转换成cv2可以识别的图
image = numpy.asarray(image)
# 将图像扩大五倍
ax,ay = ax0*5,ay0*5
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 高斯滤波
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
# 自适应二值化方法
blurred = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 51, 2)
# 重塑可能用到的图像
thresh = cv2.resize(blurred, (ax, ay), cv2.INTER_LANCZOS4)
fImage = cv2.resize(image, (ax, ay), cv2.INTER_LANCZOS4)
# 均值滤波
ChQImg = cv2.blur(thresh, (40, 40))
# 二进制二值化
ChQImg = cv2.threshold(ChQImg, 30, 225, cv2.THRESH_BINARY)[1]
# 在二值图像中查找轮廓
cnts = cv2.findContours(ChQImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 用边缘检测绘制
cnts = cnts[1] if imutils.is_cv3() else cnts[0]
x1,x2,y1,y2 = int(Range[0][0]),int(Range[0][1]),int(Range[0][2]),int(Range[0][3])
for c in cnts:
# 计算轮廓的边界框,然后利用边界框数据计算宽高比
(x, y, w, h) = cv2.boundingRect(c)
if (w > 75 and h > 13) and x > x1 and x < x2 and y > y1 and y < y2 : # 原始数据: x>324 and x<4700 and y>3072 and y<5016
M = cv2.moments(c) # 矩形的宽高, 起点终点(划分区域)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# 绘制中心及其轮廓
cv2.drawContours(fImage, c, -1, (0, 0, 255), 8, lineType=0)
cv2.circle(fImage, (cX, cY), 40, (255, 255, 255), -1)
if name == 0 :
# #保存题目坐标信息
Answer.append((cX, cY))
elif name == 1:
#考试答案
catch_Answer.append((cX,cY))
#框选区域
discren = fImage[y1:y2,x1:x2]
y,x,_ = discren.shape
print(y)
print('判断显示,x:',x)
if x <= 1000:
discren = cv2.resize(discren, (int(x/2), int(y/1.5)))
elif 1000 < x < 3500:
discren = cv2.resize(discren, (int(x/5), int(y/5)))
elif 3500 <= x:
discren = cv2.resize(discren,(int(x/10),int(y/10)))

#调用判断
if Answer and catch_Answer:
a = contrast(Answer, catch_Answer)
cv2.circle(discren, a, 4, (255, 255, 255), -1)
catch_Answer.clear()
#展示图
discren = Image.fromarray(discren)
discren = ImageTk.PhotoImage(image=discren)
Label_c.config(image=discren)
Label_c.image = discren
def testing():
# filename = tkinter.filedialog.askopenfilename() # 打开文件夹
# filename = filename.split('/')[::]
# print(filename)
path = 'D:/PyCharm Community Edition 2021.1.3/项目/答题卡项目/img'
paths = os.listdir(path)
for path in paths:
print('./img/'+path)
discren('./img/'+path,1)
def contrast(Answer,catch_Answer):
a = 0
for i in range(len(Answer)):
if catch_Answer[i][0] - 5 <= Answer[i][0] <= catch_Answer[i][0] + 5 and catch_Answer[i][1] - 3 <= Answer[i][1] <= catch_Answer[i][1] + 3:
a += 1
else:
if catch_Answer[i] in Answer:
a += 1
else:
print(Answer[i], catch_Answer[i])
return catch_Answer[i]
# print('一共{}道题,XX答对{},得分{}'.format(int(len(Answer)), a, a))
Label_d['text'] = '一共{}道题,XX答对{},得分{}'.format(int(len(Answer)), a, a)
tkinter.Label(root,text='框选区域').place(x=730,y=0)
tkinter.Label(root,text='识别结果').place(x=730,y=250)
tkinter.Button(root,text='答题卡模板',command=lambda:enter()).place(x=50,y=500)
tkinter.Button(root,text='框选区域',command=lambda:rectangle()).place(x=200,y=500)
tkinter.Button(root,text='识别的答题卡',command=lambda:testing()).place(x=350,y=500)
root.mainloop()

标签:python,discren,image,cv2,答题卡,Label,int,Answer
From: https://www.cnblogs.com/lld76/p/16717485.html

相关文章

  • day1 python学习前言
    ......
  • python第一天
    PYTHON第一天一、typoratypora主要功能介绍 --格式转换(在文件-导出中) --字体大小(在文件-设置偏好-外观-字体大小-自定义) --主题样式(在上方主题工具栏主题中) 1.去......
  • Python3 + selenium 获取疫情中高风险区数据
    背景:需要动态将疫情风险区数据和区域业务动作想结合,赋能销售业务,内部使用非商用哈环境:Python3+selenium自动化测试软件中Chrome驱动exe文件输出:以e......
  • python语法糖记录
    reduce对可迭代对象进行累积操作https://www.runoob.com/python/python-func-reduce.html注意:Python3.xreduce()已经被移到functools模块里,如果我们要使用,需要引入......
  • selenium(Python)的缺陷总结
    Message:Browsingcontexthasbeendiscarded这是一个稀里糊涂的错误,有时候会无缘无故冒出来。据网上的消息说,是原先的内容已经不在了导致的...没有找到解决办法,这种错......
  • 初学python的建议。
    今日内容总结一.记录好每一天的笔记对于我们初学者来说,就好每一天的上课内容来说是至关重要的,我个人比较推荐typora这款文本编辑器。对于这款编译器的安装路径,尽量不要......
  • Python——索引与切片
    #索引与切片##1.序列序列:list,tuple,str其中list是可变序列typle,str是不可变序列#修改序列的值list=[3,4,5]tup=(3,4,5)str='345'list[1]=99listoutp......
  • python1
    python课程总结(1)1.今日内容概要typora软件--下载与安卓--文件路径--主要功能markdown语法网络博文编写教程计算机的本质计算机的五大组成部分计算机......
  • python-Typora的安装及应用
      Typora软件是一个文本编辑器,可以记录文字类似于word,可以用来日常记笔记,学习代码,界面简洁,清晰,方便日常工作。安装        安装时尽量装在其他盘不要......
  • python django request接收UIRL传参
    POST方式:ifrequest.method=='POST':body_str=request.body.decode('utf-8')post_data=parse_qs(body_str)post_dict={}......