/* SplitBregmanROF.c (MEX version) by Tom Goldstein * This code performs isotropic ROF denoising using the "Split Bregman" algorithm. * This version of the code has a "mex" interface, and should be compiled and called * through MATLAB. * *DISCLAIMER: This code is for academic (non-commercial) use only. Also, this code *comes with absolutely NO warranty of any kind: I do my best to write reliable codes, *but I take no responsibility for the reliability of the results. * * HOW TO COMPILE THIS CODE * To compile this code, open a MATLAB terminal, and change the current directory to *the folder where this "c" file is contained. Then, enter this command: * >> mex splitBregmanROF.c *This file has been tested under windows using lcc, and under SUSE Unix using gcc. *Once the file is compiled, the command "splitBregmanROF" can be used just like any *other MATLAB m-file. * * HOW TO USE THIS CODE * An image is denoised using the following command * * SplitBregmanROF(image,mu,tol); * * where: * - "image" is a 2d array containing the noisy image. * - "mu" is the weighting parameter for the fidelity term * (usually a value between 0.01 and 0.5 works well for images with * pixels on the 0-255 scale). * - "tol" is the stopping tolerance for the iteration. "tol"=0.001 is reasonable for * most applications. * */ #include #include "mex.h" #include #include typedef double num; /*A method for isotropic TV*/ void rof_iso(num** u, num** f, num** x, num** y, num** bx, num** by , double mu, double lambda, int nGS, int nBreg, int width, int height); /*A method for Anisotropic TV*/ void rof_an(num** u, num** f, num** x, num** y, num** bx, num** by , double mu, double lambda, int nGS, int nBreg, int width, int height); /*****************Minimization Methods*****************/ void gs_an(num** u, num** f, num** x, num** y, num** bx, num** by , double mu, double lambda, int width, int height, int iter); void gs_iso(num** u, num** f, num** x, num** y, num** bx, num** by , double mu, double lambda, int width, int height, int iter); /******************Relaxation Methods*****************/ void gsU(num** u, num** f, num** x, num** y, num** bx, num** by , double mu, double lambda, int width, int height); void gsX(num** u, num** x, num** bx , double lambda, int width, int height); void gsY(num** u, num** y, num** by , double lambda, int width, int height); void gsSpace(num** u, num** x, num** y, num** bx, num** by, double lambda, int width, int height); /************************Bregman***********************/ void bregmanX(num** x,num** u, num** bx, int width, int height); void bregmanY(num** y,num** u, num** by, int width, int height); /**********************Memory************/ num** newMatrix(int rows, int cols); void deleteMatrix(num ** a); double** get2dArray(const mxArray *mx, int isCopy); double copy(double** source, double** dest, int rows, int cols); /***********************The MEX Interface to rof_iso()***************/ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* get the size of the image*/ int rows = mxGetN(prhs[0]); int cols = mxGetM(prhs[0]); /* get the fidelity and convergence parameters*/ double mu = (double)(mxGetScalar(prhs[1])); double lambda = 2*mu; double tol = (double)(mxGetScalar(prhs[2])); /* get the image, and declare memory to hold the auxillary variables*/ double **f = get2dArray(prhs[0],0); double **u = newMatrix(rows,cols); double **x = newMatrix(rows-1,cols); double **y = newMatrix(rows,cols-1); double **bx = newMatrix(rows-1,cols); double **by = newMatrix(rows,cols-1); double** uOld; double *outArray; double diff; int i,j; /***********Check Conditions******/ if (nrhs != 3) {mexErrMsgTxt("Three input arguments required.");} if (nlhs > 1){mexErrMsgTxt("Too many output arguments.");} if (!(mxIsDouble(prhs[0]))) {mexErrMsgTxt("Input array must be of type double.");} /* Use a copy of the image as an initial guess*/ for(i=0;itol); /* copy denoised image to output vector*/ plhs[0] = mxCreateDoubleMatrix(cols, rows, mxREAL); /*mxReal is our data-type*/ outArray = mxGetPr(plhs[0]); for(i=0;iflux) {x[w][h] = base-flux; continue;} if(baseflux) {y[w][h] = base-flux; continue;} if(baseflux) {xw[h] = base-flux; continue;} if(baseflux) {yw[h] = base-flux; continue;} if(base