我在 OpenCV 中尝试了一些过滤器/操作,似乎效果很好。
第 1 步:放大图像 -
kernel = np.ones((5, 5), np.uint8)
cv2.dilate(img, kernel, iterations = 1)
如你所见,噪点消失了,但字符很轻,所以我侵蚀了图像。
第 2 步:腐蚀图像 -
kernel = np.ones((5, 5), np.uint8)
cv2.erode(img, kernel, iterations = 1)
如您所见,噪音消失了,但其他列上的一些字符已损坏。我建议仅在嘈杂的列上运行这些操作。您可能想使用HoughLines 来查找最后一列。然后您可以只提取该列,运行膨胀+腐蚀并将其替换为原始图像中的相应列。
此外,膨胀+腐蚀实际上是一种称为关闭的操作。这你可以直接调用 -
cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
正如@Ermlg 建议的那样,内核为 3 的 medianBlur 也可以很好地工作。
cv2.medianBlur(img, 3)
替代步骤
正如您所见,所有这些过滤器都有效,但最好只在噪声所在的部分实施这些过滤器。为此,请使用以下命令:
edges = cv2.Canny(img, 50, 150, apertureSize = 3) // img is gray here
lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, 1000, 50) // last two arguments are minimum line length and max gap between two lines respectively.
for line in lines:
for x1, y1, x2, y2 in line:
print x1, y1
// This gives the start coordinates for all the lines. You should take the x value which is between (0.75 * w, w) where w is the width of the entire image. This will give you essentially **(x1, y1) = (1896, 766)**
然后,你可以只提取这部分:
extract = img[y1:h, x1:w] // w, h are width and height of the image
然后,在此图像中实现过滤器(中值或闭合)。去除噪声后,您需要将这张过滤后的图像放置在原始图像中的模糊部分。
图像[y1:h, x1:w] = 中位数
这在 C++ 中很简单:
extract.copyTo(img, new Rect(x1, y1, w - x1, h - y1))
替代方法的最终结果
希望对您有所帮助!