编程语言
首页 > 编程语言> > 区域生长法的C++实现(opencv)

区域生长法的C++实现(opencv)

作者:互联网

区域生长法的C++实现(opencv)

区域生长法是一种图像分割的常用算法,能够将目标区域精确得分割出来。我的程序是将图像最中央的白色圆形区域提取出来,因此第一个种子点选择在了图像中央。
待处理图片:
待处理的图像
提取结果如下:

处理结果
代码如下:

void AreaGrow(Mat &mat, Mat &growArea)     
//mat为输入图像,growArea为区域生长后的输出图像
{
	//定义第一个种子点位置为图片最中心处	
	int firstSeed_x = mat.cols / 2;
	int firstSeed_y = mat.rows / 2;
	Point firstSeed = Point(firstSeed_x, firstSeed_y);

	growArea = Mat::zeros(mat.size(), CV_8UC1);    //创建一个全黑区域用于存放生长点
	growArea.at<uchar>(firstSeed.x, firstSeed.y) = mat.at<uchar>(firstSeed.x, firstSeed.y);   //为第一个生长点赋值
	Point waitSeed;    //待生长种子点
	int waitSeed_value = 0;    //待生长种子点像素值
	int opp_waitSeed_value = 0;   //mat_thresh中对应待生长种子点处的像素值
	vector<Point> seedVector;     //种子栈
	seedVector.push_back(firstSeed);    //将种子放入栈中最后一个位置
	int direct[8][2] = { {-1,-1}, {0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0} };  //定义8邻域

	while (!seedVector.empty())     //种子栈不为空则生长,即遍历栈中所有元素后停止生长
	{
		Point seed = seedVector.back();     //取出最后一个元素
		seedVector.pop_back();         //删除栈中最后一个元素,防止重复扫描
		for (int i = 0; i < 8; i++)    //遍历种子点的8邻域
		{
			waitSeed.x = seed.x + direct[i][0];    //第i个坐标0行,即x坐标值
			waitSeed.y = seed.y + direct[i][1];    //第i个坐标1行,即y坐标值

			//检查是否是边缘点
			if (waitSeed.x < 0 || waitSeed.y < 0 ||
				waitSeed.x >(mat.cols - 1) || (waitSeed.y > mat.rows - 1))
				continue;

			waitSeed_value = growArea.at<uchar>(waitSeed.x, waitSeed.y);   //为待生长种子点赋对应位置的像素值
			opp_waitSeed_value = mat.at<uchar>(waitSeed.x, waitSeed.y);
			if (waitSeed_value == 0)     //判断waitSeed是否已经被生长,避免重复生长造成死循环
			{
				if (opp_waitSeed_value != 0)     //区域生长条件
				{
					growArea.at<uchar>(waitSeed.x, waitSeed.y) = mat.at<uchar>(waitSeed.x, waitSeed.y);
					seedVector.push_back(waitSeed);    //将满足生长条件的待生长种子点放入种子栈中
				}
			}
		}
	}
}

标签:生长,mat,waitSeed,seedVector,C++,opencv,firstSeed,种子
来源: https://blog.csdn.net/qq_43799400/article/details/115247784