分水岭算法VC实现_第1页
分水岭算法VC实现_第2页
分水岭算法VC实现_第3页
分水岭算法VC实现_第4页
分水岭算法VC实现_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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.po

13、p();m=temp.x;n=temp.y;/当前种子的坐标if(m0)if(!Labellmagem-1n)上方若未处理,表示没有标号,应该在输入前已经作过初始化为0/本函数中在开头也作过初始化temp.x=m-1;temp.y=n;LabelImagem-1n=i+1;上方点标记为已淹没区域/注意到这个标记是与扫描点的区域号相同,一定在这个标号所属的区域吗?是的/这样在下一轮至少会扫描到这个点,确保不遗漏,但是下一轮的处理会使它合理/归类吗?问题还有这样标记并没有一定将它加入到种子队列。也就是说它/只是被淹没而不能向上淹没。只有满足下述可生长条件才行。if(Originallmagem-1

14、n=WaterLevel)上方若为可生长点则加入当前队列,当前高度的队列vqueiWaterLevel.push(temp);else/否则加入Originallmagem-1n对应的灰度级的队列,为什么?vqueiOriginallmagem-1n.push(temp);SeedCountsiOriginallmagem-1n+;if(mrow-1)if(!Labellmagem+1n)下方若未处理temp.x=m+1;temp.y=n;LabelImagem+1n=i+1;下方点标记为已淹没区域if(Originallmagem+1n=WaterLevel)下方若为可生长点则加入当前队列v

15、queiWaterLevel.push(temp);else/否则加入Originallmagem+1n级队列vqueiOriginallmagem+1n.push(temp);SeedCountsiOriginallmagem+1n+;if(ncol-1)if(!Labellmagemn+1)右边若未处理temp.x=m;temp.y=n+1;Labellmagemn+1=i+1;右边点标记为已淹没区域if(Originallmagemn+10)if(!LabelImagemn-1)左边若未处理temp.x=m;temp.y=n-1;Labellmagemn-1=i+1;左边点标记为已淹没区

16、域if(Originallmagemn-1=WaterLevel)左边若为可生长点则加入当前队列vqueiWaterLevel.push(temp);else/否则加入Originallmagemn-1级队列vqueiOriginalImagemn-1.push(temp);SeedCountsiOriginalImagemn-1+;/while循环结束SeedCountsiWaterLevel=vqueiWaterLevel.size();/if结束/for循环结束/while循环结束/for循环结束/*/testwhethertheorigionalsegmentationnumischa

17、nonzeronum=Num;for(m=0;mNum;m+)for(i=0;irow;i+)for(j=0;jcol;j+)if(LabelImageij=m)break;if(LabelImageij=m)break;if(j=col-1&i=row-1&LabelImageij!=m)nonzeronum-;str.Format(”newregionnum:%d,nonzeronum);这表示的是可扩张的点AfxMessageBox(str);/*/while(!vque.empty()pque=vque.back();deletepque;vque.pop_back()

18、;while(!SeedCounts.empty()array=SeedCounts.back();deletearray;SeedCounts.pop_back();/在主程序中的调用代码如下(用于处理8位图)/getoneimage.CAPCountMDoc*pDoc=GetDocument();HDIBm_hDIBOptFlo=OnReadimage();/HDIB是Dib图像句柄LPSTRlpDIB2=(LPSTR):GlobalLock(HGLOBAL)m_hDIBOptFlo);intm_imageH=viewdib.DIBHeight(lpDIB2);intm_imageW=vi

19、ewdib.DIBWidth(lpDIB2);/viewdib.MedianFilter(lpDIB2,m_imageW,m_imageH,3,3,1,1);/filterLPSTRlpDIBBits=viewdib.FindDIBBits(lpDIB2);DWORDDWidth=WIDTHBYTES(m_imageW*8);/watershed.LPSTRlpDIBG=viewdib.MakeGray8Bmp(lpDIB2);lpDIBG=viewdib.GetGrad(lpDIBG);LPSTRlpDIBBitsG=viewdib.FindDIBBits(lpDIBG);inti,k,num=0;intm=0,n=0;/getoritionalimageunsignedchar*ori_image;ori_image=alloc_uszchar_space(m_imageH,m_imageW);for(i=0;im_imageH;i+)for(k=0;km_imageW;k+)ori_imageik=*(lpDIBBitsG+i*DWidth+k);/getseedimagean

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论