区域生长法的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