/myselfOCR

使用opencv从试卷中提取出数据

Primary LanguagePython

myselfOCR

使用的OpenCV中的从试卷中提取出数据

(图片丢失了可以在我的公众号看具体的“https://mp.weixin.qq.com/s/9ei-3tNCoxGfskL-MAsN_Q

前言:

大二的时候几个人一起搞的一个东西,上周运气好被一个同学投到了成都的一个比赛还进了决赛,然后思考了一下既然要比赛还是把这个系统的各个方面完善一下好了。我做的是图片预处理部分,把一张图片中的数字算式部分提取出来。

之前的图片预处理分割字符是通过照片的像素点来分割的,
现在看来是十分的愚蠢。。。主要是那个时候自己也菜,
所以现在想了办法预处理部分重新做一下。

需求分析

  • 图片预处理部分要实现的功能很简单,就是把一整张图片中的数字和运算符号切割成单独的一个一个小图像就好了。 大概步骤就是这样:
graph LR
整张图片-->图片旋转闭操作等处理
图片旋转闭操作等处理-->切割单个等式
切割单个等式-->获取每一个数字与运算符
  • 理想效果: 原图⬇ 0--test0

    结果⬇ 1

  • 其中图片的拍摄过程中需要解决的问题及解决方法:

    1. 图片倾斜 --> 霍夫变换
    2. 不平整 --> 闭操作透视变换
    3. 噪点与阴影 --> 二值化处理
    4. 提取内容 --> 算式框的边界检测

模块具体实施步骤和结果

  • 步骤零:获取图片 image

  • 步骤一:霍夫变换

    这个地方因为拍摄的照片就比较正,所以霍夫变换的效果不是十分明显,仔细看是能看到这个图边缘黑边的地方就是进行旋转后的痕迹。结果如下: image

  • 步骤二:获取边界图片

    opencv的边界检测方法 image

  • 步骤三:灰度化闭操作及透视变换

    闭操作: '' 图片形态学操作中的一种,闭操作可使轮廓线更光滑,但与开操作相反的是,闭操作通常消弥狭窄的间断和长细的鸿沟,消除小的空洞,并填补轮廓线中的断裂。''

    简单点说:图片细节增强

    透视变换:将原图投影到另一个平面上并通过点运算使图像更加平整。

    二值化处理方法:根据Otsu's方法取最佳阈值对图片进行二值化处理

    结果如下:这里透明变换的效果并不是很好,目前还没有找到一个合适的参数使用,并且从分割的情况来看效果也还行,所以暂时就这样勉强用了。。。 image

  • 步骤四:分割单元格

    opencv对图片轮廓进行识别: image

    使用opencv把边界画出来,效果简明易懂:

    image

    单个单元格的提取: image

  • 步骤五:从单个单元格中提取数字及符号

    因为用了垂直投影方法切割字符,在使用之前去噪点的步骤没有检测效果如何,导致这里用垂直投影会出现将噪点也切割出来的情况。返回重新调整一下二值化的阈值就可以了。

    效果: 1

其他:

  1. 使用png格式图片的原因 png它是无损压缩格式,jpg是有损
  2. 写一个完整的系统代码一定要分方法分模块,否则到后面代码量增加起来之后对后续的维护很麻烦。
  3. 对opencv模块的强大有了更加的了解。。。
  4. 这里实名感谢"@ATP合成酶"大佬提供的相关处理思路,万分感谢
  5. 项目为了赶时间基本只写了两周还有很多不完整的细节处理地方,如果继续做下去的话也还是蛮有意思的
  6. 第一次感受到当程序员没日没夜的加班生活,想到以后还有很多次真的是很后悔如这一行了