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

📄 ll_boundaries.c

📁 image processing including fourier,wavelet,segmentation etc.
💻 C
字号:
/*----------------------------- MegaWave Module -----------------------------*//* mwcommand   name = {ll_boundaries};   version = {"1.1"};   author = {"Lionel Moisan"};   function = {"Extract meaningful boundaries (contrasted level lines) from a Fimage"};   usage = { 'e':[eps=0]->eps      "-log10(max. number of false alarms), default 0",'a'->all              "get all contrasted level lines (not only maximal ones)",'w'->weak             "select weak maximality",'s':step->step        "quantization step (bilinear), default 1.",'p':p->precision      "sampling precision (bilinear), default 2",'t':tree->tree        "use a precomputed FLST tree",'z'->z                "use zero order instead of bilinear interpolation",in->in                "input Fimage",out<-ll_boundaries    "output boundaries (Flists)"    }; */ /*---------------------------------------------------------------------- v1.1: added weak maximality, fixed Sonylogo 'type' bug (L.Moisan)----------------------------------------------------------------------*/#include <stdio.h>#include <float.h>#include <math.h>#include "mw.h" extern void flst();extern void flst_bilinear();extern void flstb_quantize();extern Flist flst_boundary();extern Flist flstb_boundary();extern int  fsaddles();extern Fsignal sintegral();extern Fsignal fhisto();#define HISTO_STEP 0.01/*----- internal structure associated to each Shape -----*/typedef struct mydata {  int ndetect;  float nfa;  char type; /* inferior_type of nearest ascending meaningful boundary */} *Mydata;/*----- global variables -----*/Fimage   image,NormOfDu;int      precision1,precision2,max_only,zero_order;Fsignal  logProbaOfDu;Shapes   ref_tree;float    **tabsaddles;Flists   boundaries;Flist    boundary;/*===== Compute the minimum contrast and the length of the curve l =====*/float min_contrast(l,length)Flist l;float *length;{  double per;  float mu,minmu,x,y,ox,oy;  int i,ix,iy;  per = 0.;  minmu = FLT_MAX;  for (i=0;i<l->size;i++) {    x = l->values[i*2];    y = l->values[i*2+1];    if (!zero_order) {      if (i>0) per += sqrt((double)(x-ox)*(x-ox)+(y-oy)*(y-oy));      ox = x; oy = y;    }        ix = (int)rint((double)x)-1;    iy = (int)rint((double)y)-1;    if (ix>=0 && iy>=0 && ix<NormOfDu->ncol && iy<NormOfDu->nrow) {      mu = NormOfDu->gray[NormOfDu->ncol*iy+ix];      if (mu<minmu) minmu=mu;    }  }  if (minmu == FLT_MAX) minmu = 0.;  if (zero_order) *length = (float)l->size; else *length = (float)per;  return(minmu);}/*===== compute NFA term associated to contrast mu =====*/float logH(mu)float mu;{  int i;  i = (int)(mu/logProbaOfDu->scale);  if (i>=logProbaOfDu->size) i=logProbaOfDu->size-1;  return(logProbaOfDu->values[i]);}/*===== first pass: compute # meaningful sons w/o contrast reversal =====*/void update_mydata(s,threshold,type)Shape s;float threshold;char type;{   Shape t;  float mu,length;  struct mydata *sdata, *tdata;  if (!s) return;  sdata = (struct mydata *)malloc(sizeof(struct mydata));  if (!sdata) mwerror(FATAL,1,"Not enough memory\n");  s->data = (void *)sdata;    if (s->parent) {    /* extract boundary */    if (zero_order)       flst_boundary(ref_tree,s,boundary);    else      flstb_boundary(&precision1,image,ref_tree,s,NULL,boundary,tabsaddles);    /*** compute nfa (-log10) ***/    mu = min_contrast(boundary,&length);    sdata->nfa = length*logH(mu)/(zero_order?3.:2.);        /* update type */    if (sdata->nfa < threshold) sdata->type = s->inferior_type;    else sdata->type = type;  } else {        sdata->nfa = threshold;    sdata->type = s->inferior_type;  }  /* visit children and update ndetect from children */  sdata->ndetect = 0;  for (t=s->child;t;t=t->next_sibling) {    update_mydata(t,threshold,sdata->type);    tdata = (struct mydata *)t->data;    if (tdata->nfa<threshold) {      if (sdata->type==t->inferior_type) sdata->ndetect++;    } else sdata->ndetect += tdata->ndetect;  }  if (sdata->nfa<threshold)      mwdebug("contrast=%g length=%g nfa=%g (threshold=%g) ndetect=%d\n",	    mu,length,sdata->nfa,threshold,sdata->ndetect);}/*===== second pass : compute and store maximal meaningful boundaries =====*/void add_boundary(s,threshold,bestnfa_inf,bestnfa_sup,type)Shape s;float threshold;float *bestnfa_inf,bestnfa_sup;char type;{   Shape t;  float mu,nfa,new_bestnfa_inf,old_bestnfa_sup;  int length,detect;  struct mydata *sdata, *tdata;  if (!s) return;  if (s->parent) {    sdata = (struct mydata *)s->data;    nfa = sdata->nfa;     /* update bestnfa_sup */    if (nfa<=bestnfa_sup) bestnfa_sup=nfa;    old_bestnfa_sup = bestnfa_sup;    if (type != s->inferior_type || sdata->ndetect!=1) bestnfa_sup=threshold;       /* visit children and update bestnfa_inf from children */    new_bestnfa_inf = threshold;    for (t=s->child;t;t=t->next_sibling) {      tdata = (struct mydata *)t->data;      *bestnfa_inf = threshold;      add_boundary(t,threshold,bestnfa_inf,bestnfa_sup,sdata->type);      if (*bestnfa_inf<new_bestnfa_inf 	  && sdata->ndetect==1	  && sdata->type==tdata->type) 	new_bestnfa_inf=*bestnfa_inf;    }    *bestnfa_inf = new_bestnfa_inf;    /* test if this shape has to be kept */    if ((nfa<threshold && !max_only) || 	(nfa<threshold && nfa <= old_bestnfa_sup && nfa < *bestnfa_inf)) {      /* store boundary */      if (zero_order)	flst_boundary(ref_tree,s,boundary);      else 	flstb_boundary(&precision2,image,ref_tree,s,NULL,boundary,tabsaddles);      boundaries->list[boundaries->size++] = mw_copy_flist(boundary,NULL);      printf("nfa=%f bestnfa_inf=%f bestnfa_sup=%f type=%d %d %d\n",nfa,*bestnfa_inf,bestnfa_sup,type,sdata->type,s->inferior_type);    } else s->removed = (char)1;    if (nfa<*bestnfa_inf) *bestnfa_inf = nfa;  } else {    for (t=s->child;t;t=t->next_sibling)       add_boundary(t,threshold,bestnfa_inf,bestnfa_sup,s->inferior_type);  }}/*===== simplified recursive algorithm for no or weak maximality =====*/void add_boundary_weak(s,threshold,bestnfa_inf,bestnfa_sup)Shape s;float threshold;float *bestnfa_inf,bestnfa_sup;{   Shape t;  float mu,nfa,new_bestnfa_inf,new_bestnfa_sup,length;  int nchildren;  if (!s) {    *bestnfa_inf = threshold;    return;  }    for (nchildren=0,t=s->child;t;t=t->next_sibling) nchildren++;    if (s->parent) {        /* extract boundary */    if (zero_order)       flst_boundary(ref_tree,s,boundary);    else      flstb_boundary(&precision1,image,ref_tree,s,NULL,boundary,tabsaddles);    /*** compute nfa (-log10) ***/    mu = min_contrast(boundary,&length);    nfa = length*logH(mu)/(zero_order?3.:2.);    /* check for 'type' chain break */    if (s->parent->inferior_type!=s->inferior_type) bestnfa_sup = threshold;        /* compute new_bestnfa_sup */    if (nchildren>1) new_bestnfa_sup = threshold;     else new_bestnfa_sup = bestnfa_sup;    if (nfa<new_bestnfa_sup) new_bestnfa_sup = nfa;        /* visit children and comput new_bestnfa_inf from children */    new_bestnfa_inf = threshold;    for (t=s->child;t;t=t->next_sibling) {      add_boundary_weak(t,threshold,bestnfa_inf,new_bestnfa_sup);      if (nchildren<=1 && *bestnfa_inf<new_bestnfa_inf)	new_bestnfa_inf = *bestnfa_inf;    }        /* test if this shape has to be kept */    if (nfa<threshold && (!max_only || 			  (nfa <= bestnfa_sup && nfa < new_bestnfa_inf))) {            /* store boundary */      if (zero_order)	flst_boundary(ref_tree,s,boundary);      else 	flstb_boundary(&precision2,image,ref_tree,s,NULL,boundary,tabsaddles);      boundaries->list[boundaries->size++] = mw_copy_flist(boundary,NULL);          } else s->removed = (char)1;    *bestnfa_inf = new_bestnfa_inf;    if (nfa<*bestnfa_inf) *bestnfa_inf = nfa;    if (s->parent->inferior_type!=s->inferior_type) *bestnfa_inf = threshold;  } else {    for (t=s->child;t;t=t->next_sibling)       add_boundary_weak(t,threshold,bestnfa_inf,bestnfa_sup);      }}/*------------------------------ MAIN MODULE ------------------------------*/Flists ll_boundaries(in,tree,eps,all,step,precision,z,weak)Fimage in;Shapes tree;float *eps,*step;int *precision;char *all,*z,*weak;{  Shape s;  Fimage saddles,copy_in;  float threshold,nfa_inf,nfa_sup,offset,histo_step,fzero;  int newtree=0,nsize,i;  /* check consistency */  if (all && weak)     mwerror(WARNING,0,"-w option is useless when -a option is selected\n");  zero_order = (z != NULL);  if (tree) {    if (zero_order && tree->interpolation!=0)      mwerror(FATAL,1,"Please use a zero order tree with -z option\n");    if (!zero_order && tree->interpolation!=1)      mwerror(FATAL,1,"Please use a bilinear tree without -z option\n");  }  if (zero_order && step)    mwerror(WARNING,0,"-s option have no effect with -z option\n");  /* compute FLST if needed */  if (!tree) {    newtree = 1;    tree = mw_new_shapes();    copy_in = mw_change_fimage(NULL,in->nrow,in->ncol);    if (!tree || !copy_in) mwerror(FATAL,1,"Not enough memory");    mw_copy_fimage(in,copy_in);    if (zero_order)       flst(NULL,copy_in,tree);    else      flst_bilinear(NULL,copy_in,tree);    mw_delete_fimage(copy_in);  }   if (!zero_order) {    /* bilinear case : compute saddle points and quantize FLST tree */    ref_tree = mw_new_shapes();    saddles = mw_new_fimage();    if (!ref_tree || !saddles) mwerror(FATAL,1,"Not enough memory");    fsaddles(in,saddles);    tabsaddles = mw_newtab_gray_fimage(saddles);    if (!tabsaddles) mwerror(FATAL,1,"Not enough memory");    offset = 0.5;    flstb_quantize(NULL,&offset,step,tree,ref_tree);    if (newtree) mw_delete_shapes(tree);  } else ref_tree = tree;  mwdebug("Total number of shapes: %d\n",ref_tree->nb_shapes);  /* initialization and memory allocation */  image = in; precision1 = 2; precision2 = (precision?*precision:2);  boundaries = mw_change_flists(NULL,ref_tree->nb_shapes-1,0);  if (!boundaries) mwerror(FATAL,1,"Not enough memory");  if (all) max_only=0; else max_only=1;  boundary = mw_change_flist(NULL,2,0,2);  /* compute NormOfDu */  NormOfDu = mw_new_fimage();  fzero = 0.; nsize = 3;  fderiv(in,NULL,NULL,NULL,NULL,NULL,NULL,NormOfDu,NULL,&fzero,&nsize);  /* compute logProbaOfDu */  histo_step = HISTO_STEP;  logProbaOfDu = fhisto(NormOfDu,NULL,&fzero,NULL,NULL,&histo_step,NULL);  logProbaOfDu->values[0]=0.; /* because Du!=0 on level lines */  sintegral(logProbaOfDu,1,1);  for (i=0;i<logProbaOfDu->size;i++)    logProbaOfDu->values[i] = (float)log10((double)logProbaOfDu->values[i]);  /* add boundaries recursively */  threshold = -*eps-(float)log10((double)(ref_tree->nb_shapes));  nfa_inf = nfa_sup = threshold;  mwdebug("NFA threshold: %g\n",threshold);  if (weak || all) {    add_boundary_weak(ref_tree->the_shapes,threshold,&nfa_inf,nfa_sup);  } else {    update_mydata(ref_tree->the_shapes,threshold,0);    add_boundary(ref_tree->the_shapes,threshold,&nfa_inf,nfa_sup,0);  }  printf("%d %sboundaries detected\n",boundaries->size,(all?"":"maximal "));  /* free memory and exit */  mw_delete_flist(boundary);  mw_delete_fimage(NormOfDu);  mw_delete_fsignal(logProbaOfDu);  if (!zero_order) {    free(tabsaddles);    mw_delete_fimage(saddles);    mw_delete_shapes(ref_tree);  }  return(boundaries);} 

⌨️ 快捷键说明

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