分水岭算法vc实现

上传人:ldj****22 文档编号:40361991 上传时间:2018-05-26 格式:DOC 页数:11 大小:52KB
返回 下载 相关 举报
分水岭算法vc实现_第1页
第1页 / 共11页
分水岭算法vc实现_第2页
第2页 / 共11页
分水岭算法vc实现_第3页
第3页 / 共11页
分水岭算法vc实现_第4页
第4页 / 共11页
分水岭算法vc实现_第5页
第5页 / 共11页
点击查看更多>>
资源描述

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

1、函数名: Watershed功能: 用标记-分水岭算法对输入图像进行分割算法实现: 无输入参数说明: OriginalImage -输入图像(灰度图,0255)SeedImage -标记图像(二值图,0-非标记,1-标记)LabelImage -输出图像(1-第一个分割区域,2-第二个分割区域,.)row -图像行数col -图像列数返回值说明: 无 =*/void WINAPI CDib:Watershed(unsigned char *OriginalImage, char* SeedImage, int *LabelImage, int row, int col)/ using name

2、space std;/标记区域标识号,从 1 开始int Num=0;int i,j;/保存每个队列种子个数的数组vector SeedCounts;/临时种子队列queue quetem;/保存所有标记区域种子队列的数组,里面放的是种子队列的指针vector* vque;int* array;/指向种子队列的指针queue *pque;POINT temp;for(i=0;i256;/加入到队列数组中,对应的是本标记号 Num 的vque.push_back(pque);/当前点放入本标记区域的临时种子队列中temp.x=i;temp.y=j;quetem.push(temp);/当前点标记

3、为已处理LabelImageij=Num;SeedImageij=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 对扫描过程的影响,影响下面的比较,但是不

4、影响 while 语句中的扫描if(m0)/上方若为可生长点则加为新种子if(SeedImagem-1n=1)temp.x=m-1;temp.y=n;quetem.push(temp);/如果这样的话,那么这些标记过的区域将再次在 while 循环中被扫描到,不会,因为值是 127/新种子点标记为已淹没区域,而且是当前区域,并记录区域号到 labelImageLabelImagem-1n=Num;SeedImagem-1n=127;else/否则上方为不可生长up=TRUE;if(m0temp.y=n-1;quetem.push(temp);/新种子点标记为已淹没区域,即下一个循环中以 127

5、 来标识不再扫描,而且是当前区域LabelImagem-1n-1=Num;SeedImagem-1n-1=127;else/否则左上方为不可生长upleft=TRUE;if(m0temp.y=n-1;quetem.push(temp);/新种子点标记为已淹没区域LabelImagemn-1=Num;SeedImagemn-1=127;else/否则左方为不可生长left=TRUE;if(m0)if(SeedImagem+1n-1=1)/左下方若为可生长点则加为新种子temp.x=m+1;temp.y=n-1;quetem.push(temp);/新种子点标记为已淹没区域LabelImagem+

6、1n-1=Num;SeedImagem+1n-1=127;else/否则左方为不可生长downleft=TRUE;/上下左右只要有一点不可生长,那么本点为初始种子队列中的一个/这里可否生长是由 seedimage 中的值来决定的。if(up|down|right|left|upleft|downleft|upright|downright)temp.x=m;temp.y=n;/下面这个矢量数组:第一维是标记号;第二维是该图像点的灰度级/m,n 点对应的是 while 循环里面扫描的像素点。/Num 是当前的区域号/这样这个二维信息就表示了,某个区域中对应某个灰度级对应的成员点的集合与个数/分别

7、由下面两个量来表达vqueNum-1OriginalImagemn.push(temp);/这两句中我把 Num-1 改成了 Num.pans codes.SeedCountsNum-1OriginalImagemn+; /while 结束,扫描到 quetem 为空而止。也就是对应所有的节点都得到不可生长为止(或者是周围的点要么不可生长,要么已生长)/if 结束/ if(Num=5)/ return;/在上述过程中,如果标记的点为 0 则表示,没有扫描到的点,或者表明不是输入的种子点/这里相当于是找 seedimage 传过来的初始区域的分水岭界线的所有的点;并且用标号记录每个区域,同时集水

8、盆的边缘点进入队列。/上面是找集水盆的程序。同时也是连通区域。/*/test 这里测试一下剩下的非水盆地的点数。int seednum;for(i=0;i0)SeedCountsiWaterLevel-;/取出一个点,个数少一temp=vqueiWaterLevel.front();/取出该区域的一个点,清空这个边缘点,表示当前/灰度级该像素已经处理掉了。vqueiWaterLevel.pop();m = temp.x;n = temp.y;/当前种子的坐标if(m0)if(!LabelImagem-1n)/上方若未处理,表示没有标号,应该在输入前已经作过初始化为 0/本函数中在开头也作过初始

9、化temp.x=m-1;temp.y=n;LabelImagem-1n=i+1;/上方点标记为已淹没区域/注意到这个标记是与扫描点的区域号相同,一定在这个标号所属的区域吗?是的/这样在下一轮至少会扫描到这个点,确保不遗漏,但是下一轮的处理会使它合理/归类吗?问题还有这样标记并没有一定将它加入到种子队列。也就是说它/只是被淹没而不能向上淹没。只有满足下述可生长条件才行。if(OriginalImagem-1n0)if(!LabelImagemn-1)/左边若未处理temp.x=m;temp.y=n-1;LabelImagemn-1=i+1;/左边点标记为已淹没区域if(OriginalImage

10、mn-1=WaterLevel)/左边若为可生长点则加入当前队列vqueiWaterLevel.push(temp);else/否则加入 OriginalImagemn-1级队列vqueiOriginalImagemn-1.push(temp);SeedCountsiOriginalImagemn-1+;/while 循环结束SeedCountsiWaterLevel=vqueiWaterLevel.size();/if 结束/for 循环结束/while 循环结束/for 循环结束/*/test whether the origional segmentation num is change

11、d.int 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 str.Format(“new region num:%d“,nonzeronum);/这表示的是可扩张的点AfxMessageBox(str);/*/while(!vque.empty()pque=vque.back();delete pque;vque.pop_back();while(!SeedCounts.empty()array=S

12、eedCounts.back();delete array;SeedCounts.pop_back();/在主程序中的调用代码如下(用于处理 8 位图)/*/get one image.CAPCountMDoc *pDoc=GetDocument();HDIB m_hDIBOptFlo=OnReadimage();/HDIB 是 Dib 图像句柄LPSTR lpDIB2 = (LPSTR) :GlobalLock(HGLOBAL) m_hDIBOptFlo);int m_imageH = viewdib.DIBHeight(lpDIB2);int m_imageW = viewdib.DIBW

13、idth(lpDIB2);/ viewdib.MedianFilter(lpDIB2,m_imageW,m_imageH,3,3,1,1);/filterLPSTR lpDIBBits=viewdib.FindDIBBits(lpDIB2);DWORD DWidth=WIDTHBYTES(m_imageW*8);/watershed.LPSTR lpDIBG=viewdib.MakeGray8Bmp(lpDIB2);lpDIBG=viewdib.GetGrad(lpDIBG);LPSTR lpDIBBitsG=viewdib.FindDIBBits(lpDIBG);int i,k,num=0;

14、int m=0,n=0;/get oritional imageunsigned char* 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); /get seedimage and initialize itchar* seed_image;seed_image=alloc_char_space(m_imageH,m_imageW);for(i=0;im_imageH;i+)for(k=0;km_imageW;k+)seed_imageik=0;unsigned char uszThre=3; unsigned char uszTem=0;for(i=2,num=0;im_imageH-2;i+)for(k=

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

当前位置:首页 > 行业资料 > 其它行业文档

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