OpenCV - 去除图像中的噪声

新手上路,请多包涵

我这里有一张带桌子的图片。在右边的列中,背景充满了噪音

如何检测有噪声的区域?我只想对有噪声的部分应用某种过滤器,因为我需要对其进行 OCR,任何类型的过滤器都会降低整体识别率

什么样的滤镜最适合去除图像中的背景噪声?

如前所述,我需要对图像进行 OCR

在此处输入图像描述

原文由 clarkk 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.6k
2 个回答

我在 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))

使用替代方法的最终结果

最后结果 希望能帮助到你!

原文由 Rick M. 发布,翻译遵循 CC BY-SA 3.0 许可协议

据我所知,中值滤波器是降低噪声的最佳解决方案。我建议使用具有 3x3 窗口的中值滤波器。见函数 cv::medianBlur()

但在同时使用任何噪声过滤和 OCR 时要小心。会导致识别准确率下降。

另外我建议尝试使用一对函数(cv::erode() 和 cv::dilate())。但我不确定它会是最好的解决方案,然后是 cv::medianBlur() 与窗口 3x3。

原文由 ErmIg 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题