python - 如何使用水平投影清理二进制图像?

标签 python opencv image-processing

我想使用二进制过滤器从车牌中删除除文本之外的任何内容。

我在每个轴上都有投影,但我不知道如何应用它。我的想法是删除白色轮廓。

这是我现在正在工作的图像:

enter image description here

这是 X 轴上的投影:

from matplotlib import pyplot as plt
import pylab

(rows,cols)=img.shape
h_projection = np.array([ x/255/rows for x in img.sum(axis=0)])
plt.plot(range(cols), h_projection.T)

这是结果:

enter image description here

正如您在图表中看到的那样,线的末端是由白色轮廓拍摄的。

如何删除照片某个阈值的所有内容?感谢每一个帮助

最佳答案

因此,您要提取白色字符中的黑色区域。
例如,您可以在直方图中选择值小于某个阈值的列(或行)。

from matplotlib import pyplot as plt
import pylab
import numpy as np


img = plt.imread('binary_image/iXWgw.png')
(rows,cols)=img.shape
h_projection = np.array([ x/rows for x in img.sum(axis=0)])
threshold = (np.max(h_projection) - np.min(h_projection)) / 4
print("we will use threshold {} for horizontal".format(threshold))
# select the black areas
black_areas = np.where(h_projection < threshold)
fig = plt.figure(figsize=(16,8))
fig.add_subplot(121)
for j in black_areas:
    img[:, j] = 0
    plt.plot((j, j), (0, 1), 'g-')
plt.plot(range(cols), h_projection.T)

v_projection = np.array([ x/cols for x in img.sum(axis=1)])
threshold = (np.max(v_projection) - np.min(v_projection)) / 4
print("we will use threshold {} for vertical".format(threshold))
black_areas = np.where(v_projection < threshold)
fig.add_subplot(122)
for j in black_areas:
    img[j, :] = 0
    plt.plot((0,1), (j,j), 'g-')
plt.plot(v_projection, range(rows))
plt.show()

# obscurate areas on the image
plt.figure(figsize=(16,12))
plt.subplot(211)
plt.title("Image with the projection mask")
plt.imshow(img)

# erode the features
import scipy
plt.subplot(212)
plt.title("Image after erosion (suggestion)")
eroded_img = scipy.ndimage.morphology.binary_erosion(img,  structure=np.ones((5,5))).astype(img.dtype)
plt.imshow(eroded_img)
plt.show()

所以现在你有了水平和垂直投影,看起来像这样

enter image description here

之后你可以应用掩码:有几种方法可以做到这一点,在代码中已经应用了 for 循环,我们在其中设置 img[:,j] = 0对于列,img[j,:] = 0为行。这很简单,我认为很直观,但你可以寻找其他方法。
作为一个建议,我想说你可以查看 erosion 的形态运算符这可以帮助分离白色部分。
所以输出看起来像这样。

enter image description here

不幸的是,上部和下部仍然显示白色区域。您可以手动将行设置为白色 img[:10,:] = 0, img[100:,:] = 0 ,但这可能不适用于您拥有的所有图像(如果您正在尝试训练神经网络,我假设您有很多图像,因此您需要有一个适用于所有图像的代码。

所以,既然你现在也要求分割,这就打开了另一个话题。分割是一项复杂的任务,它不像二进制掩码那样简单。我强烈建议你在不理解的情况下应用一些东西之前阅读一些关于这方面的 Material 。例如 here a guide on image processing with scipy ,但您可能会寻找更多。
作为一个建议和一个小片段,您可以使用 scipy.ndimage 中的标签。 .
这里有一小部分代码(来自 guide )
label_im, nb_labels = scipy.ndimage.label(eroded_img)
plt.figure(figsize=(16,12))
plt.subplot(211)
plt.title("Segmentation")
plt.imshow(label_im)   
plt.subplot(212)
plt.title("One Object as an example")
plt.imshow(label_im == 6)   # change number for the others!

这将输出:

enter image description here

作为一个例子,我展示了 S信。如果你改变 label_im == 6你会收到下一封信。正如您将看到的那样,它并不总是正确的,图像的其他小块也被视为对象。所以你将不得不在这方面做更多的工作。

关于python - 如何使用水平投影清理二进制图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62127537/

相关文章:

python - 如何使用nopython true检查推断的numba类型?

python - mypy 可以检查文档字符串吗?

opencv - 使用cmake和opencv构建 "hollow world"错误: undefined reference to viz's moduls

python - 获取从最低点到裁剪的水平线

Python Pandas - groupby() 和 apply() 和rolling() 非常慢

c++ - OpenCV 人脸检测 ROI 断言失败

objective-c - 使用强光混合模式时突出显示伪影

image-processing - 固定 Gabor 滤波器卷积神经网络

matlab - 在 Matlab 中使用主成分分析 (PCA) 计算和绘制主成分

python - 为什么我们在 Python 类中使用 __init__?