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

📄 funzoom.c

📁 image processing including fourier,wavelet,segmentation etc.
💻 C
字号:
/*--------------------------- Commande MegaWave -----------------------------*//* mwcommand   name = {funzoom};   version = {"2.3"};   author = {"Lionel Moisan"};   function = {"Image reduction by projection on a B-spline space"};   usage = {  'z':[z=2.0]->z     "unzoom factor (default 2.0)",'x':tx->tx         "to first translate (x) the original image",'y':ty->ty         "to first transalte (y) the original image",'o':[o=0]->o       "spline space order, 0..5, default 0",in->in             "input Fimage",out<-out           "output Fimage"};*//*---------------------------------------------------------------------- v2.3: fixed image border bug (L.Moisan)----------------------------------------------------------------------*/#include <stdio.h>#include <math.h>#include "mw.h"extern void finvspline();extern Fimage fdirspline();/* NB : calling this module with out=in is possible *//* extract image value (symmetrize outside image domain) */float v(in,x,y)Fimage in;int x,y;{  if (x<0) x=-x;  if (x>=in->ncol) x=2*(in->ncol-1)-x;  if (y<0) y=-y;  if (y>=in->nrow) y=2*(in->nrow-1)-y;  return(in->gray[y*in->ncol+x]);}/* fast integral power function */double ipow(x,n)     double x;     int n;{  double res;  for (res=1.;n;n>>=1) {    if (n&1) res*=x;    x*=x;  }  return(res);}/* binomial coefficient */double binom(k,n)     int k,n;{  int i;  double v;  for (i=0,v=1.;i<k;i++) v*=(double)(n-i)/(double)(k-i);  return v;}/*------------ SMALL piecewise polynomial functions LIBRARY ------------*//* piecewise polynomial function (0 outside its domain) */#define PPMAXKNOTS 50#define PPMAXDEG   50typedef struct ppfunction {  int n;                /* number of knot points */  float x[PPMAXKNOTS];  /* knot points (in increasing order) */  int k;                /* number of coefficients for each polynomial */  double a[PPMAXKNOTS][PPMAXDEG];                          /* a[i][j] X^j contributes between x[i] and x[i+1] */} *Ppfunction;/* print algebraic description of Ppfunction */void ppprint(f)     Ppfunction f;{  int i,j;  printf("%d knots\n",f->n);  for (i=0;i<f->n-1;i++) {    printf("interval [%f,%f]\n",f->x[i],f->x[i+1]);    printf("%f ",f->a[i][0]);    for (j=1;j<f->k;j++)       printf("+ %f X^%d",f->a[i][j],j);    printf("\n\n");  }}/* find the interval [x(i),x(i+1)] corresponding to a given point *//* convention : i=-1 if the interval is unbounded */int ppfind(f,x)     Ppfunction f;     double x;{  int i;  if (f->n==0 || x<f->x[0]) return(-1);  for (i=1;i<f->n && x>=f->x[i];i++);  if (i==f->n) return(-1); else return(i-1);}/* eval a Ppfunction at a given point x (Horner algorithm) */double ppeval(f,x)     Ppfunction f;     double x;{  int i,j;  double v;  i = ppfind(f,x);  if (i==-1) return(0.);  for (j=f->k,v=0.;j--;)     v = v*x + f->a[i][j];  return(v);}    /* add integral between x[i] and t-w (sign=-1)              or between x[i] and t+w (sign=1) */void ppaddint(f,g,i,sign,w)     Ppfunction f,g;     int i,sign;     double w;{  double x,v;  int n,j,i0,k;    i0 = (sign==-1?i-1:i);  if (i0<0 || i0>=f->n-1) return;  x = (double)(f->x[i]);  n = g->n-2;    for (j=0;j<f->k;j++) {    v = (double)sign*(double)(f->a[i0][j])/(double)(j+1);    for (k=0;k<=j+1;k++)        g->a[n][k] += v*binom(k,j+1)*ipow(w*(double)sign,j+1-k);    g->a[n][0] -= v*ipow(x,j+1);  }}/* add integral between x[i1] and x[i2] */void ppaddcte(f,g,i1,i2)     Ppfunction f,g;     int i1,i2;{  double x,y;  int n,i,j;    if (i1<0 || i1>=i2 || i2>f->n-1) return;  n = g->n-2;    for (j=0;j<f->k;j++) {    y = ipow( (double)(f->x[i1]),j+1 );    for (i=i1;i<i2;i++) {      x = y;      y = ipow( (double)(f->x[i+1]),j+1 );      g->a[n][0] += (double)(f->a[i][j])*(y-x)/(double)(j+1);    }  }}/* convolution of a piecewise polynomial function *//* by a symmetric pulse of width 2*w and height 1 */void ppconvol(f,g,w)     Ppfunction f,g;     double w;{  float x1,x2;  int i1,i2;  /*  memset((void *)g->a,0,600*sizeof(double));*/  for (i1=0;i1<PPMAXKNOTS;i1++)    for (i2=0;i2<PPMAXDEG;i2++)      g->a[i1][i2]=0.;      g->n = 0; g->k = f->k+1;    /* i1 is the left index of the interval containing x-w */  /* i2 is the left index of the interval containing x+w */  i1 = i2 = -1; /* we start with x = - infinity */  while (i1<f->n-1) {    /* determine next knot point */    x1 = f->x[i1+1]+w;    if (i2<f->n-1) x2=f->x[i2+1]-w; else x2=x1+1.;    if (x1<=x2) {      /* right bound encountered on the left */      g->x[g->n++]=x1;      if (g->n>1) {	ppaddint(f,g,i1+1,-1,w);	ppaddcte(f,g,i1+1,i2);	ppaddint(f,g,i2,1,w);      }      i1++;      if (x2==x1) i2++;    } else {      /* right bound encountered on the right */      g->x[g->n++]=x2;      if (g->n>1) {	ppaddint(f,g,i1+1,-1,w);	ppaddcte(f,g,i1+1,i2);	ppaddint(f,g,i2,1,w);      }      i2++;    }  }}/* build spline of order o : W1^o */void ppspline(f,o)     Ppfunction f;     int o;{  struct ppfunction g;  Ppfunction f1,f2,f3;  int i;  /* init */  f->n=2; f->x[0]=-0.5; f->x[1]=0.5; f->k=1; f->a[0][0]=1.;  f1=f; f2=&g;  for (i=0;i<o;i++) {    ppconvol(f1,f2,0.5);    f3=f1; f1=f2; f2=f3;  }  if (f!=f1) *f=g;}/* build unzoom kernel of order o : (W1*Wz)^o */void ppkernel(f,o,z)     Ppfunction f;     int o;     float z;{  struct ppfunction g;  Ppfunction f1,f2,f3;  int i;  /* init */  f->n=2; f->x[0]=-0.5; f->x[1]=0.5; f->k=1; f->a[0][0]=1.;  for (i=1;i<=o+1;i++) f->a[0][0]/=z;  f1=f; f2=&g;  for (i=0;i<o;i++) {    ppconvol(f1,f2,0.5);    f3=f1; f1=f2; f2=f3;  }  for (i=0;i<=o;i++) {    ppconvol(f1,f2,0.5*z);    f3=f1; f1=f2; f2=f3;  }    if (f!=f1) *f=g;}/*------------------------ MAIN MODULE ---------------------------------*/Fimage funzoom(in,out,z,o,tx,ty)     Fimage in,out;     float *z,*tx,*ty;     int *o;{  int i,d,n,x,y,nx,ny,nsx,nsy;  float *c,p,u,res,delta;  Fimage tmp,in0,out0;  struct ppfunction xi;  if (*z<1.)     mwerror(FATAL,1,"illegal unzoom factor (%f) - should be at least 1.\n",*z);  if (*o<0 || *o>5)     mwerror(USAGE,0,"spline space order should be in [0..5]\n");  nx = in->ncol; ny = in->nrow;  nsx = (int)rint((double)nx/(double)(*z));  nsy = (int)rint((double)ny/(double)(*z));  out = mw_change_fimage(out,nsy,nsx);    tmp = mw_change_fimage(NULL,ny,nsx);    n = (int)ceil(0.5*(double)(*z+1.)*(float)(*o+1));  c = (float *)malloc((2*n+1)*sizeof(float));  /********** PRE-FILTERING **********/  if (*o>1) {    in0 = mw_change_fimage(NULL,ny,nx);    finvspline(in,*o,in0);   } else in0 = in;  /********** CONVOLUTION AND SAMPLING **********/  /* compute convolution kernel xi = (W1*Wz)^{n+1} */  ppkernel(&xi,*o,*z);  if (*o==0) out0 = out;  else out0 = mw_change_fimage(NULL,nsy,nsx);  /* FIRST LOOP (x) */  delta = (tx?*tx:0.);  for (x=0;x<nsx;x++) {    p = *z*((float)x+0.5)-0.5-delta;    i = (int)floor((double)p);     u = p-(float)i;    for (d=-n;d<=n;d++)       c[n+d]=(float)ppeval(&xi,u+(float)d);    for (y=0;y<ny;y++) {      /* this test saves computation time */      if (i-n>=0 && i+n<nx)	for (d=-n,res=0.;d<=n;d++)	  res += c[n+d]*in0->gray[y*nx+i-d];      else 	for (d=-n,res=0.;d<n;d++)	  res += c[n+d]*v(in0,i-d,y);      tmp->gray[y*nsx+x] = res;    }  }    /* SECOND LOOP (y) */  delta = (ty?*ty:0.);  for (y=0;y<nsy;y++) {    p = *z*((float)y+0.5)-0.5-delta;    i = (int)floor((double)p);     u = p-(float)i;    for (d=-n;d<=n;d++)       c[n+d]=(float)ppeval(&xi,u+(float)d);    for (x=0;x<nsx;x++) {      /* this test saves computation time */      if (i-n>=0 && i+n<ny)	for (d=-n,res=0.;d<=n;d++)	  res += c[n+d]*tmp->gray[(i-d)*nsx+x];      else 	for (d=-n,res=0.;d<=n;d++)	  res += c[n+d]*v(tmp,x,i-d);      out0->gray[y*nsx+x] = res;    }  }  /********** POST-FILTERING **********/  if (*o>=1) {    if (*o>1) {      finvspline(out0,*o*2+1,out0);      fdirspline(out0,*o,out);      mw_delete_fimage(in0);    } else finvspline(out0,*o*2+1,out);    mw_delete_fimage(out0);  }  mw_delete_fimage(tmp);  return(out);}

⌨️ 快捷键说明

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