资源简介
图像分割经典算法分水岭图像分割算法 c++实现 很好用
代码片段和文件信息
//算法实现代码如下
/*====================================================================
函数名: Watershed
功能: 用标记-分水岭算法对输入图像进行分割
算法实现: 无
输入参数说明: OriginalImage --输入图像(灰度图,0~255)
SeedImage --标记图像(二值图,0-非标记,1-标记)
LabelImage --输出图像(1-第一个分割区域,2-第二个分割区域,...)
row --图像行数
col --图像列数
返回值说明: 无
====================================================================*/
void WINAPI CDib::Watershed(unsigned char **OriginalImage char** SeedImage int **LabelImage int row int col)
{
// using namespace std;
//标记区域标识号,从1开始
int Num=0;
int ij;
//保存每个队列种子个数的数组
vector SeedCounts;
//临时种子队列
queue quetem;
//保存所有标记区域种子队列的数组,里面放的是种子队列的指针
vector*> vque;
int* array;
//指向种子队列的指针
queue *pque;
POINT temp;
for(i=0;i
{
for(j=0;j LabelImage[i][j]=0;
}
int mnk=0;
BOOL updownrightleftupleftuprightdownleftdownright;//8 directions...
//预处理提取区分每个标记区域,并初始化每个标记的种子队列
//种子是指标记区域边缘的点,他们可以在水位上升时向外淹没(或者说生长)
//pan‘s words:我的理解是梯度值较小的象素点,或者是极小灰度值的点。
for(i=0;i
{
for(j=0;j {
//如果找到一个标记区域
if(SeedImage[i][j]==1)
{
//区域的标识号加一
Num++;
//分配数组并初始化为零,表示可有256个灰阶
array=new int[256];
ZeroMemory(array256*sizeof(int));
//种子个数数组进vector,每次扫描则生成一个数组,并用区域标识号来做第一维。灰度级做第二维。
//表示某个盆地区域中某灰阶所对应的点的数目。
SeedCounts.push_back(array);
//分配本标记号的优先队列,256个种子队列,
//表示对应一个灰阶有一个队列,并且每个队列可以存储一个集合的点信息
pque=new queue[256];
//加入到队列数组中,对应的是本标记号Num的
vque.push_back(pque);
//当前点放入本标记区域的临时种子队列中
temp.x=i;
temp.y=j;
quetem.push(temp);
//当前点标记为已处理
LabelImage[i][j]=Num;
SeedImage[i][j]=127;//表示已经处理过
//让临时种子队列中的种子进行生长直到所有的种子都生长完毕
//生长完毕后的队列信息保存在vque中,包括区域号和灰阶,对应点数存储在seedcounts中
while(!quetem.empty())
{
up=down=right=left=FALSE;
upleft=upright=downleft=downright=FALSE;
//队列中取出一个种子
temp=quetem.front();
m=temp.x;
n=temp.y;
quetem.pop();
//注意到127对扫描过程的影响,影响下面的比较,但是不影响while语句中的扫描
if(m>0)
{
//上方若为可生长点则加为新种子
if(SeedImage[m-1][n]==1)
{
temp.x=m-1;
temp.y=n;
quetem.push(temp);//如果这样的话,那么这些标记过的区域将再次在while循环中被扫描到,不会,因为值是127
//新种子点标记为已淹没区域,而且是当前区域,并记录区域号到labelImage
LabelImage[m-1][n]=Num;
SeedImage[m-1][n]=127;
}
else//否则上方为不可生长
{
up=TRUE;
}
}
if(m>0&&n>0)
{
if(SeedImage[m-1][n-1]==1)//左上方若为可生长点则加为新种子
{
temp.x=m-1;
temp.y=n-1;
quetem.push(temp);
//新种子点标记为已淹没区域,即下一个循环中以127来标识不再扫描,而且是当前区域
LabelImage[m-1][n-1]=Num;
SeedImage[m-1][n-1]=127;
}
else//否则左上方为不可生长
{
upleft=TRUE;
}
}
if(m {
if(SeedIm
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 13560 2007-04-06 16:05 实现分水岭图像分割\watershed\watershed.cpp
文件 103936 2007-04-06 16:03 实现分水岭图像分割\watershed\watershed.doc
文件 3437 2008-10-08 20:50 实现分水岭图像分割\watershed\watershed.dsp
文件 50176 2009-12-21 20:01 实现分水岭图像分割\watershed\watershed.ncb
文件 541 2008-10-08 20:50 实现分水岭图像分割\watershed\watershed.dsw
文件 36864 2009-12-21 19:59 实现分水岭图像分割\watershed\Debug\vc60.pdb
文件 33792 2009-12-21 19:59 实现分水岭图像分割\watershed\Debug\vc60.idb
文件 186988 2009-12-21 19:59 实现分水岭图像分割\watershed\Debug\watershed.pch
文件 1816 2009-12-21 19:59 实现分水岭图像分割\watershed\watershed.plg
文件 53760 2009-12-21 20:01 实现分水岭图像分割\watershed\watershed.opt
目录 0 2009-03-04 09:52 实现分水岭图像分割\watershed\Debug
目录 0 2009-03-04 09:52 实现分水岭图像分割\watershed
目录 0 2009-12-21 19:59 实现分水岭图像分割
----------- --------- ---------- ----- ----
484870 13
评论
共有 条评论