您的位置:首页 > 其它

图像中区域生长算法的详解和实现

2016-01-27 21:27 417 查看

区域生长算法的基本思想是将有相似性质的像素点合并到一起。对每一个区域要先指定一个种子点作为生长的起点,然后将种子点周围领域的像素点和种子点进行对比,将具有相似性质的点合并起来继续向外生长,直到没有满足条件的像素被包括进来为止。这样一个区域的生长就完成了。这个过程中有几个关键的问题:

1 给定种子点(种子点如何选取?)

种子点的选取很多时候都采用人工交互的方法实现,也有用其他方式的,比如寻找物体并提取物体内部点或者利用其它算法找到的特征点作为种子点。

2 确定在生长过程中能将相邻像素包括进来的准则

这个准则很重要:例如包括灰度值的差值;彩色图像的颜色;梯度特征,包括梯度的方向和幅值特征。该点周围的区域特征,例如harr特征,也就是区域像素和特征。

举个例子:发在PAMI上的LSD直线检测算法中的关键一步就是找line support regions.这个区域的查找就是利用区域生长法则,生长的条件就是梯度的方向角度。



#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <vector>
#include <stack>

using namespace std;
using namespace cv;

void regiongrowth(IplImage* &inputimg,IplImage* &outputimg,CvPoint pt,int th)
{

CvPoint ptGrowing;//待生长点的位置
int nGrowLabel=0;//是否被标记
int nScrValue=0;//生长起始点的灰度值
int nCurValue=0;//当前生长点的灰度值

IplImage* Dstimg=cvCreateImage(cvGetSize(inputimg),8,1);
if (Dstimg==NULL)
{
printf("image read error too");
return;
}
cvZero(Dstimg);

int DIR[8][2]={{-1,-1}, {0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}};

vector<CvPoint>vcGrowpt;//生长点的堆栈
vcGrowpt.push_back(pt);//将初始生长点压入堆栈

//标记初始生长点
Dstimg->imageData[pt.x+pt.y*Dstimg->widthStep]=255;
nScrValue=inputimg->imageData[pt.x+pt.y*inputimg->widthStep];

while(!vcGrowpt.empty())
{
CvPoint curpt=vcGrowpt.back();//在堆栈中取出一个生长点
vcGrowpt.pop_back();

for(int i=0;i<8;i++)
{
ptGrowing.x=curpt.x+DIR[i][0];
ptGrowing.y=curpt.y+DIR[i][1];
//检查边缘点
if(ptGrowing.x<0||ptGrowing.y<0||(ptGrowing.x>inputimg->width-1)||(ptGrowing.y>inputimg->height-1))
continue;
nGrowLabel=Dstimg->imageData[ptGrowing.x+ptGrowing.y*Dstimg->widthStep];
if (nGrowLabel==0)//表示还未标记过
{
nCurValue=inputimg->imageData[ptGrowing.x+ptGrowing.y*inputimg->widthStep];
if(abs(nCurValue-nScrValue)<=th)
{
Dstimg->imageData[ptGrowing.x+ptGrowing.y*Dstimg->widthStep]=255;
vcGrowpt.push_back(ptGrowing);

}
}

}

}
cvCopy(Dstimg,outputimg);
cvReleaseImage(&Dstimg);

}

int _tmain(int argc, _TCHAR* argv[])
{

IplImage* sourceimage=cvLoadImage("H:\\programm\\test.jpg",0);

if (sourceimage==NULL)
{
printf("image read error");
}

IplImage* outputimg=cvCreateImage(cvGetSize(sourceimage),8,1);
IplImage* resultimg=cvCreateImage(cvGetSize(sourceimage),8,1);
cvZero(resultimg);
cvCopy(sourceimage,outputimg);
regiongrowth(sourceimage,outputimg,cvPoint(392,282),12);
cvAdd(outputimg,resultimg,resultimg);

regiongrowth(sourceimage,outputimg,cvPoint(587,195),8);
cvAdd(outputimg,resultimg,resultimg);

regiongrowth(sourceimage,outputimg,cvPoint(707,356),8);
cvAdd(outputimg,resultimg,resultimg);

regiongrowth(sourceimage,outputimg,cvPoint(546,549),10);
cvAdd(outputimg,resultimg,resultimg);

regiongrowth(sourceimage,outputimg,cvPoint(310,435),10);
cvAdd(outputimg,resultimg,resultimg);

cvNamedWindow("source",0);
cvShowImage("source",sourceimage);

cvNamedWindow("result",0);
cvShowImage("result",resultimg);
cvWaitKey(0);

cvReleaseImage(&sourceimage);
cvReleaseImage(&outputimg);
cvReleaseImage(&resultimg);
system("pause");
return 0;
}


View Code
[b]这个代码实现结果,就是提取下面左图中的5个区域,右边为提取结果,由于用的是灰度差作为生长条件,效果一般般。






参考文章:http://blog.csdn.net/robin__chou/article/details/50071313
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: