【问题标题】:Algorithm that Fills the White Holes Within the Character Image填充字符图像中的白洞的算法
【发布时间】:2020-10-03 17:26:21
【问题描述】:

我有这个退化的图像:

Paint.NET Windows 应用程序中使用paintbucket 工具,我将字符图像填充为黑色。

我的问题是:

  1. 我们可以使用什么算法来填补字符图像中的漏洞?
  2. Python中是否有相应的内置函数来填补字符图像中的白洞?
  3. Paint.Net 中的油漆桶工具使用什么可能的算法?

谢谢。

【问题讨论】:

  • Paint.net 的填充算法请参考this

标签: python python-3.x image image-processing signal-processing


【解决方案1】:

不是 python 的答案,但您仍然可能会觉得这很有趣。如果你不这样做,这一切都是免费的,所以请原谅我。

我有一个 C# 解决方案,它对 Paint.Net 不擅长的事情非常有用,例如在无法确定边界在哪里时使用油漆桶工具。

我的网站https://pixeldatabase.net 使用我发明的一种语言,称为位图查询语言,简称 BQL。如果您了解 SQL for SQL Server,那么您已经完成了 BQL 的 80%。

支持此功能的 Nuget 包位于此处:
Nuget:DataJuggler.PixelDatabase
https://github.com/DataJuggler/PixelDatabase

BQL 与在 Paint.Net 中单击油漆桶工具的作用相同,但更好,因为它填补了小空白:

更新
设置颜色 黑色
在哪里
总计

结果:

BQL 的工作方式是首先应用所有标准,在这种情况下,所有像素的总和

  • 为简单起见,小于 (

背景区域的总和都在500以上,所以查询只影响暗区。

如果您不想在右侧添加额外的黑色小区域,只需添加以下内容:
X

这与第一个查询的作用相同,但它只影响小于等于 168 的像素。

我要告诉你的最后一件事是,如果你想在上一个查询之后删除背景:

隐藏
总计 > 20

这将消除任何总值为 20 或更高的像素:

这里看起来是白色的,因为这个页面是白色的。

我使用 Paint.Net 已有 15 年了,对我来说,BQL 是图像所需要的。

如果冒犯了任何人,很抱歉在这里发帖,我只是觉得我创造了一些超级整洁的东西,但也许像我所有其他想法一样,我是唯一喜欢它的人。

【讨论】:

    【解决方案2】:

    以下解决方案使用 OpenCV 和 Numpy 库,但产生的结果比 Paint.Net 还要好。代码部分的解释是内联的:

    import numpy as np
    import cv2
    
    # The standard stuff: image reading, grayscale conversion, inverting, morphology & edge detection
    image = cv2.imread('charm.png')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.bitwise_not(gray)
    sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    gray = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, sqKernel)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
    edges = cv2.Canny(thresh, 50, 200)
    
    # Finding and sorting contours based on contour area
    cnts = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
    
    # Filling the contours with black color
    for c in cnts:
        cv2.drawContours(image, [c], -1, (0, 0, 0), -1)
    
    # Displaying the result
    cv2.imshow("Contour", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    输出结果:

    【讨论】:

    • 您也可以使用 cv2.connectedComponentsWithStats 代替 Contours 进行区域选择。
    【解决方案3】:

    从我的大学时代开始,我就记得工作/构建灰度形态过滤器。

    您可以在以下链接中检查灰度侵蚀和膨胀。我认为 Paint.Net 本身也使用了类似的技术。

    https://imagej.net/index.php?title=MorphoLibJ&mobileaction=toggle_view_mobile

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2012-03-17
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 2019-05-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多