【问题标题】:Implementing 8-Connectivity Connected-Component Labeling in Python在 Python 中实现 8-Connectivity Connected-Component Labeling
【发布时间】:2012-01-15 02:34:06
【问题描述】:

仅出于教育目的,我正在使用 Python 制作一个字母和符号识别程序,但在区域分离方面遇到了一些麻烦。我使用此处的信息制作了一个有效的连接组件标签功能:

CCL - Wikipedia

但我需要一个具有 8 连接精度的设备,它提到但没有提供相关信息。它的右侧有一个图表,显示要检查它,需要包括西北和东北像素,但我不知道如何,也找不到任何信息。我不是要代码,但是任何熟悉这种方法的人都可以描述如何合并这些代码吗?

【问题讨论】:

    标签: python image-processing ocr image-recognition


    【解决方案1】:

    8 连接并不更准确,实际上它仅适用于某些应用程序。使用 4 连接更为常见,尤其是对于“自然”图像,而不是在实验室中创建用于测试的图像。一个 8 连接区域将包括棋盘图案和锯齿形噪声。一个 4 连接的前景产生一个 8 连接的背景。

    您可以深入了解 OpenCV 函数 cvFindContours() 的源代码。有与 Python 的 OpenCV 绑定。 http://opencv.willowgarage.com/documentation/python/structural_analysis_and_shape_descriptors.html

    http://opencv.willowgarage.com/wiki/PythonInterface

    我建议首先实现一个 4-connected 算法。您可以在以下书籍中找到伪代码:

    • 机器视觉:理论、算法、实践 作者:E. R. Davies 在第 3 版中,请参阅第 6.3 节“对象标记和计数”
    • 数字图像处理,Gonzalez 和 Woods 请参阅第 9.5.3 节“连接组件的提取” 演示不太清楚,但这是一本标准的图像处理一体化教科书。关于二值化阈值的部分很好。国际版的价格约为 35 美元。
    • 较旧的教科书可能有简单、直接的描述。 Ballard 和 Brown 的
      Computer Vision 的二手副本非常便宜。在那本书中,算法 5.1 被称为 Blob Coloring。
    • 我最喜欢的快速描述可以在 Al Bovik 编辑的图像和视频处理手册的“区域标记算法”部分找到。方便的是,第 44 - 45 页可在 Google 图书中在线获取: http://books.google.com/books?id=UM_GCfJe88sC&q=region+labeling+algorithm#v=snippet&q=region%20labeling%20algorithm&f=false

    对于 OCR,通常会在浅色背景上寻找深色连接区域(斑点)。我们的二值化图像将是 1 位图像中白色背景 (1) 上的黑色前景 (0)。

    对于 4 连接算法,您将使用如下所示的结构元素(您还将在 Bovik 书中看到)。一旦你修改了 4 连接,8 连接的扩展应该是显而易见的。

    我们从左到右扫描图像中的每一行像素,从上到下扫描所有行。对于任何像素 (x,y),它的左邻 (x - 1, y) 和上邻 (x, y - 1) 已经被扫描,因此我们可以检查区域编号是否已经分配给其中一个或两个那些邻居。例如,如果像素 (x, y-1) 被标记为区域 8,并且如果 (x,y) 也是前景像素,那么我们将区域 8 分配给 (x,y)。如果像素 (x,y) 是前景像素,但左侧和顶部邻居是背景像素,我们将新的区域编号分配给 (x,y)。

    我推荐 Bovik 参考,但这里是算法的快速概述。

    1. 初始化区域编号轮廓(例如“region = 0”)
    2. 初始化“区域等效性”数据结构以供以后处理。
    3. 使用二值化阈值创建黑白图像。
    4. 从上到下、从左到右扫描图像中的每个像素。
    5. 将区域 0 分配给任何白色背景 (1) 像素。
    6. 对于任何黑色前景像素 (x,y) 测试以下条件:
      • 如果顶部和左侧像素是前景,则使用 (x-1, y) 的区域编号作为 (x,y) 的区域编号,并跟踪左侧和顶部区域编号的等效性。
      • 如果只有左邻 (x - 1,y) 是前景像素,则将其区域编号用于 (x,y)
      • 如果只有顶部邻居 (x, y - 1) 是前景像素,则将其区域编号用于 (x,y)
      • 如果左侧和顶部邻居是背景像素,则增加区域编号并将此新区域编号分配给 (x,y)。
    7. 对整个图像完成此处理后,分析等效矩阵并将等效区域的每个集合缩减为单个区域。

    当量的减少是棘手的部分。在下图中,区域已根据算法正确标记。图像为每个区域编号显示不同的颜色。三个接触区域必须缩减为一个连接区域。

    您的代码应扫描等效数据结构以将 2(红色)和 3(深蓝色)重新分配给编号最小的区域,即 1(黄色)。区域编号重新分配完成后,区域标注就完成了。

    有一次性算法可以完全避免等效性检查,尽管此类算法实施起来有点困难。我建议首先实现传统的 4-connectivity 算法,解决它的问题,然后引入一个使用 8-connectivity 的选项。 (这个选项在图像处理库中很常见。)一旦你有 4-connected 和 8-connected region labeling 工作,你就会有一个很好的算法,可以找到很多用途。在搜索有关该主题的学术论文时,请检查“区域标签”、“斑点”、“轮廓”和“连接性”。

    对于需要二值化的灰度算法,您的阈值算法可能会成为您算法链中的薄弱环节。如需有关阈值的帮助,请获取 Gonzalez 和 Woods 书籍的副本。对于 OCR,请查看 Cheriet、Karma、Liu 和 Suen 所著的字符识别系统一书。

    【讨论】:

    • 为了速度,我推荐 Chen 和 Chang google.com/…"A Component-Labeling Algorithm Using Contour Tracing Technique" 中实现的单通道算法。
    • 假设我选择了一个二值图像的连通分量(CC),并想在原始图像中扫描并找到该 CC 的相邻暗像素和亮像素位置,您将如何实现?
    • @JuneWang:有几种处理方法,具体取决于内存和速度要求。如果你有可用的内存,你可以保存一张 0 和 1 的图像,其中 1 代表感兴趣的连接组件(“博客”)。然后您可以将每个像素的 (x,y) 与图像中的 1 值与原始图像中的 (x,y) 相关联。或者,您可以将一个或多个 blob 与整数 -1(所有位设置为 1)相关联,将背景像素设置为 0,并将 -1/0 图像与原始图像组合。根据您的需要,还有许多其他方法可以做到这一点。
    【解决方案2】:

    我建议实现 8-cclabeling,posted on Github。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-05
      • 1970-01-01
      • 1970-01-01
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      相关资源
      最近更新 更多