分水岭算法代码C.doc
《分水岭算法代码C.doc》由会员分享,可在线阅读,更多相关《分水岭算法代码C.doc(12页珍藏版)》请在三一文库上搜索。
1、 弄了快一周了,分水岭算法代码终于出来了,这个算法太有难度了,通过自己敲一遍后,终于明白了为什么这么多人可以不厌其烦的该进这样经典的算法,他们对算 法其实根本就没有改良和创新,只是对图像进展一些预处理和改变一下微分算子,其实最核心的还是分水岭算法本身,到至今为止我还没有看到有那篇论文能对分水 岭算法本身有所改良,即便是效率上的进步也没有,甚至还没有发现有那个论文能把分水岭算法本身流程给描绘清楚也许没找到,通过这段时间的读论文,我发 现很多论文只有开头背景和结论,中间过程就写得很随意,我想一个算法结论固然重要,但没有过程拿来的结论,那只能认为这是拍脑壳拍出来的。下面是我这 几天用c+实现的分水岭
2、算法,该算法基于的是LUV颜色空间,假设有人要用,需要把RGB转化为LUV。/ ImageSegWatershed.cpp: implementation of the CImageSegWatershed class./#include ImageSegWatershed.h#include math.h#include qstring.h#include qqueue.husing namespace std;#define MAXV 256static const double RGB33= double(3.2405),double(-1.5371),double(-0.4985),
3、double(-0.9693),double(1.8760),double(0.0416), double(0.0556),double(-2040),double(1.0573);static const int XYZ33=4125,3576,1804,2125,7154,721,193,1192,9502;static const double Xn=double(0.9505);static const double Yn=double(1.0);static const double Zn=double(1.0888);static const double Un_prime=dou
4、ble(0.1978);static const double Vn_prime=double(0.4683);static const double Lt=double(0.008856);/ Construction/Destruction/CImageSegWatershed:CImageSegWatershed(int ImageHeight,int ImageWidth,int *ImageData)PicHeight=ImageHeight;PicWidth=ImageWidth;PicData=ImageData;luvData=new MyluvImageHeight*Imag
5、eWidth;RgbtoLuvPcm(ImageData,ImageWidth,ImageHeight,luvData);CImageSegWatershed:CImageSegWatershed()void CImageSegWatershed:WaterShedArith()long Piclen=PicHeight*PicWidth;int i,j,temp;/梯度模数组double *deltar=new doublePiclen;/梯度角度数组double *deltasita=new doublePiclen;/个点标识数组int *flag=new intPiclen;int *
6、gradientfre=new int256; /图像中各点梯度值的频数int *gradientadd=new int257; /各梯度起终位置memset(gradientfre,0,sizeof(int)*256);memset(gradientadd,0,sizeof(int)*257);/得到各点的梯度值GetGradient(deltar,deltasita);/以下统计各梯度频数;MyImageGraPt* graposarr = new MyImageGraPtPiclen;long xstart, imagepos, deltapos;xstart = imagepos =
7、deltapos = 0;for (int y=0; yPicHeight; y+)xstart = y*PicWidth;for (int x=0; x255)deltardeltapos = 255; /范围在0-255之间int tempi = (int)(deltardeltapos);gradientfretempi +; /灰度值频数;/统计各梯度的累加频数int added=0;gradientadd0=0; /第一个初始位置为0for(i=1;i256;i+)added+=gradientfrei-1;gradientaddi=added;gradientadd256=Picl
8、en; /最后累加和为总的像素点的个数memset(gradientfre,0,256*sizeof(int);MyImageGraPt *graposarr=new MyImageGraPtPiclen;/自左上至右下sorting. (注意是对所求得的各个像素的累加梯度梯度值进展排序)for (y=0; yPicHeight; y+)xstart = y*PicWidth;for (int x=0; xPicWidth; x+)deltapos = xstart + x;int tempi = (int)(deltardeltapos); /当前点的梯度值,由于前面的步骤,最大只能为255
9、0-255);/根据梯度值决定在排序数组中的位置;int tempos = gradientaddtempi + gradientfretempi;gradientfretempi +;/梯度内指针后移(统计各个像素点的总的个数;graposarrtempos.gradient = tempi;/根据当前点的梯度将该点信息放后排序后数组中的适宜位置中去;graposarrtempos.x = x;graposarrtempos.y = y;int rgnumber=0;/记录分割后的区域数/下面是分水岭算法的核心步骤/开场吞没泛洪(泛洪函数各个形参的意义)/第一个参数是按一定规那么排好序的个
10、像素的梯度值和该像素在图片中的位置, /第二个参数是各个像素点的梯度累加和,倒数第二个参数是记录在泛洪过程中各个像素点的信息属于哪个区域,/最后一个参数是记录整个泛洪过程产生多少个区域FloodVincent(graposarr,gradientadd,0,255,flag,rgnumber); /区域增长步骤/以下准备计算各个区域的LUV的均值(也可以用其他的颜色空间)MyRgnInfo *rginfoarrr=new MyRgnInforgnumber+1;/分割后各个区的一些统计信息,第一个元素不用,图像各点所属区域的信息存放在flag数组中 /清空该数组(对各区域要统计的数据进展初始化
11、)for(int i=0;i=rgnumber;i+)rginfoarrri.isflag=FALSE;rginfoarrri.l=0;rginfoarrri.u=0;rginfoarrri.v=0;rginfoarrri.ptcount=0;long xstart;for(int y=0;yPicHeight;y+)xstart=y*PicWidth;for(int x=0;xPicWidth;x+)int pos=xstart+x;int rgid=flagpos;/当前位置点所属区域在区统计信息数组中的位置。/以下将该点的信息加到其所属区域信息中区rginfoarrrrgid.ptcou
12、nt+;rginfoarrrrgid.l+=luvDatapos.l;rginfoarrrrgid.u+=luvDatapos.u;rginfoarrrrgid.v+=luvDatapos.v;/求出各个区域的LUV均值for(i=0;i=rgnumber;i+)rginfoarrri.l=double(rginfoarrri.l)/rginfoarrri.ptcount);rginfoarrri.u=double(rginfoarrri.u)/rginfoarrri.ptcount);rginfoarrri.v=double(rginfoarrri.v)/rginfoarrri.ptcoun
13、t);/根据各个区域灰度均值和各区之间的邻接关系(用flag计算)进展区域交融(主要是消除不必要的过分割)int *mergearr=new int rgnumber+1;memset(mergearr,-1,sizeof(int)*(rgnumber+1);int mergednum=0;/第一个参数是各个区域的信息,第二个参数是图像所分的区域数,第三个参数是各个像素点的标志/倒数第二个参数和倒数第一个参数用于区域交融MergeRgs(rginfoarrr,rgnumber,flag,PicWidth,PicHeight,mergearr,mergednum);/确定合并后各像素点所属区域f
14、or(y=0;yPicHeight;y+)xstart=y*PicWidth;for(int x=0;xPicWidth;x+)int pos=xstart+x;int rgid=flagpos;/改点所属区域flagpos=FindMergedRgn(rgid,mergearr);delete mergearr;mergearr=NULL;/用各区均值来代替原像素点值double *luvbuff=NULL;luvbuff=new doublePicWidth*PicHeight*3;for(y=1;yPicHeight-1;y+)xstart=y*PicWidth;for(int x=1;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 分水岭 算法 代码
