python - 使用神经网络非常准确地去除手写字符/数字的背景并为任何新图像自动执行此过程
问题描述
我知道这可以通过应用阈值和使用 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”):
后来,在这种图像上:
是否可以重建如此小的字符/数字?
我应该如何提高它的性能?如果架构、数据集的大小、分辨率或其他方面有改进的话。
如果还有其他更好的方法,我会很高兴知道。
解决方案
你需要数据来训练你的网络,在图像之前和之后,以你期望的结果训练网络。
这就是为什么您需要“使用 OpenCV 应用阈值和其他一些技术”。
一种方法是使用[此处](使用 OpenCV 从图像中删除水印 )或此处所述的从图像中删除水印的技术。
移除背景并使用图像训练网络。
另一种方法是创建合成图像来训练网络。这里的一个优点是您事先拥有生成的图像。
- 取一个空的背景
- 使用一些字体在其上绘制(之后,合成图像)
- 在白色背景上绘制相同的东西(之前)
用这些图像训练网络。使用这种方法的另一个优点是您可以在不同的字体、字体大小和背景上训练您的网络。
推荐阅读
- unity3d - 如何使用 Hololens 在 Unity 中获取点击 rawImage 的坐标?
- java - JAX-B 反序列化自定义标签
- excel - 使用 Table2excel 插件将自定义表格 HTML 下载到 Excel
- python - 如何在matplotlib中给定开始日期设置轴日期刻度
- javascript - 查找元素的可滚动容器,包括在 shadow DOM 中
- autoit - ntp数据包解码
- python - 如何将此 pyqt4 代码转换为 pyqt5?
- java - JSplitPane:可以让一侧为空/透明以查看下面的下层吗?
- python - 通过检查多个条件更改 Pandas 列值
- c - 为什么下面代码中的 printf 语句打印的是值而不是垃圾值?