⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_snakes.c

📁 image processing including fourier,wavelet,segmentation etc.
💻 C
字号:
/*--------------------------- Commande MegaWave -----------------------------*//* mwcommand   name = {mac_snakes};   version = {"1.0"};   author = {"Lionel Moisan"};   function = {"Maximizing Average Contrast Snakes for contour detection"};   usage = {   'p':[power=1.]->power   "g(s)=|s|^power (default power=1.0)",   'n':[niter=1000]->niter "number of iterations (default 1000)",   's':[step=1.]->step     "evolution step (default 1.0)",   'v'->v                  "verbose mode",   'V':V->V                "select video mode and specify zoom (e.g. 2)",    u->u                   "input Fimage",    in->in                 "input curves (Dlists)",    out<-mac_snakes        "output curves (modified input)"   };*/#include <stdio.h>#include <math.h>#include "mw.h"#include "window.h"extern Cimage czoom();Cimage bg;double *xt,*yt;double thepower;Wframe *win;Dlists ref;/* the g function in the energy (energy is int g(Du.n)ds) */void gdgh(t,g,dg,h)     double t,*g,*dg,*h;{  if (t>0.) {    *g = pow(t,thepower);    *dg = thepower*(*g)/t;  } else if (t<0.) {    *g = pow(-t,thepower);    *dg = thepower*(*g)/t;  } else {    *g = 0.;    *dg = 0.;  }  *h = *g-t*(*dg);}/* reparameterize a curve with respect to arclength */void param(c,size)     double *c;     int size;{  double length,cur,norm;  int k,i;  for (k=0;k<size;k++) {    xt[k]=c[2*k]; yt[k]=c[2*k+1];  }  length = 0.;  for (k=0;k<size-1;k++)     length += hypot(yt[k+1]-yt[k],xt[k+1]-xt[k]);  length /= (double)(size-1);  cur = 0.; i = 1;  for (k=0;k<size-1;k++) {    cur +=  (norm=hypot(yt[k+1]-yt[k],xt[k+1]-xt[k]));    while (cur>=(double)i*length && i<size-1) {      c[2*i  ] = xt[k+1] + (xt[k]-xt[k+1])*((cur-(double)i*length)/norm);      c[2*i+1] = yt[k+1] + (yt[k]-yt[k+1])*((cur-(double)i*length)/norm);      i++;    }  }  }/* bilinear interpolation */double interpolate(u,x,y)     Fimage u;     double x,y;{  int ix,iy;  float *p;    x -= 0.5; y -= 0.5;  ix = (int)floor(x); iy = (int)floor(y);  if (ix<0 || ix>=u->ncol || iy<0 || iy>=u->nrow) return(0);  x -= (double)ix; y -= (double)iy;  p = u->gray+iy*u->ncol+ix;  return( (1.-y)*((1.-x)*(double)p[0]+x*(double)p[1])	  +y*((1.-x)*(double)p[u->ncol]+x*(double)p[u->ncol+1]) );}/* init video mode */void init_visu(u,in,zoom)     Fimage u;     Dlists in;     float zoom;{  int order=1;  bg = mw_fimage_to_cimage(u,NULL);  ref = mw_copy_dlists(in,NULL);  czoom(bg,bg,NULL,NULL,&zoom,&order,NULL);  win = (Wframe *)mw_get_window(NULL,bg->ncol,bg->nrow+12,10,10,bg->name);  if (!win) mwerror(INTERNAL,1,"NULL window returned by mw_get_window\n");  /*WfillRectangle*/  WSetUserEvent(win,W_KEYPRESS);}/* refresh display */int visu(in,zoom,niter,energy,refresh)     Dlists in;     float zoom;     int niter,refresh;     double energy;{  int i,j;  char str[100];  if (refresh) {    WLoadBitMapColorImage(win,bg->gray,bg->gray,bg->gray,bg->ncol,bg->nrow);    WRestoreImageWindow(win,0,0,bg->ncol,bg->nrow);    mw_copy_dlists(in,ref);  } else {    WSetColorPencil(win,164); /* red */    for (j=0;j<in->size;j++)       for (i=0;i<in->list[j]->size-1;i++) 	WDrawLine(win,		  (int)(in->list[j]->values[2*i  ]*zoom),		  (int)(in->list[j]->values[2*i+1]*zoom),		  (int)(in->list[j]->values[2*i+2]*zoom),		  (int)(in->list[j]->values[2*i+3]*zoom));  }  WSetColorPencil(win,84); /* green */  for (j=0;j<ref->size;j++)     for (i=0;i<ref->list[j]->size-1;i++)       WDrawLine(win,		(int)(ref->list[j]->values[2*i  ]*zoom),		(int)(ref->list[j]->values[2*i+1]*zoom),		(int)(ref->list[j]->values[2*i+2]*zoom),		(int)(ref->list[j]->values[2*i+3]*zoom));  sprintf(str,"iter = %8d     energy = %g             ",niter,energy);  WSetColorPencil(win,0); /* black */  WDrawString(win,0,bg->nrow+10,str);  WFlushWindow(win);  return(WUserEvent(win)==W_KEYPRESS && WGetKeyboard()==(int)'q');}/*------------------------------ MAIN MODULE ------------------------------*/Dlists mac_snakes(u,in,niter,step,power,v,V)     Fimage u;     Dlists in;     int *niter;     float *V;     double *step,*power;     char *v;{  Fimage imux,imuy,imuxx,imuxy,imuyy;  int nx,ny,i,j,k,kp,stop;  double *ux,*uy,*uxx,*uxy,*uyy,*dx,*dy,*dn,g,*dg,*h,mingrad;  double mx,my,zx,zy,a,b,c,d,e,length,s,tx,ty,p,energy;  int xi,yi,nsize,size,sizemax,closed;  thepower = *power;  sizemax = stop = 0;  for (j=0;j<in->size;j++)     if (in->list[j]->size>sizemax) sizemax=in->list[j]->size;  if (V) init_visu(u,in,*V);  xt = (double *)malloc(sizemax*sizeof(double));  yt = (double *)malloc(sizemax*sizeof(double));  dg = (double *)malloc(sizemax*sizeof(double));  h = (double *)malloc(sizemax*sizeof(double));  dx = (double *)malloc(sizemax*sizeof(double));  dy = (double *)malloc(sizemax*sizeof(double));  dn = (double *)malloc(sizemax*sizeof(double));  ux = (double *)malloc(sizemax*sizeof(double));  uy = (double *)malloc(sizemax*sizeof(double));  uxx = (double *)malloc(sizemax*sizeof(double));  uxy = (double *)malloc(sizemax*sizeof(double));  uyy = (double *)malloc(sizemax*sizeof(double));  nx = u->ncol; ny = u->nrow;  imux = mw_change_fimage(NULL,ny,nx);  imuy = mw_change_fimage(NULL,ny,nx);  imuxx = mw_change_fimage(NULL,ny,nx);  imuxy = mw_change_fimage(NULL,ny,nx);  imuyy = mw_change_fimage(NULL,ny,nx);  mingrad = 0.;  nsize = 8;  fderiv(u,NULL,NULL,NULL,NULL,imux,imuy,NULL,NULL,&mingrad,&nsize);  fderiv(imux,NULL,NULL,NULL,NULL,imuxx,imuxy,NULL,NULL,&mingrad,&nsize);  fderiv(imuy,NULL,NULL,NULL,NULL,NULL,imuyy,NULL,NULL,&mingrad,&nsize);    for (i=0;i<=*niter;i++) {        /********** ONE ITERATION **********/    energy = 0.;    for (j=0;j<in->size;j++) {            /********** ONE CURVE **********/            size = in->list[j]->size;      closed = ((in->list[j]->values[0]==in->list[j]->values[2*size-2] &&		 in->list[j]->values[1]==in->list[j]->values[2*size-1])?1:0);      /* pre-computation */      e = length = 0.;      for (k=0;k<size-1;k++) {	/* Gradient of potential */	mx = 0.5*(in->list[j]->values[2*k  ]+in->list[j]->values[2*k+2]);	my = 0.5*(in->list[j]->values[2*k+1]+in->list[j]->values[2*k+3]);	ux[k] = interpolate(imux,mx,my);	uy[k] = interpolate(imuy,mx,my);	uxx[k] = interpolate(imuxx,mx,my);	uxy[k] = interpolate(imuxy,mx,my);	uyy[k] = interpolate(imuyy,mx,my);		/* energy */	dx[k] = in->list[j]->values[2*k+2]-in->list[j]->values[2*k  ];	dy[k] = in->list[j]->values[2*k+3]-in->list[j]->values[2*k+1];	dn[k] = hypot(dy[k],dx[k]);	if (dn[k]==0.) dn[k]=1.0e-20;	s = (-uy[k]*dx[k]+ux[k]*dy[k])/dn[k];	gdgh(s,&g,dg+k,h+k);	e += g*dn[k];	h[k] /= dn[k];	length += dn[k];      }      energy += e/length;            /* evolution */      if (i<*niter) for (k=(closed?0:1);k<size-1;k++) {	if (k==0) kp=size-2; else kp=k-1;	tx = (-dg[kp]*uy[kp]+dg[k]*uy[k]	      +h[kp]*dx[kp]-h[k]*dx[k]	      +0.5*dg[k ]*(-uxy[k ]*dx[k ]+uxx[k ]*dy[k ])	      +0.5*dg[kp]*(-uxy[kp]*dx[kp]+uxx[kp]*dy[kp]) )/length	  -(dx[kp]/dn[kp]-dx[k]/dn[k])*e/(length*length);	ty = ( dg[kp]*ux[kp]-dg[k]*ux[k]	       +h[kp]*dy[kp]-h[k]*dy[k]	       +0.5*dg[k ]*(-uyy[k ]*dx[k ]+uxy[k ]*dy[k ])	       +0.5*dg[kp]*(-uyy[kp]*dx[kp]+uxy[kp]*dy[kp]) )/length	  -(dy[kp]/dn[kp]-dy[k]/dn[k])*e/(length*length);	in->list[j]->values[2*k  ] += *step * tx;	in->list[j]->values[2*k+1] += *step * ty;      }      if (closed) {	in->list[j]->values[2*size-2] = in->list[j]->values[0];	in->list[j]->values[2*size-1] = in->list[j]->values[1];      }      param(in->list[j]->values,size);    }        if (V) {      stop = (WUserEvent(win)==W_KEYPRESS && WGetKeyboard()==(int)'q');      if (stop) *niter=i;      if (i%100==0 || i==*niter) visu(in,*V,i,energy,1);      else if (i%10==0) visu(in,*V,i,energy,0);    }    if (i==0 || i==*niter || v) printf("energy: %g\n",energy);  }  if (V && !stop)     while (WUserEvent(win)!=W_KEYPRESS || WGetKeyboard()!=(int)'q');  return(in);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -