分水岭算法VC实现Word格式.docx
- 文档编号:6314394
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:14
- 大小:18.87KB
分水岭算法VC实现Word格式.docx
《分水岭算法VC实现Word格式.docx》由会员分享,可在线阅读,更多相关《分水岭算法VC实现Word格式.docx(14页珍藏版)》请在冰点文库上搜索。
//标记区域标识号,从1开始
intNum=0;
inti,j;
//保存每个队列种子个数的数组
vector<
int*>
SeedCounts;
//临时种子队列
queue<
POINT>
quetem;
//保存所有标记区域种子队列的数组,里面放的是种子队列的指针
*>
vque;
int*array;
//指向种子队列的指针
*pque;
POINTtemp;
for(i=0;
i<
row;
i++)
for(j=0;
j<
col;
j++)
LabelImage[i][j]=0;
}
intm,n,k=0;
BOOLup,down,right,left,upleft,upright,downleft,downright;
//8directions...
//预处理,提取区分每个标记区域,并初始化每个标记的种子队列
//种子是指标记区域边缘的点,他们可以在水位上升时向外淹没(或者说生长)
//pan'
swords:
我的理解是梯度值较小的象素点,或者是极小灰度值的点。
{
//如果找到一个标记区域
if(SeedImage[i][j]==1)
//区域的标识号加一
Num++;
//分配数组并初始化为零,表示可有256个灰阶
array=newint[256];
ZeroMemory(array,256*sizeof(int));
//种子个数数组进vector,每次扫描则生成一个数组,并用区域标识号来做第一维。
灰度级做第二维。
//表示某个盆地区域中某灰阶所对应的点的数目。
SeedCounts.push_back(array);
//分配本标记号的优先队列,256个种子队列,
//表示对应一个灰阶有一个队列,并且每个队列可以存储一个集合的点信息
pque=newqueue<
[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;
//如果这样的话,那么这些标记过的区域将再次在while循环中被扫描到,不会,因为值是127
//新种子点标记为已淹没区域,而且是当前区域,并记录区域号到labelImage
LabelImage[m-1][n]=Num;
SeedImage[m-1][n]=127;
}
else//否则上方为不可生长
up=TRUE;
0&
&
n>
if(SeedImage[m-1][n-1]==1)//左上方若为可生长点则加为新种子
temp.y=n-1;
//新种子点标记为已淹没区域,即下一个循环中以127来标识不再扫描,而且是当前区域
LabelImage[m-1][n-1]=Num;
SeedImage[m-1][n-1]=127;
else//否则左上方为不可生长
upleft=TRUE;
if(m<
row-1)
if(SeedImage[m+1][n]==1)//下方若为可生长点则加为新种子
temp.x=m+1;
//新种子点标记为已淹没区域,而且是当前区域
LabelImage[m+1][n]=Num;
SeedImage[m+1][n]=127;
else//否则下方为不可生长
down=TRUE;
(row-1)&
n<
(col-1))
if(SeedImage[m+1][n+1]==1)//下方若为可生长点则加为新种子
temp.y=n+1;
LabelImage[m+1][n+1]=Num;
SeedImage[m+1][n+1]=127;
downright=TRUE;
if(n<
col-1)
if(SeedImage[m][n+1]==1)//右方若为可生长点则加为新种子
temp.x=m;
LabelImage[m][n+1]=Num;
SeedImage[m][n+1]=127;
else//否则右方为不可生长
right=TRUE;
if(SeedImage[m-1][n+1]==1)//右上方若为可生长点则加为新种子
LabelImage[m-1][n+1]=Num;
SeedImage[m-1][n+1]=127;
else//否则右上方为不可生长
upright=TRUE;
if(n>
if(SeedImage[m][n-1]==1)//左方若为可生长点则加为新种子
//新种子点标记为已淹没区域
LabelImage[m][n-1]=Num;
SeedImage[m][n-1]=127;
else//否则左方为不可生长
left=TRUE;
if(SeedImage[m+1][n-1]==1)//左下方若为可生长点则加为新种子
LabelImage[m+1][n-1]=Num;
SeedImage[m+1][n-1]=127;
downleft=TRUE;
//上下左右只要有一点不可生长,那么本点为初始种子队列中的一个
//这里可否生长是由seedimage中的值来决定的。
if(up||down||right||left||
upleft||downleft||upright||downright)
//下面这个矢量数组:
第一维是标记号;
第二维是该图像点的灰度级
//m,n点对应的是while循环里面扫描的像素点。
//Num是当前的区域号
//这样这个二维信息就表示了,某个区域中对应某个灰度级对应的成员点的集合与个数
//分别由下面两个量来表达
vque[Num-1][OriginalImage[m][n]].push(temp);
//这两句中我把Num-1改成了Num...pan'
scodes...
SeedCounts[Num-1][OriginalImage[m][n]]++;
}
}//while结束,扫描到quetem为空而止。
也就是对应所有的节点都得到不可生长为止(或者是周围的点要么不可生长,要么已生长)
}//if结束
//if(Num==5)
//return;
//在上述过程中,如果标记的点为0则表示,没有扫描到的点,或者表明不是输入的种子点
//这里相当于是找seedimage传过来的初始区域的分水岭界线的所有的点;
并且用标号记录每个区域,同时集水盆的边缘点进入队列。
//上面是找集水盆的程序。
同时也是连通区域。
/*************************************/
//test这里测试一下剩下的非水盆地的点数。
intseednum;
if(SeedImage[i][j]==0)
seednum++;
CStringstr;
str.Format("
preregionnum:
%d"
Num);
AfxMessageBox(str);
boolactives;
//在某一水位处,所有标记的种子生长完的标志
intWaterLevel;
//淹没过程开始,水位从零开始上升,水位对应灰度级,采用四连通法
for(WaterLevel=0;
WaterLevel<
180;
WaterLevel++)//第二维。
。
actives=true;
while(actives)
actives=false;
//依次处理每个标记号所对应的区域,且这个标记号对应的区域的点的个数在SeedCounts里面
for(i=0;
Num;
i++)//第一维。
if(!
vque[i][WaterLevel].empty())//对应的分水岭不为空集,i表示区域号,waterlevel表示灰阶
while(SeedCounts[i][WaterLevel]>
SeedCounts[i][WaterLevel]--;
//取出一个点,个数少一
temp=vque[i][WaterLevel].front();
//取出该区域的一个点,清空这个边缘点,表示当前
//灰度级该像素已经处理掉了。
vque[i][WaterLevel].pop();
m=temp.x;
n=temp.y;
//当前种子的坐标
LabelImage[m-1][n])//上方若未处理,表示没有标号,应该在输入前已经作过初始化为0
//本函数中在开头也作过初始化
LabelImage[m-1][n]=i+1;
//上方点标记为已淹没区域
//注意到这个标记是与扫描点的区域号相同,一定在这个标号所属的区域吗?
是的
//这样在下一轮至少会扫描到这个点,确保不遗漏,但是下一轮的处理会使它合理
//归类吗?
问题还有这样标记并没有一定将它加入到种子队列。
也就是说它
//只是被淹没而不能向上淹没。
只有满足下述可生长条件才行。
if(OriginalImage[m-1][n]<
=WaterLevel)//上方若为可生长点则加入当前队列,当前高度的队列
vque[i][WaterLevel].push(temp);
else//否则加入OriginalImage[m-1][n]对应的灰度级的队列,为什么?
vque[i][OriginalImage[m-1][n]].push(temp);
SeedCounts[i][OriginalImage[m-1][n]]++;
LabelImage[m+1][n])//下方若未处理
LabelImage[m+1][n]=i+1;
//下方点标记为已淹没区域
if(OriginalImage[m+1][n]<
=WaterLevel)//下方若为可生长点则加入当前队列
else//否则加入OriginalImage[m+1][n]级队列
vque[i][OriginalImage[m+1][n]].push(temp);
SeedCounts[i][OriginalImage[m+1][n]]++;
LabelImage[m][n+1])//右边若未处理
LabelImage[m][n+1]=i+1;
//右边点标记为已淹没区域
if(OriginalImage[m][n+1]<
=WaterLevel)//右边若为可生长点则加入当前队列
else//否则加入OriginalImage[m][n+1]级队列
vque[i][OriginalImage[m][n+1]].push(temp);
SeedCounts[i][OriginalImage[m][n+1]]++;
LabelImage[m][n-1])//左边若未处理
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 分水岭 算法 VC 实现
![提示](https://static.bingdoc.com/images/bang_tan.gif)