Python答题卡识别并给出分数的实现代码

1. Python答题卡识别与分数计算

在教育考试系统中,答题卡是一种常见的评测方式。对于这种评测方式,使用计算机自动识别并给出分数是非常必要的。本文将介绍使用Python实现答题卡识别与分数计算的过程。

1.1 开发环境配置

在本文中,我们将使用Python的OpenCV库和Pytesseract库来实现答题卡的识别和分数计算。因此,我们需要先安装这两个库。

pip install opencv-python

pip install pytesseract

在安装完库之后,我们需要对使用的模型进行配置。本文使用的模型可以在这里下载。

1.2 识别答题卡

在进行答题卡的分数计算之前,我们需要识别答题卡的位置。以下是识别答题卡的代码:

import cv2

import numpy as np

def findOMR(img):

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

gray = cv2.GaussianBlur(gray, (5,5), 0)

edge = cv2.Canny(gray, 75, 200)

contours, hierarchy = cv2.findContours(edge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:

approx = cv2.approxPolyDP(cnt, 0.02*cv2.arcLength(cnt,True),True)

if len(approx) == 4:

x,y,w,h = cv2.boundingRect(cnt)

return x,y,w,h

return None

上面的代码会返回一个元组,其中包含了答题卡在原图中的位置坐标和宽度高度。

1.3 将答题卡分成小块

将答题卡分成小块可以帮助我们更好地对答题卡进行分析。以下是将答题卡分成小块的代码:

def splitOMR(img, x, y, w, h, nx=5, ny=10):

omr_img = img[y:y+h, x:x+w]

omr_w = w // nx

omr_h = h // ny

omrs = []

for i in range(ny):

for j in range(nx):

omr = omr_img[i*omr_h:(i+1)*omr_h, j*omr_w:(j+1)*omr_w]

omrs.append((omr, x+j*omr_w, y+i*omr_h, omr_w, omr_h))

return omrs

上面的代码会将答题卡分成 nx * ny 块。每个块包含了一个小方格,并返回一个列表。

1.4 答案识别

在将答题卡分成小块之后,我们要对每个小块进行答案的识别。

def recognizeAnswers(img, threshold=150):

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(gray,threshold,255,cv2.THRESH_BINARY_INV)

kernel = np.ones((2,2),np.uint8)

thresh = cv2.erode(thresh,kernel,iterations = 1)

kernel = np.ones((3,3),np.uint8)

thresh = cv2.dilate(thresh,kernel,iterations = 1)

text = pytesseract.image_to_string(thresh, config='--psm 6').strip().upper()

return text

上面的代码会返回一个字符串,其中包含了识别出的答案。

1.5 分数计算

在对答案进行识别后,我们需要根据正确答案计算出成绩。以下是计算分数的代码:

def calculateScore(correct_answers, answers):

if len(correct_answers) != len(answers):

return 0

score = 0

for i in range(len(correct_answers)):

if answers[i] == correct_answers[i]:

score += 1

return score

上面的代码会返回计算出的分数。

2. 实现过程与结果输出

通过上面的步骤,我们可以将整个答题卡识别和分数计算的过程实现。以下是整个过程的代码:

import cv2

import numpy as np

import pytesseract

def findOMR(img):

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

gray = cv2.GaussianBlur(gray, (5,5), 0)

edge = cv2.Canny(gray, 75, 200)

contours, hierarchy = cv2.findContours(edge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:

approx = cv2.approxPolyDP(cnt, 0.02*cv2.arcLength(cnt,True),True)

if len(approx) == 4:

x,y,w,h = cv2.boundingRect(cnt)

return x,y,w,h

return None

def splitOMR(img, x, y, w, h, nx=5, ny=10):

omr_img = img[y:y+h, x:x+w]

omr_w = w // nx

omr_h = h // ny

omrs = []

for i in range(ny):

for j in range(nx):

omr = omr_img[i*omr_h:(i+1)*omr_h, j*omr_w:(j+1)*omr_w]

omrs.append((omr, x+j*omr_w, y+i*omr_h, omr_w, omr_h))

return omrs

def recognizeAnswers(img, threshold=150):

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret,thresh = cv2.threshold(gray,threshold,255,cv2.THRESH_BINARY_INV)

kernel = np.ones((2,2),np.uint8)

thresh = cv2.erode(thresh,kernel,iterations = 1)

kernel = np.ones((3,3),np.uint8)

thresh = cv2.dilate(thresh,kernel,iterations = 1)

text = pytesseract.image_to_string(thresh, config='--psm 6').strip().upper()

return text

def calculateScore(correct_answers, answers):

if len(correct_answers) != len(answers):

return 0

score = 0

for i in range(len(correct_answers)):

if answers[i] == correct_answers[i]:

score += 1

return score

def recognizeOMR(img_path, correct_answers):

img = cv2.imread(img_path)

x,y,w,h = findOMR(img)

omrs = splitOMR(img, x, y, w, h)

answers = []

for omr, x, y, w, h in omrs:

answer = recognizeAnswers(omr)

answers.append(answer)

score = calculateScore(correct_answers, answers)

return score

score = recognizeOMR('test.jpg', 'ABCDABCDABCDABCD')

print('分数:', score)

上面的代码中,我们使用了一张包含了答题卡的图片 test.jpg 作为输入,同时还传入了正确答案。在运行上面的代码之后,将会输出计算出的分数。

3. 结语

通过使用Python和OpenCV库以及Pytesseract库,我们可以实现对答题卡的自动识别和分数计算。这种方法可以有效地减少人工干预,提高评测效率。当然,这种方法可能还需要根据具体情况进行改进和优化。

后端开发标签