目前关于图像的标记算法是研究的热点,下面来介绍一下关于二值图像的区域标记算法的原理及其相关说明:
到现在为止,图像的标记算法有很多,这些方法大致可以分为以下3类:
1、像素标记法:根据标记过程中对图像扫描次数的不同可以分为:两次扫描法、单向反复扫描法、以及双向反复扫描法。两次扫描法第一次扫描时记录冲突的标记并形成等价对(存储在特殊的数据结构中),第二次扫描时,把等价标记中最小的标记赋予所有等价标记对应的像素点。单向反复扫描法,反复扫描图像,并在同一连通区域内传播最小标号,直到没有标号变化为止。双向反复扫描法,正向和反向反复扫描图像,并在邻域内传播标号,直到没有标号变化为止。
2、线标记法:将目标段(目标物体同一行中两个边界点像素集合,包括边界点)作为连通体检测的基本单元,第一次扫描时记录冲突的标记并形成等价对;第二次扫描时用等价标记中最小的标号赋予所有等价标号对应的像素点。在线标记法的基础上发展起来的算法有基于跑长码的标记算法、基于游程的标记算法等。
3、区域增长法:依次扫描二值图像中的每个像素点,当找到某个未标记的目标像素时,将其压入堆栈并从该点开始反复标记其邻域,直到堆栈为空。 常见的有8邻域连通标记和4邻域连通标记,区域增长的扫描次数可以由自己设定。我主要介绍的就是4邻域和8邻域的标记算法,具体如下:
4邻域标记算法流程如下:
1)判断此点四邻域中的最左,最上有没有点,如果都没有点,则表示一个新的区域的开始。
2)如果此点四邻域中的最左有点,最上没有点,则标记此点为最左点的值;如果此点四邻域中的最左没有点,最上有点,则标记此点为最上点的值。
3)如果此点四邻域中的最左有点,最上都有点,则标记此点为这两个中的最小的标记点,并修改大标记为小标记。
8邻域标记算法流程如下:
1)判断此点八邻域中的最左,左上,最上,上右点的情况。 如果都没有点,则表示一个新的区域的开始。
2)如果此点八邻域中的最左有点,上右都有点,则标记此点为这两个中的最小的标记点,并修改大标记为小标记。
3)如果此点八邻域中的左上有点,上右都有点,则标记此点为这两个中的最小的标记点,并修改大标记为小标记。
4)否则按照最左,左上,最上,上右的顺序,标记此点为四个中的一个。
下面是两种标记算法的VC代码,请大家参考:
#include <list>
#include <vector>
#include <algorithm>
typedef struct tagMarkRegion //连通区域属性结构
{
std::list<POINT> MarkPointList; //点列表
RECT rect;
}MarkRegion;
//定义MarkMap 结构,用来存放等价对
typedef str