在不丢失 OpenCV 数据的情况下从图像中去除噪声
Remove noise from image without losing data in OpenCV
我使用了这个代码:
horizontalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (horizontalsize, 1))
horizontal = cv2.erode(horizontal, horizontalStructure, (-1, -1))
horizontal = cv2.dilate(horizontal, horizontalStructure, (-1, -1))
删除线条。
和一些过滤器来删除噪音和加粗字体:
blur = cv2.GaussianBlur(img, (11, 11), 0)
thresh = cv2.threshold(blur, 80, 255, cv2.THRESH_BINARY)[1]
kernel = np.ones((2,1), np.uint8)
dilation = cv2.erode(thresh, kernel, iterations=1)
dilation = cv2.bitwise_not(dilation)
尽管有阈值和其他方法,如您所见,仍然存在很多噪声
这是我想要达到的结果:
您知道可以帮助我实现此结果的 OpenCV 过滤器吗?
以下解决方案并不完美,也不是通用的解决方案,但我希望它足以满足您的需求。
为了删除线,我建议使用 cv2.connectedComponentsWithStats
来查找集群,并屏蔽宽或长的集群。
该解决方案使用以下阶段:
- 将图像转换为灰度。
- 应用阈值并反转极性。
通过应用标志 cv2.THRESH_OTSU
. 使用自动阈值
- 使用"close"形态学操作来缩小小间隙。
- 使用统计信息查找连接的组件(集群)。
- 迭代集群,删除宽度和高度大的集群。
删除非常小的簇 - 被认为是噪音。
- 顶部和左侧已清洁 "manually"。
代码如下:
import numpy as np
import cv2
img = cv2.imread('Heshbonit.jpg') # Read input image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert to Grayscale.
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # Convert to binary and invert polarity
# Use "close" morphological operation to close small gaps
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.array([1, 1]));
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.array([1, 1]).T);
nlabel,labels,stats,centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)
thresh_size = 100
# Delete all lines by filling wide and long lines with zeros.
# Delete very small clusters (assumes to be noise).
for i in range(1, nlabel):
#
if (stats[i, cv2.CC_STAT_WIDTH] > thresh_size) or (stats[i, cv2.CC_STAT_HEIGHT] > thresh_size):
thresh[labels == i] = 0
if stats[i, cv2.CC_STAT_AREA] < 4:
thresh[labels == i] = 0
# Clean left and top margins "manually":
thresh[:, 0:30] = 0
thresh[0:10, :] = 0
# Inverse polarity
thresh = 255 - thresh
# Write result to file
cv2.imwrite('thresh.png', thresh)
我使用了这个代码:
horizontalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (horizontalsize, 1))
horizontal = cv2.erode(horizontal, horizontalStructure, (-1, -1))
horizontal = cv2.dilate(horizontal, horizontalStructure, (-1, -1))
删除线条。
和一些过滤器来删除噪音和加粗字体:
blur = cv2.GaussianBlur(img, (11, 11), 0)
thresh = cv2.threshold(blur, 80, 255, cv2.THRESH_BINARY)[1]
kernel = np.ones((2,1), np.uint8)
dilation = cv2.erode(thresh, kernel, iterations=1)
dilation = cv2.bitwise_not(dilation)
尽管有阈值和其他方法,如您所见,仍然存在很多噪声
这是我想要达到的结果:
您知道可以帮助我实现此结果的 OpenCV 过滤器吗?
以下解决方案并不完美,也不是通用的解决方案,但我希望它足以满足您的需求。
为了删除线,我建议使用 cv2.connectedComponentsWithStats
来查找集群,并屏蔽宽或长的集群。
该解决方案使用以下阶段:
- 将图像转换为灰度。
- 应用阈值并反转极性。
通过应用标志cv2.THRESH_OTSU
. 使用自动阈值
- 使用"close"形态学操作来缩小小间隙。
- 使用统计信息查找连接的组件(集群)。
- 迭代集群,删除宽度和高度大的集群。
删除非常小的簇 - 被认为是噪音。 - 顶部和左侧已清洁 "manually"。
代码如下:
import numpy as np
import cv2
img = cv2.imread('Heshbonit.jpg') # Read input image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Convert to Grayscale.
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # Convert to binary and invert polarity
# Use "close" morphological operation to close small gaps
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.array([1, 1]));
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.array([1, 1]).T);
nlabel,labels,stats,centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)
thresh_size = 100
# Delete all lines by filling wide and long lines with zeros.
# Delete very small clusters (assumes to be noise).
for i in range(1, nlabel):
#
if (stats[i, cv2.CC_STAT_WIDTH] > thresh_size) or (stats[i, cv2.CC_STAT_HEIGHT] > thresh_size):
thresh[labels == i] = 0
if stats[i, cv2.CC_STAT_AREA] < 4:
thresh[labels == i] = 0
# Clean left and top margins "manually":
thresh[:, 0:30] = 0
thresh[0:10, :] = 0
# Inverse polarity
thresh = 255 - thresh
# Write result to file
cv2.imwrite('thresh.png', thresh)