首页 > 解决方案 > 使用神经网络非常准确地去除手写字符/数字的背景并为任何新图像自动执行此过程

问题描述

我知道这可以通过应用阈值和使用 OpenCV 的一些其他技术来完成,但在这种情况下,不同的图像可能需要不同的阈值。

我尝试应用编码器-解码器神经网络。但是我注意到,对于字符大小很大的图像,我能够得到它,即每个图像有大约 4 个字符,但是当我增加数字或等效地减小图像中每个字符的大小时,结果非常糟糕.

我需要一个非常准确的输出,以便进一步将每个字符输入到识别模型中。

实际输入图像

灰度作为神经网络的输入图像

目标/地面实况(输出图像)

 def encoder_decoder(input_shape):
        return Sequential([
            Lambda(lambda x: x / 127.5 - 1.0, input_shape=input_shape),
            Convolution2D(8, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(8, 3, 3, activation='relu', border_mode='same'),
            MaxPooling2D((2,2), strides=(2,2)),
            Dropout(0.2),
            Convolution2D(16, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(16, 3, 3, activation='relu', border_mode='same'),
            MaxPooling2D((2,2), strides=(2,2)),
            Dropout(0.2),
            Convolution2D(32, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(32, 3, 3, activation='relu', border_mode='same'),
            MaxPooling2D((2,2), strides=(2,2)),
            Dropout(0.2),
            Convolution2D(64, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(64, 3, 3, activation='relu', border_mode='same'),
            MaxPooling2D((2,2), strides=(2,2)),
            Dropout(0.2),
            Convolution2D(128, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(128, 3, 3, activation='relu', border_mode='same'),
            UpSampling2D(size=(2,2)),
            Dropout(0.2),
            Convolution2D(64, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(64, 3, 3, activation='relu', border_mode='same'),
            UpSampling2D(size=(2,2)),
            Dropout(0.2),
            Convolution2D(32, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(32, 3, 3, activation='relu', border_mode='same'),
            UpSampling2D(size=(2,2)),
            Dropout(0.2),
            Convolution2D(16, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(16, 3, 3, activation='relu', border_mode='same'),
            UpSampling2D(size=(2,2)),
            Dropout(0.2),
            Convolution2D(8, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(8, 3, 3, activation='relu', border_mode='same'),
            Convolution2D(1, 1, 1, activation='relu')
        ])

背景也包含在不同图像中不完全相同的线条(也将被删除)。它们也不完全平行于应用 FFT。笔迹来自不同的人。

在一组小的图像(70 到 100)上训练神经网络进行测试,直到它过拟合。输入图像首先转换为灰度,即整个过程以灰度进行。图像的大小为(800X600),因为我需要进一步绘制轮廓并应用分类算法,我无法获得更小的输出。

早些时候,我在图像中包含较少字符数的清晰图像上训练(忽略此处的背景为“0”,在下一个示例中为输出“255”):

输入图像(灰度)

获得的输出

后来,在这种图像上:

输入图像

输入图像到NN(灰度)

神经网络的输出

是否可以重建如此小的字符/数字?

我应该如何提高它的性能?如果架构、数据集的大小、分辨率或其他方面有改进的话。

如果还有其他更好的方法,我会很高兴知道。

标签: pythondeep-learningconv-neural-network

解决方案


你需要数据来训练你的网络,在图像之前和之后,以你期望的结果训练网络。

这就是为什么您需要“使用 OpenCV 应用阈值和其他一些技术”。

一种方法是使用[此处](使用 OpenCV 从图像中删除水印 )或此处所述的从图像中删除水印的技术。

移除背景并使用图像训练网络。

另一种方法是创建合成图像来训练网络。这里的一个优点是您事先拥有生成的图像。

  • 取一个空的背景
  • 使用一些字体在其上绘制(之后,合成图像)
  • 在白色背景上绘制相同的东西(之前)

用这些图像训练网络。使用这种方法的另一个优点是您可以在不同的字体、字体大小和背景上训练您的网络。


推荐阅读