图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找出彼此互相独立的连通域并将其标记出来。提取图像中不同的连通域是图像处理中较为常用的方法,例如在车牌识别、文字识别、目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二值化后的图像。
邻域即相邻得区域,opencv中有以下两种形式得领域
4-邻域:必须在水平和垂直方向上相邻,相邻的两个像素坐标必须只有一位不同而且只能相差1个像素
8-邻域: 九宫格形式,相邻的两个像素坐标必须只有一位不同而且只能相差1个像素
图示如下:
两遍扫描法会遍历两次图像,第一次遍历图像时会给每一个非0像素赋予一个数字标签,当某个像素的上方和左侧邻域内的像素已经有数字标签时,取两者中的最小值作为当前像素的标签,否则赋予当前像素一个新的数字标签。第一次遍历图像的时候同一个连通域可能会被赋予一个或者多个不同的标签
首先将所有非0像素放到一个集合中,之后在集合中随机选出一个像素作为种子像素,根据邻域关系不断扩充种子像素所在的连通域,并在集合中删除掉扩充出的像素,直到种子像素所在的连通域无法扩充,之后再从集合中随机选取一个像素作为新的种子像素,重复上述过程直到集合中没有像素(类似DFS)
此处的OutputArray labels是不能直接imshow的,需要进行相应的转换,才能正常显示
int connectedComponents(InputArray image, OutputArray labels,int connectivity = 8, int ltype = CV_32S);
/*******************************************************************
* image: 输入二值图像
* labels: 输出图像
* connectivity: 邻域
* ltype: 输出图深度
*********************************************************************/
int connectedComponentsWithStats(InputArray image, OutputArray labels, OutputArray stats, OutputArray centroids,int connectivity, int ltype, int ccltype);
/*******************************************************************
* image: 输入二值图像
* labels: 输出图像
* stats: 统计信息,包括每个组件的位置、宽、高与面积
* centroids: 每个组件的中心位置坐标cx, cy
* connectivity: 邻域
* ltype: 输出图深度
* ccltype: 连通组件算法
*********************************************************************/
//ccltype取值
enum ConnectedComponentsTypes {
CC_STAT_LEFT = 0, // 组件的左上角点像素点坐标的X位置
CC_STAT_TOP = 1, // 组件的左上角点像素点坐标的Y位置
CC_STAT_WIDTH = 2, // 组件外接矩形的宽度
CC_STAT_HEIGHT = 3, // 组件外接矩形的高度
CC_STAT_AREA = 4, // 当前连通组件的面积(像素单位)
CC_STAT_MAX = 5 // 最大枚举值,仅在内部用于内存分配(可忽略)
};
注意at函数通过宏的设置获取Mat的一系列的属性(x,y,width,height)
#include
#include
#include
#include