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 算法。您可以在以下书籍中找到伪代码:
对于 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 参考,但这里是算法的快速概述。
- 初始化区域编号轮廓(例如“region = 0”)
- 初始化“区域等效性”数据结构以供以后处理。
- 使用二值化阈值创建黑白图像。
- 从上到下、从左到右扫描图像中的每个像素。
- 将区域 0 分配给任何白色背景 (1) 像素。
- 对于任何黑色前景像素 (x,y) 测试以下条件:
- 如果顶部和左侧像素是前景,则使用 (x-1, y) 的区域编号作为 (x,y) 的区域编号,并跟踪左侧和顶部区域编号的等效性。
- 如果只有左邻 (x - 1,y) 是前景像素,则将其区域编号用于 (x,y)
- 如果只有顶部邻居 (x, y - 1) 是前景像素,则将其区域编号用于 (x,y)
- 如果左侧和顶部邻居是背景像素,则增加区域编号并将此新区域编号分配给 (x,y)。
- 对整个图像完成此处理后,分析等效矩阵并将等效区域的每个集合缩减为单个区域。
当量的减少是棘手的部分。在下图中,区域已根据算法正确标记。图像为每个区域编号显示不同的颜色。三个接触区域必须缩减为一个连接区域。
您的代码应扫描等效数据结构以将 2(红色)和 3(深蓝色)重新分配给编号最小的区域,即 1(黄色)。区域编号重新分配完成后,区域标注就完成了。
有一次性算法可以完全避免等效性检查,尽管此类算法实施起来有点困难。我建议首先实现传统的 4-connectivity 算法,解决它的问题,然后引入一个使用 8-connectivity 的选项。 (这个选项在图像处理库中很常见。)一旦你有 4-connected 和 8-connected region labeling 工作,你就会有一个很好的算法,可以找到很多用途。在搜索有关该主题的学术论文时,请检查“区域标签”、“斑点”、“轮廓”和“连接性”。
对于需要二值化的灰度算法,您的阈值算法可能会成为您算法链中的薄弱环节。如需有关阈值的帮助,请获取 Gonzalez 和 Woods 书籍的副本。对于 OCR,请查看 Cheriet、Karma、Liu 和 Suen 所著的字符识别系统一书。