2

给定一张图像(如下图所示),我需要将其转换为二值图像(仅限黑白像素)。这听起来很简单,我尝试了两个阈值函数。问题是我无法使用这些功能中的任何一个获得完美的边缘。任何帮助将不胜感激。

我尝试过的过滤器是 RGB 和 HSV 空间中的欧几里得距离。

示例图片:

在此处输入图像描述

这是在运行 RGB 阈值过滤器之后。(40% 之后会出现更多的人工制品)

在此处输入图像描述

这是在运行 HSV 阈值过滤器之后。(在 30% 时,路径变得几乎看不到,但由于噪音明显无法使用)

在此处输入图像描述

我使用的代码非常简单。将输入图像更改为适当的颜色空间,并使用黑色检查欧几里得距离。

sqrt(R*R + G*G + B*B)

因为我正在与黑色 (0, 0, 0) 进行比较

4

5 回答 5

3

您的问题似乎是扫描图像上的照明变化,这表明局部自适应阈值方法可以为您提供更好的结果。

Sauvola 方法根据原始图像窗口中像素的均值和标准差计算二值化像素的值。这意味着,如果图像的某个区域通常更暗(或更亮),则将为该区域调整阈值,并且(可能)在二值化图像中为您提供更少的暗点或褪色线。

http://www.mediateam.oulu.fi/publications/pdf/24.p

我还找到了 Shafait 等人的方法。以更高的时间效率实现 Sauvola 方法。缺点是您必须计算原始图像的两个完整图像,一个为每像素 8 位,另一个可能为每像素 64 位,这可能会出现内存限制问题。

http://www.dfki.uni-kl.de/~shafait/papers/Shafait-efficient-binarization-SPIE08.pdf

我没有尝试过这两种方法,但它们看起来很有希望。我通过粗略的 Google 搜索找到了两者的 Java 实现。

于 2013-06-13T15:39:16.230 回答
1

在 HSV 颜色空间中的 V 通道上运行自适应阈值应该会产生出色的结果。最好的结果将来自大于 11x11 大小的窗口,不要忘记为阈值选择一个负值。

自适应阈值基本上是:

if (Pixel value + constant > Average pixel value in the window around the pixel )
    Pixel_Binary = 1;
else
    Pixel_Binary = 0;
于 2013-06-13T16:06:50.823 回答
1

由于噪声和光照变化,您可能需要自适应局部阈值,这也感谢 Beaker 的回答。

因此,我尝试了以下步骤:

  • 将其转换为灰度。

  • 进行均值或中值局部阈值处理,我使用 10 作为窗口大小,使用 10 作为截距常数并得到这个图像(较小的值也可能有效): 图片

    如果您需要有关此技术的更多信息,请参阅:http ://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm。

  • 为了确保阈值工作正常,我对其进行了骨架化以查看是否有换行符。该骨架可能是进一步处理所需的骨架。

图片

  • 要消除剩余的噪声,您可以在骨架化图像中找到最长的连接组件。

谢谢你。

于 2013-06-13T16:22:20.170 回答
0

您可能希望将此作为三步操作。

  1. 使用调平,而不仅仅是阈值:获取输入并使用仅使中间色调变暗的参数缩放强度(伽马校正),而不消除黑暗或灯光(例如,您的 rgb 阈值太强。您丢失了一些行)。

  2. 使用小内核卷积对生成的图像进行边缘检测(二进制图像的 5x5 应该绰绰有余)。使用简单的 [1 2 3 2 1 ; 2 3 4 3 2 ; 3 4 5 4 3 ; 2 3 4 3 2 ; 1 2 3 2 1] 内核(标准化)

  3. 阈值生成的图像。您现在应该有一个更好的二进制图像。

于 2013-06-13T14:42:03.087 回答
0

您可以尝试黑色礼帽变换。这涉及从图像的关闭中减去图像。我使用了 11 的结构元素窗口大小和 0.1 的常数阈值(25.5 on 255 比例)

你应该得到类似的东西:

在此处输入图像描述

然后您可以轻松地设置阈值:

在此处输入图像描述

祝你好运。

于 2013-06-17T01:22:53.667 回答