基于C++的区域生长法实现
程序员文章站
2024-01-15 23:30:16
...
图像分割是一种重要的数字图像处理技术,生长区域法是选择一个种子点(图像中的某一像素点),对二维图像来言,先遍历种子点的8领域像素或者4领域像素,如果满足一定的条件(例如所要选取的像素范围)则进行生长,并将满足的点当做一个新的种子点,就如一颗种子发芽生长一样,一直到没有种子点停止生长。
区域生长法的算法步骤:
1.选择一个种子点,将种子点push到stack。
2.从stack中取出后存入种子点并pop,遍历该种子点的像素领域,判断遍历的像素是否生长过,如果否则判断是否满足像素的相似条件,如果是,则将该像素点加入到stack.
3.直到没有满足的生长点,即stack为空的时候停止运行。
## 影响算法的要素 ##:
.种子点的选择 2.搜索路径的选择 3.像素的生长条件的判断
how to choose them?
种子点选择:本次测试是根据图像随便选择了一个点
路径的选择:对于二维图像,往往采用8领域搜索或者4领域搜索。
生长条件判断:灰度范围判断或者根据起始种子点与待生长点之间的绝对值之差在某一个范围。
void RegionGrowing::RGA()
{
//8领域像素的生长方向
Point2D pointArray[8] =
{
Point2D(1, -1),
Point2D(1, 0),
Point2D(0, -1),
Point2D(-1, -1),
Point2D(-1, 0),
Point2D(-1, 1),
Point2D(0, 1),
Point2D(1, 1)
};
//将种子点入栈
std::stack<Point2D> pointStack;
pointStack.push(this->seedPoint);
//用OutputData去得到输入的图像,先将OutpuData置为黑色背景
OutputData = Mat::zeros(InputData.size(), CV_8UC1);
//在OutputData中标记生长点为白色
OutputData.at<uchar>(this->seedPoint.y,this->seedPoint.x) = 255;
int initialColor = InputData.at<uchar>(this->seedPoint.y,this->seedPoint.x);
Point2D p;
int growLable = 0;//标记是否生长过
int inputValue = 0;//待生长点的灰度值
int outputValue = 0;//在OutputData的图像中标记满足条件的生长点的灰度值
while (!pointStack.empty())
{
//取得 种子点
Point2D topPoint = pointStack.top();
//从stack中删除该点
pointStack.pop();
//遍历该像素的八领域
for (int i = 0; i < 8; i++)
{
p = topPoint + pointArray[i];//p是待生长点
int x = p.x;
int y = p.y;
// growLable = OutputData.at<uchar>(y,x);
// inputValue=InputData.at<uchar>(y, x);
//图像的边界检测
if ( x<0|| y<0 ||x>(this->InputData.cols-1 )|| y>(this->InputData.rows-1))
{
continue;
}
growLable = OutputData.at<uchar>(y, x);
inputValue = InputData.at<uchar>(y, x);
//次点未生长且待生长点与第一个种子点的灰度差的绝对值小于10则生长
if (growLable == 0 && abs(inputValue - initialColor) < 30)
{
outputValue = OutputData.at<uchar>(y, x) = 165;//用灰色表示生长
//将此点入栈
pointStack.push(p);
}
}
}
}