需求描述
多张判过分的试卷,通过demo来识别出每道题目扣分多少,将结果汇总到excel文件中。
个人想法
将图片按照题目划分矩形区域,识别出哪道题扣分,将结果统计出来。
步骤概述
图片处理
图片按照边框裁剪校正
保证初始输入的图片处理之后有基本相同的像素大小,按照试卷的边框进行裁剪,然后图片进行校正。
可参考链接
图片增强
对校正好的图片进行处理,对比度增强、亮度增强、色度增强、锐度增强等。
# -*- coding: UTF-8 -*- |
todo
图片增强的效果不是太好,考虑参考其它图片处理方法。 高斯模糊(todo)
图片分割
分割是比较简单,此图的难点在于如何确定哥哥题目区域,即各个题目的坐标。
此处我先均分,然后手动计算坐标给一张图片划分了矩形。(此处的基准模板图片可以考虑借助用户的帮助来生成,包括划分后区域题号的对应)
图片识别
识别切割出的题目区域中有没有扣分
选择题可以考虑只要是识别出了红色即算此题错误(todo)
客观题需要识别出所扣分数,初步打算是将扣分区域再分割出来,然后用手写体识别模型来识别扣分(准确率会高一些)。
目的是为了将扣分显示出来,所以题目信息不重要,图像处理,使得题目信息变模糊,红色加深。
提取目标图像参考下 投影法字符分割,或者是识别特定颜色并提取图像相关文章。
提取目标图像(扣分区域)
python 用opencv完成图像分割,并且完成每一个目标物的提取
使用Python和OpenCV检测图像中的物体并将物体裁剪下来
基于tensorflow、opencv的入门案例_发票识别三:发票数据集制作和cnn网络训练
百度OCR开源API
腾讯OCR ??
结果统计
题号和切割出的图片的对应关系,导出到excel不是难点。
重难点
- 图像的处理和高质量图片(测试图片)的获取
- 题目区域的划分(若扣分跨两个题目区域??)
- 题目和切割后图片对应关系
- 分割后的图片中是否包含扣分识别(选择题)
- 图片中扣分切割出并识别
- 识别的准确率问题
关键词参考
透视变换 图像二值化 图片膨胀腐蚀 高斯模糊 HSV openCV 图像切割投影法字符分割 特定区域ROI提取
可能用到的参考链接
可能会用到的demo
识别图片中的红色
import cv2
import numpy as np
src = cv2.imread("fix.jpg")
cv2.namedWindow("input", cv2.WINDOW_AUTOSIZE)
cv2.imshow("input", src)
"""
提取图中的红色部分
"""
hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
low_hsv = np.array([0, 36, 10])
high_hsv = np.array([10, 255, 255])
mask = cv2.inRange(hsv, lowerb=low_hsv, upperb=high_hsv)
cv2.imshow("pic", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()手动给试卷题目划分区域
# encoding:utf-8
import cv2
image = cv2.imread("origin.jpg")
GrayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print(GrayImage.shape)
h, w = image.shape[:2]
h, w = map(int, [h, w])
print("高-宽", h, w)
# # no flip
draw_0 = cv2.rectangle(image, (10, 10), (500, 770), (0, 0, 255))
cv2.rectangle(image, (510, 10), (1000, 770), (0, 0, 255))
a = 0
while a < h:
a += 50
# cv2.rectangle(image, (10, int(a)), (500, 770), (255, 0, 0), 1)
# cv2.rectangle(image, (510, int(a)), (1000, 770), (255, 0, 0), 1)
cv2.rectangle(image, (10, 270), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 313), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 365), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 415), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 470), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 505), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 615), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 670), (500, 770), (0, 0, 255))
cv2.rectangle(image, (10, 725), (500, 770), (0, 0, 255))
cv2.rectangle(image, (510, 10), (1000, 70), (0, 0, 255))
cv2.rectangle(image, (510, 10), (1000, 370), (0, 0, 255))
x, y, w, h = cv2.boundingRect(GrayImage)
print(x, y, w, h)
draw_1 = cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 参数:pt1,对角坐标1, pt2:对角坐标2
# 注意这里根据两个点pt1,pt2,确定了对角线的位置,进而确定了矩形的位置
# draw_0 = cv2.rectangle(image, (2 * w, 2 * h), (3 * w, 3 * h),(255, 255, 0), 2)
# 将画过矩形框的图片保存到当前文件夹
cv2.imwrite("changed.jpg", draw_0)
# 显示画过矩形框的图片
cv2.imshow("draw", draw_1)
cv2.waitKey(0)
cv2.destroyWindow("draw")
已知区域坐标,切割图片
import cv2
"""
特定区域图片裁切
方法1:利用OpenCV对其进行裁剪
方法2:使用Pillow对图片进行裁剪
https://blog.csdn.net/hfutdog/article/details/82351549
动态获取裁切点坐标
(10, 270), (500, 770)
(10, 313), (500, 770)
(10, 365), (500, 770)
(10, 415), (500, 770)
(10, 470), (500, 770)
(10, 505), (500, 770)
"""
x0 = 10
x1 = 500
n = 770
# 裁切点坐标 动态的坐标 图片以题号等命名
y = [270, 313, 365, 415, 470, 505]
img = cv2.imread("origin.jpg")
print(img.shape)
# 裁剪坐标为[y0:y1, x0:x1]
for i in range(len(y)-1):
cropped = img[y[i]:y[i + 1], x0:x1]
cv2.imwrite("pic/" + str(i) + ".jpg", cropped)原始图片(测试用)
origin.jpg