Opencv之答题卡识别判卷 | 您所在的位置:网站首页 › 答题卡识别的原理 › Opencv之答题卡识别判卷 |
项目要求
提供一张答题卡图像,通过图像处理识别出答题卡上每个题的选项,与正确答案对比,得出分数并写在答题卡上。 代码实现过程 1、引入需要的库 import numpy as np import cv2 as cv 2、定义绘图函数 def cv_show(name,img): cv.imshow(name, img) cv.waitKey(0) cv.destroyAllWindows() 3、输入正确答案 # 正确答案 ANSWER_KEY = {0: 1, 1: 4, 2: 0, 3: 3, 4: 1} 4、传入答题卡图像 image = cv.imread('./images/test_01.png') cv_show('image', image)答题卡图像如下图所示: 得到滤波后的图像: 得到图像: 为了完成透视变换,需要检测出图像的外轮廓。 cnts = cv.findContours(edged.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)[1] contours_img = image.copy() cv.drawContours(contours_img, cnts, -1, [0, 0, 255], 3) cv_show('contours_img',contours_img) print(np.array(cnts).shape) (1, 89, 1, 2)由此可见,代码只检测出此图像的一个含有89个点的外轮廓。如果检测到不止一个外轮廓,则需要通过比较轮廓周长、面积的方式筛选出最外围的轮廓,可以用如下代码实现: cnts = sorted(cnts, key=cv.contourArea, reverse=True)将轮廓在原图中画出,得到: 由于轮廓检测返回的轮廓是由89个点构成的,而我们需要进行的透视变换只需要4个点(左上,右上,右下,左下)的位置即可完成,故需要找到此外轮廓的近似多边形的坐标。 peri = cv.arcLength(cnts[0], True) approx = cv.approxPolyDP(cnts[0], 0.02 * peri, True) 8、将得到的点坐标按照左上,右上,右下,左下排序为了使现在得到的点与投射完成后的点的位置一一对应,在这里要先将这些点按一定顺序排列。 pts = approx.reshape(4, 2) rect = np.zeros((4, 2), dtype=np.float32) s = np.sum(pts, 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)] 9、获取变换后对应坐标位置变换后,图像的长和宽应该变为: 长 = max(变换前左边长,变换前右边长) 宽 = max(变换前上边长,变换前下边长) 设变换后图像的左上角位置为原点位置。 # 获取坐标点 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=np.float32) 10、计算变换矩阵并做透视变换 H = cv.getPerspectiveTransform(rect, dst) warped = cv.warpPerspective(gray, H, (maxWidth, maxHeight)) cv_show('warped',warped)得到变换后的图像: 得到二值图像: 得到82个轮廓,存放在列表cnts中。 得到图像: 得到结果: |
CopyRight 2018-2019 实验室设备网 版权所有 |