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

📄 tvdenoise.c

📁 image processing including fourier,wavelet,segmentation etc.
💻 C
字号:
/*----------------------------MegaWave2 module----------------------------*//* mwcommandname = {tvdenoise};version = {"1.0"};author = {"Lionel Moisan"};function = {"Image denoising by TV minimization (Rudin-Osher)"};usage = { 'w':[w=0.1]->w    "weight on fidelity term (default 0.1)", 's':[s=1.]->s     "initial (and maximal) time step, default 1.", 'E':[eps=1.]->eps "epsilon in sqrt(epsilon+|Du|^2), default 1.", 'e':[e=0.1]->e    "stop when |u(n)-u(n-1)|<e (L2 error, default 0.1)", 'n':n->n          "or perform a fixed number of iterations (default: 5)", 'r':ref->ref      "to specify a reference image different from in", 'v'->v            "verbose : print energy and L2 errors at each iteration", 'c'->c            "cancel auto step reduction", in->in            "input Fimage", out<-out          "output Fimage"        };*/#include <stdio.h>#include <stdlib.h>#include <math.h>#include "mw.h"extern float fnorm();#define COEFF .70710678118654752440#define COEFF2P2 3.41421356237309504880double mytvgrad(u,grad,eps)Fimage u,grad;double eps;{  int x,y,nx,ny,adr;  double E,a,b,c,d,e,f,z,norm;  nx = u->ncol;   ny = u->nrow;  E = 0.;  if (grad) {    mw_change_fimage(grad,ny,nx);    mw_clear_fimage(grad,0.);  }  for (x=0;x<nx-1;x++)    for(y=0;y<ny-1;y++) {      adr = y*nx+x;      a = (double)u->gray[adr     ];      b = (double)u->gray[adr   +1];      c = (double)u->gray[adr+nx+1];      d = (double)u->gray[adr+nx  ];      z=d; d-=c; c-=b; b-=a; a-=z; e=COEFF*(b-d); f=COEFF*(c-a);      norm = sqrt( eps + (a*a+b*b+c*c+d*d + e*e+f*f)/COEFF2P2 );      E += norm;      norm *= COEFF2P2;      if (grad) {	if (norm==0.) norm=1.;	grad->gray[adr     ] += (a-b+COEFF*(-e-f))/norm;	grad->gray[adr   +1] += (b-c+COEFF*( e-f))/norm;	grad->gray[adr+nx+1] += (c-d+COEFF*( e+f))/norm;	grad->gray[adr+nx  ] += (d-a+COEFF*(-e+f))/norm;      }    }  return(E);}/* Compute energy F(u) = weight * int |u-u_0|^2 and its gradient */double fidelity_term_grad(u,u0,grad,weight)     Fimage u,u0,grad;     double weight;{  int x,y,nx,ny,adr;  double e,d;  nx = u->ncol;   ny = u->nrow;  e = 0.;  for (x=0;x<nx;x++)    for(y=0;y<ny;y++) {      adr = y*nx+x;      d = (double)u->gray[adr] - (double)u0->gray[adr];      if (grad) grad->gray[adr] += (float)(weight*2.*d);      e += weight*d*d;    }  return(e);}/*----------------------- MAIN MODULE ---------------*/Fimage tvdenoise(in,out,s,c,v,e,n,w,ref,eps)Fimage in,out,ref;int *n;double *s,*e,*w,*eps;char *v,*c;{  Fimage dE,aux,tmp,cur,prev;  double energy,old_energy,step;  float two,norm1,norm2;  int i,j,border,cont,prevok,nx,ny;  /* initialization */  nx = in->ncol;   ny = in->nrow;  border = 0;  two = 2.;  dE = mw_change_fimage(NULL,ny,nx);  out = mw_change_fimage(out,ny,nx);  aux = mw_change_fimage(NULL,ny,nx);  if (!dE || !out || !aux)     mwerror(FATAL,1,"inttv: not enough memory\n");  mw_copy_fimage(in,out);  mw_copy_fimage(in,aux);  if (!ref) ref = in;  prev = aux; cur = out;   i = prevok = 0; step = *s;  /* compute initial error and its gradient */  energy = mytvgrad(cur,dE,*eps);  if (*w!=0.) energy += fidelity_term_grad(cur,ref,dE,*w);  energy /= (double)(nx*ny);  if (v) printf("init:  E = %f\n",energy);  /***** MAIN LOOP *****/   do {    /* update image */    for (j=nx*ny;j--;)       prev->gray[j] = cur->gray[j] - (float)step * dE->gray[j];        /* flip pointers and increment */    tmp=prev; prev=cur; cur=tmp;    i++;        /* compute error and its gradient for the next iteration */    old_energy = energy;    energy = mytvgrad(cur,dE,*eps);    if (*w!=0.) energy += fidelity_term_grad(cur,ref,dE,*w);    energy /= (double)(nx*ny);        if (energy>old_energy) {      tmp=prev; prev=cur; cur=tmp;      energy = mytvgrad(cur,dE,*eps);      if (*w!=0.) energy += fidelity_term_grad(cur,ref,dE,*w);      energy /= (double)(nx*ny);      if (c) {	printf("Stop after %d iterations (energy increases)\n",i);	cont = 0;      } else {	step *= 0.8;	if (v) printf("reduction to step=%f\n",step);	prevok = 0;	i--;	cont = 1;      }    } else {      if (prevok && (v || !n)) 	norm2 = fnorm(cur,prev,&two,0,0,&border,0,0);      if (n) cont=(i!=*n); else cont=(!prevok || norm2>=*e);      if (v) {	norm1 = fnorm(cur,ref,&two,0,0,&border,0,0);	printf("n=%3d: E = %f, dt = %f, |u-u0| = %f",i,energy,step,norm1);	if (prevok) printf(", |du| = %f\n",norm2); else printf("\n");      }      prevok = 1;    }  } while (cont);  /***** END OF MAIN LOOP *****/  if (cur!=out) mw_copy_fimage(cur,out);  mw_delete_fimage(aux);  return(out);}

⌨️ 快捷键说明

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