手写算式的输入的形式,有2种:拍照、手绘。照片要经过图像处理之后,才能 进行切割;而手绘可直接采集像素轨迹,就省掉了这一步。对于照片的预处理,需要二值化和降噪才能把手写数字区域抠出来。
往往图片还有一些背景,就变得有些麻烦了。只是去噪,就想把手写的算式分解出来,好像有点悬。试了一下Canny 算子检测边缘,还挺有效果的。这借助OpenCV的API很容易实现。
我们这种要求手写不黏连的情况,把Canny输出的二值图像往X轴投影,就能得出每个数字的横向跨度和坐标。但不黏连也有笔画上下重叠的情况,那就得写个算法去绕圈了,或者估计一下字符宽度硬裁剪。哎,先不考虑这么复杂了。
图像处理的算法,自己实现还挺麻烦的,但用OpenCV也是大材小用,就在CSDN和GitHub各找了一份Canny实现代码。发现GitHub上的实现出奇的好,而CSDN上忽略了很多实现的细节,很难实用。(下图是Canny结果)
接着,我就发现实用Canny边缘检测法,虽然纯净噪点少,但算式变成空心字了,关键是还断线,无法使用FloodFill(泛水)算法填充。不过,也不少一点用处没有,至少可以用来切割,容易检测每个字符的边界。
经过Canny算子处理之后,切割图像就非常容易了。把Canny输出的二值图像,在 水平方向上投影,对数字进行竖向分割;同理,在纵向再做一次,就能切割得紧凑一 些。以上,就是在原图上切割的效果。
Minist数据集是白底黑字的,使用它训练出来的模型,就很难识别我们的手写算式。 所以,有必要在二值图像上切割。
好像,还是乖乖地不是黑底白字面临的问题是,怎么填充啊,怎么填充?感觉图像处理看的不多,一时有点恍惚了。使用我的洪荒之力,发现膨胀一下像素点就可以~
接下来,就剩尺寸标准化了。要做成Minist那样的28 × 28像素就很简单了,缩放一下图片就行。
下回继续~
领取专属 10元无门槛券
私享最新 技术干货