连通域与相距变换

目录

1、连通域

1.1 连通域分割原理

1.2 连通域分割函数

2、相距变换

2.1 像素间距离

2.2 距离变换函数


1、连通域

   

//连通域
int test1()
{
	//对图像进行距离变换
	Mat img = imread("F:/testMap/rice.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat rice, riceBW;

	//将图像转成二值图像,用于统计连通域
	cvtColor(img, rice, COLOR_BGR2GRAY);//先转为灰度图
	threshold(rice, riceBW, 50, 255, THRESH_BINARY);//再二值化

	//生成随机颜色,用于区分不同连通域
    //RNG类是opencv里C++的随机数产生器。它可产生一个64位的int随机数。
	//目前可按均匀分布和高斯分布产生随机数。
	RNG rng(10086);
	Mat out;

	int number = connectedComponents(riceBW, out, 8, CV_16U);//统计图像中连通域的个数
	vector<Vec3b> colors;
	for (int i = 0; i < number; i++)
	{
		//使用均匀分布的随机数确定颜色
		Vec3b vec3 = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
		colors.push_back(vec3);

		//以不同颜色标记出不同的连通域
		Mat result = Mat::zeros(rice.size(), img.type());
		int w = result.cols;
		int h = result.rows;
		for (int row = 0; row < h; row++)
		{
			for (int col = 0; col < w; col++)
			{
				int label = out.at<uint16_t>(row, col);
				if (label == 0)//背景的黑色不改变
				{
					continue;
				}
				result.at<Vec3b>(row, col) = colors[label];
			}
		}

		//显示结果
		imshow("原图", img);
		imshow("标记后的图像", result);
		cout << "接下来统计连通域信息" << endl;
		waitKey(0);

		Mat stats, centroids;

		number = connectedComponentsWithStats(riceBW, out, stats, centroids, 8, CV_16U);
		vector<Vec3b> colors_new;
		for (int i = 0; i < number; i++)
		{
			//使用均匀分布的随机数确定颜色
			Vec3b vec3 = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
			colors_new.push_back(vec3);
		}

		//以不同颜色标记出不同的连通域
		for (int i = 1; i < number; i++)
		{
			//中心位置
			int center_x = centroids.at<double>(i, 0);
			int center_y = centroids.at<double>(i, 1);

			//矩形边框
			int x = stats.at<int>(i, CC_STAT_LEFT);
			int y = stats.at<int>(i, CC_STAT_TOP);
			int w = stats.at<int>(i, CC_STAT_WIDTH);
			int h = stats.at<int>(i, CC_STAT_HEIGHT);
			int area = stats.at<int>(i, CC_STAT_AREA);

			//中心位置绘制
			circle(img, Point(center_x, center_y), 2, Scalar(0, 255, 0), 2, 8, 0);

			//外接矩形
			Rect rect(x, y, w, h);
			rectangle(img, rect, colors_new[i], 1, 8, 0);
			putText(img, format("%d", i), Point(center_x, center_y), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1);
			cout << "number: " << i << " , area: " << area << endl;
		}
		//显示结果
		imshow("标记后的图像", img);

		waitKey(0);
		return 0;
	}
}

1.1 连通域分割原理

1.2 连通域分割函数

 

2、相距变换

2.1 像素间距离

2.2 距离变换函数

//图像距离变换
int test2()
{
	//构建建议矩阵,用于求取像素之间的距离
	Mat a = (Mat_<uchar>(5, 5) << 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1,
		1, 1, 0, 1, 1,
		1, 1, 1, 1, 1,
		1, 1, 1, 1, 1);

	Mat dist_L1, dist_L2, dist_C, dist_L12;

	//计算街区距离
	distanceTransform(a, dist_L1, 1, 3, CV_8U);
	cout << "街区距离:" << endl << dist_L1 << endl;

	//计算欧式距离
	distanceTransform(a, dist_L2, 2, 5, CV_8U);
	cout << "欧式距离:" << endl << dist_L2 << endl;

	//计算棋盘距离
	distanceTransform(a, dist_C, 3, 5, CV_8U);
	cout << "棋盘距离:" << endl << dist_C << endl;

	cout << "对图像进行距离变换" << endl; waitKey(0);

	Mat rice = imread("F:/testMap/rice.png", IMREAD_GRAYSCALE);
	if (rice.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat riceBW, riceBW_INV;

	//将图像转成二值图像,同时把黑白区域颜色互换
	threshold(rice, riceBW, 50, 255, THRESH_BINARY);
	threshold(rice, riceBW_INV, 50, 255, THRESH_BINARY_INV);

	//距离变换
	Mat dist, dist_INV;
	distanceTransform(riceBW, dist, 1, 3, CV_32F);

	//为了显示清晰,将数据类型变成	CV_32F
	distanceTransform(riceBW_INV, dist_INV, 1, 3, CV_8U);

	//显示变换结果
	imshow("riceBW", riceBW);
	imshow("dist", dist);
	imshow("riceBW_INV", riceBW_INV);
	imshow("dist_INV", dist_INV);

	waitKey(0);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhang丶&|!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值