在Python中去噪二值图像

5
对于我的项目,我正在尝试使用Python中的openCV对图像进行二值化处理。我使用了openCV的自适应高斯阈值法来转换图像,得到了以下结果: enter image description here 我想使用这个二进制图像进行OCR识别,但它太嘈杂了。有没有办法在Python中从二进制图像中去除噪声?我已经尝试了openCV中的fastNlMeansDenoising方法,但没有任何效果。
P.S. 如果有更好的二值化选项,请告诉我。

你可以为cv2.adaptive函数使用更大的常量参数。 - Demetry Pascal
3个回答

3

这种任务也可以使用GraphCuts来完成。为了运行代码,您需要安装maxflow库。我从他们的教程中快速复制并修改了代码,以便您更容易地运行它。只需调整平滑参数以增加或减少图像的去噪程度即可。

import cv2
import numpy as np
import matplotlib.pyplot as plt
import maxflow 

# Important parameter
# Higher values means making the image smoother
smoothing = 110

# Load the image and convert it to grayscale image 
image_path = 'your_image.png'
img = cv2.imread('image_path')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = 255 * (img > 128).astype(np.uint8)

# Create the graph.
g = maxflow.Graph[int]()
# Add the nodes. nodeids has the identifiers of the nodes in the grid.
nodeids = g.add_grid_nodes(img.shape)
# Add non-terminal edges with the same capacity.
g.add_grid_edges(nodeids, smoothing)
# Add the terminal edges. The image pixels are the capacities
# of the edges from the source node. The inverted image pixels
# are the capacities of the edges to the sink node.
g.add_grid_tedges(nodeids, img, 255-img)

# Find the maximum flow.
g.maxflow()
# Get the segments of the nodes in the grid.
sgm = g.get_grid_segments(nodeids)

# The labels should be 1 where sgm is False and 0 otherwise.
img_denoised = np.logical_not(sgm).astype(np.uint8) * 255

# Show the result.
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.title('Binary image')
plt.subplot(122)
plt.title('Denoised binary image')
plt.imshow(img_denoised, cmap='gray')
plt.show()

# Save denoised image
cv2.imwrite('img_denoised.png', img_denoised)

结果


2
你应该先调整自适应阈值的参数,使其使用更大的区域,这样它就不会分割噪声了。当输出图像比输入图像有更多的噪声时,你就知道你做错了什么。
我建议使用一个闭合运算(在输入灰度图像上)配合一个足够大的结构元素来作为自适应阈值。这个结果与输入图像之间的差异正好是所有文本。然后,你可以对这个差异应用常规阈值。

我已经使用了自适应阈值处理,但是我尝试调整变量,这产生了很大的影响。感谢您的回答。 - R.hagens

0
你可以尝试使用形态学变换中的闭运算来去除小的“孔洞”。 首先使用numpy定义一个核,你可能需要调整大小。将核的大小选择为噪音大小即可。
kernel = np.ones((5,5),np.uint8)

然后使用内核运行 morphologyEx。

denoised = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)

如果文本被删除,您可以尝试侵蚀图像,这将“增加”黑色像素。如果噪声与数据一样大,这种方法将无法帮助。

erosion = cv2.erode(img,kernel,iterations = 1)

1
谢谢你的回答,我喜欢你的方法,但是对于这张图片来说并不太适用。不过我已经找到了另一种二值化图像的方法,名为Sauvola阈值。 - R.hagens
1
谢谢您的评论。我担心这可能行不通,因为图像噪声很大。Sauvola阈值看起来很有前途,我也会尝试一下! - aclown

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接