opencv(C++) 连通域分析函数 connectedComponentsWithStats() 用法

文章目录

      • 1、函数用法
      • 2、参数说明
      • 3、例子:只保留图中连通域面积较大的区域

connectedComponentsWithStats() 是一个非常好用的连通域分析函数,可以检测连通域,获取连通域的面积、宽度/高度、质心和左上角顶点坐标等。

1、函数用法

Mat labels;      //CV_32F通道的标签矩阵,不同的连通域被赋予不同的标签值(int类型)
Mat stats;       //包含连通域统计信息的矩阵
Mat centroids;   //连通域的质心坐标矩阵
int num = connectedComponentsWithStats(src, labels, stats, centroids, 8, CV_16U);

2、参数说明

参数src        //输入的检测图,一般为二值图,255为目标,0为背景
返回值num      //连通域数量,第一个(i=0)连通域为黑色背景
int acreage = stats.at<int>(i, CC_STAT_AREA)     //第i个连通域的面积(包含的像素点总数)
int left = stats.at<int>(i, CC_STAT_LEFT)        //第i个连通域的bbox的最左边坐标值
int top = stats.at<int>(i, CC_STAT_TOP)          //第i个连通域的bbox的最上边坐标值
int width= stats.at<int>(i, CC_STAT_WIDTH)       //第i个连通域的宽度
int height stats.at<int>(i, CC_STAT_HEIGHT)      //第i个连通域的高度
double center_x = centroids.at<double>(i, 0)     //第i个连通域的质心x坐标(col)
double center_y = centroids.at<double>(i, 1)     //第i个连通域的质心x坐标(row)

3、例子:只保留图中连通域面积较大的区域

如果我们只想保留二值图中连通域面积大于某个阈值(如100)的区域,有两种思路:

(1)在原图中将不满足条件的连通域的覆盖为黑色。

(2)将满足条件的连通域复制到一张全黑图像上。

具体实现见代码:

//筛选出面积大于100的区域,输入src,输出dst
Mat labels, stats, centroids;   
sizet num = connectedComponentsWithStats(src, labels, stats, centroids, 8, CV_16U);
vector<Vec3b> colors(num);
colors[0] = Vec3b(0, 0, 0);   //第一个连通域是黑色背景

for (sizet i = 1; i != num; i++)
{
	if (stats.at<int>(i, CC_STAT_AREA) > 100)
		colors[i] = Vec3b(255, 255, 255);     //给连通域添加颜色
	else
		colors[i] = Vec3b(0, 0, 0);
}

Mat aimArea = Mat::zeros(src.size(), CV_8UC3);    //注意需要是CV_8UC3的三通道图
for (sizet row = 0; row != src.rows; row++)
	for (sizet col = 0; col != src.cols; col++)
	{
		//获取原图中每个点的label
		sizet label = labels.at<uint16_t>(row, col);
		aimArea.at<Vec3b>(row, col) = colors[label];
	}

Mat dst;
cvtColor(aimArea , dst, COLOR_BGR2GRAY);    //转换为单通道图

你可能感兴趣的:(OpenCv,opencv,c++,图像处理)