分水岭算法VC实现

上传人:大米 文档编号:563654674 上传时间:2023-11-15 格式:DOC 页数:13 大小:170.50KB
返回 下载 相关 举报
分水岭算法VC实现_第1页
第1页 / 共13页
分水岭算法VC实现_第2页
第2页 / 共13页
分水岭算法VC实现_第3页
第3页 / 共13页
分水岭算法VC实现_第4页
第4页 / 共13页
分水岭算法VC实现_第5页
第5页 / 共13页
点击查看更多>>
资源描述

《分水岭算法VC实现》由会员分享,可在线阅读,更多相关《分水岭算法VC实现(13页珍藏版)》请在金锄头文库上搜索。

1、函数名:Watershed功能:用标记-分水岭算法对输入图像进行分割算法实现:无输入参数说明:OriginalImage-输入图像(灰度图,0255)SeedImage-标记图像(二值图,0-非标记,1-标记)LabelImage-输出图像(1-第一个分割区域,2-第二个分割区域,.)row-图像行数col-图像列数无=*/voidWINAPICDib:Watershed(unsignedchar*OriginalImage,char*SeedImage,int*LabelImage,introw,intcol)/usingnamespacestd;/标记区域标识号,从1开始intNum=0;

2、inti,j;/保存每个队列种子个数的数组vectorSeedCounts;/临时种子队列queuequetem;/保存所有标记区域种子队列的数组,里面放的是种子队列的指针vectorqueue*vque;int*array;/指向种子队列的指针queue*pque;POINTtemp;for(i=0;irow;i+)for(j=0;jcol;j+)LabelImageij=0;intm,n,k=0;BOOLup,down,right,left,upleft,upright,downleft,downright;/8directions./预处理,提取区分每个标记区域,并初始化每个标记的种子队

3、列/种子是指标记区域边缘的点,他们可以在水位上升时向外淹没(或者说生长)/panswords:我的理解是梯度值较小的象素点,或者是极小灰度值的点。for(i=0;irow;i+)for(j=0;jcol;j+)/如果找到一个标记区域if(SeedImageij=1)/区域的标识号加一Num+;/分配数组并初始化为零,表示可有256个灰阶array=newint256;ZeroMemory(array,256*sizeof(int);种子个数数组进vector,每次扫描则生成一个数组,并用区域标识号来做第一维。灰度级做第二维。/表示某个盆地区域中某灰阶所对应的点的数目。SeedCounts.pu

4、sh_back(array);/分配本标记号的优先队列,256个种子队列,/表示对应一个灰阶有一个队列,并且每个队列可以存储一个集合的点信息pque=newqueue256;加入到队列数组中,对应的是本标记号Num的vque.push_back(pque);/当前点放入本标记区域的临时种子队列中temp.x=i;temp.y=j;quetem.push(temp);/当前点标记为已处理LabelImageij=Num;Seedlmageij=127;表示已经处理过/让临时种子队列中的种子进行生长直到所有的种子都生长完毕生长完毕后的队列信息保存在vque中,包括区域号和灰阶,对应点数存储在see

5、dcounts中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(m0)/上方若为可生长点则加为新种子if(Seedlmagem-1n=1)temp.x=m-1;temp.y=n;quetem.push(temp);/如果这样的话,那么这些标记过的区域将再次在while

6、循环中被扫描到,不会,因为值是127新种子点标记为已淹没区域,而且是当前区域,并记录区域号到labellmageLabelImagem-1n=Num;Seedlmagem-1n=127;else/否则上方为不可生长up=TRUE;if(m0&n0)if(Seedlmagem-1n-1=1)左上方若为可生长点则加为新种子temp.x=m-1;temp.y=n-1;quetem.push(temp);/新种子点标记为已淹没区域,即下一个循环中以127来标识不再扫描,而且是当前区域Labellmagem-1n-1=Num;Seedlmagem-1n-1=127;else/否则左上方为不可生长uple

7、ft=TRUE;if(mrow-1)if(Seedlmagem+1n=1)下方若为可生长点则加为新种子temp.x=m+1;temp.y=n;quetem.push(temp);/新种子点标记为已淹没区域,而且是当前区域Labellmagem+1n=Num;Seedlmagem+1n=127;else/否则下方为不可生长down=TRUE;if(m(row-1)&n(col-1)if(Seedlmagem+1n+1=1)下方若为可生长点则加为新种子temp.x=m+1;temp.y=n+1;quetem.push(temp);/新种子点标记为已淹没区域,而且是当前区域Labellmagem+1

8、n+1=Num;Seedlmagem+1n+1=127;else/否则下方为不可生长downright=TRUE;if(n0&n(col-1)if(SeedImagem-1n+1=1)右上方若为可生长点则加为新种子temp.x=m-1;temp.y=n+1;quetem.push(temp);/新种子点标记为已淹没区域,而且是当前区域LabelImagem-1n+1=Num;SeedImagem-1n+1=127;else/否则右上方为不可生长upright=TRUE;nvo)宀seed_magem彳)=d氓凶曰妖木汀昌岂凶蛍尊T宀iemp.xHmiiemp.yHn-queiem.pushae

9、mpr,/蛍尊汀跡击凶口番萍冈垃Labe-magm一1一HNUmiseemagem一二27e_se/羽昌卅曰妖木宀TRUEmArowQnvo)宀Seed_mag2m士一二彳二氓凶曰妖木汀昌岂凶蛍尊T宀iemp.xHm+l-iemp.yHn-queiem.pushaempr,/蛍尊汀跡击凶口番萍冈垃Labe-magem+nNum-seemagem十二二27e_se/羽昌卅曰妖木宀down-eftHTRUE/kT卅氓-nfflw汀承曰妖木“-Z卿汀凶甘-尊-丹3/何阳曰羽妖木淞seedimage丹晞册。if(up=dow-l1ghi=-eup-edoweuprighi-downhi)宀iemp.x

10、Hmiiemp.yHP二T何卅遊蜀“usss/mmwhi-e阳亠淞洲汀。/Num是当前的区域号/这样这个二维信息就表示了,某个区域中对应某个灰度级对应的成员点的集合与个数/分别由下面两个量来表达vqueNum-10riginallmagemn.push(temp);这两句中我把Num-1改成了Num.panscodes.SeedCountsNum-1OriginalImagemn+;/while结束,扫描到quetem为空而止。也就是对应所有的节点都得到不可生长为止(或者是周围的点要么不可生长,要么已生长)/if结束/if(Num=5)/return;/在上述过程中,如果标记的点为0则表示,没

11、有扫描到的点,或者表明不是输入的种子点这里相当于是找seedimage传过来的初始区域的分水岭界线的所有的点;并且用标号记录每个区域,同时集水盆的边缘点进入队列。/上面是找集水盆的程序。同时也是连通区域。/*/test这里测试一下剩下的非水盆地的点数。intseednum;for(i=0;irow;i+)for(j=0;jcol;j+)if(Seedlmageij=0)seednum+;CStringstr;str.Format(preregionnum:%d,Num);AfxMessageBox(str);/*/boolactives;/在某一水位处,所有标记的种子生长完的标志intWate

12、rLevel;/淹没过程开始,水位从零开始上升,水位对应灰度级,采用四连通法for(WaterLevel=0;WaterLevel180;WaterLevel+)第二维。actives=true;while(actives)actives=false;/依次处理每个标记号所对应的区域,且这个标记号对应的区域的点的个数在SeedCounts里面for(i=0;i0)SeedCountsiWaterLevel-;/取出一个点,个数少一temp=vqueiWaterLevel.front();取出该区域的一个点,清空这个边缘点,表示当前/灰度级该像素已经处理掉了。vqueiWaterLevel.pop();m=temp.x;n=temp.y;/当前种子的坐标if(m0)if(!La

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号