联通区域标记(Connected Component Labeling)是图像处理里面常用的一个技术,它是用来检测二值图像中联通的区域,在许多跟踪检测算法中充当目标区域检测的作用。常见的CCL(Connected Component Labeling)包括Two-Pass的方法和One-Pass的方法,这里pass就是扫描的遍数,Two-Pass就是扫描两遍的算法,One-Pass就是扫描一遍的算法。下面仅就这两类算法中有代表性的算法做一个简单的介绍。

Two-Pass

传统的Two-Pass:

逐行扫描图像上的点,检查每个点是否是前景点,如果不是,继续扫描;

检查该前景点的左边的点和上边的点 如果有一个为前景点,则为当前扫描点标记和此点相同编号;

如果两个都是前景点,则选择标号小的,为当前扫描点标记编号;这里注意如果两个都是前景点且标号不同,需要把标号小的点设为标号大的点的父节点,以方便第二遍扫描的时候用并查集算法(参考 利用不相交集实现等价元素的聚类

)合并;

如果都不是,则赋值目前标号label,label++(label初始值为零);

再次扫描图像,利用并查集算法合并联通的不同的label的区域。

run-based的Two-pass:

该算法定义每一行联通的一个区域叫做 run

,把run看成一个整体,逐行搜寻时,完成一个run扫描好后再进行整个run的标记,标记的准则是按照上一行是否有run和自己联通来判断如何标记当前的run;

每个run有两个label:representative label和一个provisional label,这里我们用R和P表示。当出现上一行n个run联通当前行的run的时候,更改n个run的R为最小的R,我们设为Rmin,同时标记当前run的P和R为Rmin;

该算法的优势在于减少了第一遍扫描时标号的数量,从而减少了第二遍中联通区域的合并任务。具体算法可以参考 “A Run-Based Two-Scan Labeling Algorithm”

One-Pass

基于区域生长的方法

单次扫描的算法有一种基于区域生长的联通区域标记算法,基本的思路可以参考博客 二值图像连通区标记之区域生长法

。为防止链接失效,这里简单描述下流程:

输入待标记图像bitmap,初始化一个与输入图像同样尺寸的标记矩阵labelmap,一个队列queue以及标记计数labelIndex;

按从左至右、从上至下的顺序扫描bitmap,当扫描到一个未被标记的前景像素p时,labelIndex加1,并在labelmap中标记p(相应点的值赋为labelIndex),同时,扫描p的八邻域点,若存在未被标记的前景像素,则在labelmap中进行标记,并放入queue中,作为区域生长的种子;

当queue不为空时,从queue中取出一个生长种子点p1,扫描p1的八邻域点,若存在未被标记过的前景像素,则在labelmap中进行标记,并放入queue中;

重复3直至queue为空,一个连通区标记完成;

转到2,直至整幅图像被扫描完毕,得到标记矩阵labelmap和连通区的个数labelIndex。

基于轮廓跟踪的方法

还有一种经典的单次扫描的的算法是由台湾的中央研究院资讯科学研究所的 张复

提出的,源代码可以在其 实验室网站

下载到,而且OpenCV的Wiki网站还有专门一个库 cvBlobsLib

,就是实现的这个算法。算法的详细介绍可以参考 “A Linear-Time Component-Labeling Algorithm Using Contour Tracing Technique”

,这里作一个简单的介绍。

逐行扫描图像,设当前像素为P

如果P为为背景点,则继续,直到扫描到前景点;

如果P是 unlabeled

的,且正上方的像素为背景像素(如图1所示),认为p是一个新遇见的 外轮廓

的起点,然后以P为起点,开始进行contour tracing跟踪外轮廓,为该轮廓上的所有点标记为新的的标号C,然后C=C+1;

图 1

如果P的正下方的像素是 unmarked

(这里marked是指在contour tracing中外围轮廓周围的背景点会被mark)的背景像素。这里有两种情况:如果p是labeled的(如图2所示),则P既是外轮廓点,又是内轮廓点;如果P是unlabled的(如图3所示),则P左边的点N一定是labeled,则设置P和N相同的标号。无论是那种情况,都以P为起点进行contour tracing跟踪内轮廓,并把轮廓上所有的点标记和P相同的标号。

图 2

图 3

如果P不是以上两种情况,即P不是轮廓点,则P的左边点N一定是标记点,把P标记成和N相同标号即可。

Contour tracking

当遇到一个外轮廓或是内轮廓的起点时,首先通过 Tracker

搜寻轮廓的下一个点,直到输出点又一次为起点位置,从而实现轮廓的跟踪。

Tracker

如图4所示,Tracker的目的是搜寻当前点P周围八邻域的点,找到轮廓的下一个点。按照顺时针方向搜寻,对于一个外轮廓的起点,其起始搜寻点为7,因为6已经知道是个背景点,而对于一个内轮廓点,其起始搜寻点为3,因为2已经知道是个背景点。对于轮廓上的任意一个点,其下一个点的搜寻起始位置为(d+2) mod 8, 这里d是当前点的前一点的在当前的八邻域的位置,如图5所示。一旦起始搜寻点确定,按照顺时针方向搜寻第一个前景点就是下一个轮廓的点。但是cvBlobsLib上的实现方法是采用逆时针搜寻的方式,所以代码上和原论文中稍有不同。

图 4

图 5

总结

以上仅是我这几天查阅文献得到的一个初步总结,所以难免有疏漏,这里记下来仅仅是做个笔记,以备后来查阅。对于轮廓的检测在OpenCV中也有相应的函数findContours,这里列出供参考。

python连通区域计算长度_连通区域算法小结相关推荐

  1. python ssd目标检测_目标检测算法之SSD的数据增强策略

    前言 这篇文章是对前面<目标检测算法之SSD代码解析>,推文地址如下:点这里的补充.主要介绍SSD的数据增强策略,把这篇文章和代码解析的文章放在一起学最好不过啦.本节解析的仍然是上篇SSD ...

  2. python数据结构与算法分析_数据结构与算法(Python版)

    为什么研究数据结构与算法 本周带大家进入Python版数据结构与算法的学习.想必大家都听过"算法"一词,算法的学习对编程者来说是至关重要的.首先我们先了解一下为什么要研究数据结构与 ...

  3. 卷积神经网络算法python实现车牌识别_车牌识别算法之CNN卷积神经网络

    原标题:车牌识别算法之CNN卷积神经网络 随着我国经济的发展,汽车,特别是小轿车的数量越来越多,智能交通管理系统应运而生.车牌智能自动识别作为智能交通管理系统中的重要组成部分,在智能交通管理中发挥着越 ...

  4. 数据结构与算法python版 期末考试_数据结构与算法Python版期末在线考试OJ部分

    1 二叉树路径(10分) 题目内容: 给定一个二叉查找树的节点插入顺序,请重新构建这个二叉查找树,并按从左至右顺序返回所有根节点至叶节点的路径 输入格式: 一行整数,以空格分隔 注:测试用例中不包含重 ...

  5. r与python做随机森林_随机森林算法入门(python)

    昨天收到yhat推送了一篇介绍随机森林算法的邮件,感觉作为介绍和入门不错,就顺手把它翻译一下. 目录 1 什么是随机森林 1.1 集成学习 1.2 随机决策树 1.3 随机森林 1.4 投票 2 为什 ...

  6. python二分查找时间复杂度_二分查找算法的时间复杂度计算(logN)

    二分查找算法的时间复杂度计算(logN) 马富天 2019-08-10 20:25:24 54 [摘要]二分查找算法是对顺序查找算法的优化,二分查找算法的前提是数列是一个有序数列,递增或者递减,本文就 ...

  7. python遍历数组冒泡排序_经典排序算法(冒泡排序,选择排序,插入排序,快速排序,堆排序)python实现...

    最近在复习经典排序算法,自己用python也实现了一下,这里不会涉及到原理(因为网上方法已经很详细啦),就把函数贴上来,可以让大家自己试着运行下,再结合别处的原理也可以更好地理解它们的实现. 如果有错 ...

  8. python数据结构视频百度云盘_数据结构与算法Python视频领课

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 课程简介: 本课程包含Python编程基础的基本语法及变量,基本数据结构,Code Structure,Function.让学生在学会Python基础的同 ...

  9. mooc数据结构与算法python版期末考试_数据结构与算法Python版-中国大学mooc-试题题目及答案...

    数据结构与算法Python版-中国大学mooc-试题题目及答案 更多相关问题 婴儿出生一两天后就有笑的反应,这种笑的反应属于(). [判断题]填制原始凭证,汉字大写金额数字一律用正楷或草书书写,汉字大 ...

  10. knn算法python理解与预测_理解KNN算法

    KNN主要包括训练过程和分类过程.在训练过程上,需要将训练集存储起来.在分类过程中,将测试集和训练集中的每一张图片去比较,选取差别最小的那张图片. 如果数据集多,就把训练集分成两部分,一小部分作为验证 ...

最新文章

  1. DvaJS 入门, 快速上手Dva
  2. NIPS 2017上演:Google大神们将带来哪些「精彩」?
  3. 在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法
  4. shell date常用运算命令
  5. Sort the Array
  6. 100道Go语言面试题
  7. mysql与php6_PHP与MySQL的连接
  8. Java实现Oracle导出数据到Excel
  9. MySQL 常用工具sysbench/fio/tpcc等测试
  10. 基于51单片机的超声波红外避障捡拾小车
  11. LeetCode刷题复盘笔记—一文搞懂509. 斐波那契数70. 爬楼梯以及递归时间复杂度计算方法(动态规划系列第一篇)
  12. 数字逻辑电路(1)--逻辑代数基础
  13. 〖TensorFlow2.0笔记21〗自定义数据集(宝可精灵数据集)实现图像分类+补充:tf.where!
  14. Python中Numpy中省略号的作用
  15. 什么是面向对象、面向过程?
  16. Ubuntu无法重启:教你用u盘系统修复ubuntu
  17. BASE理论与ACID
  18. python 最简单的画图
  19. Java程序员从携程、美团、阿里面试回来,这些面经分享给大家
  20. 《黄帝内经.上古天真论》养生秘诀节选-1

热门文章

  1. OpenCV空间人工智能竞赛:第一部分
  2. 在Swift中使用dispatch_once单例模型
  3. FST(Finite-State Transducer) 原理
  4. 为什么股票一买就跌,一卖就涨?终于找到答案了!
  5. 使用 Visio 绘制卷积示意图
  6. 【愿头发与你我同在队】团队项目第一次作业-组队与选题
  7. python高频词汇表大全_我们用程序整理出了一份Python英语高频词汇表,拿走不谢!...
  8. js中submit失效
  9. 【按键】[独立按键] - 2:双击
  10. 怎么获取url_Requests库(十二)实战获取今日头条24小时热文