Let’s realize a Lee filter using MATLAB for despeckling of an image.
Since it’s a patch based processing, the computation cost will be high.
In order to reduce the same, a part of the code is realized in C language for improved performance.
MATLAB code:
%Read an Image
I = imread('coins.png');
%Add multiplicative noise to the image
J = imnoise(I,'speckle',0.01);
figure,imshow(J);
%Apply Lee filter
K = Lee_filter_C(I,J,[5 5]);
figure,imshow(uint8(K));
Create MATLAB function Lee_filter_C :
This function takes the reference image, speckled/noisy image and the window size as input and performs the following steps.
1. The variance of the reference image is found. Variance can be found either by using MATLAB built-in function or user defined function. Here in this case, a user defined function is used to find the variance.
2. Based on the size of the kernel, the noisy image is padded with zeros on all sides.
3. The center index of the kernel is found
4. The noisy image is processed patch by patch.
5. The code written in C computelee.c to despeckle the image is used.
MATLAB code:
function Y = Lee_filter_C(R,E,sz)
%R is the Reference Image
%E is the Error or Noisy Image
%K is the Kernel or Window
%Y is the Output Image
% Y = mean(K)+W*(C-mean(K);
% W = variance(K)/(variance(K)+variance(R))
%Define the type
R = double(R);
E = double(E);
%Preallocate the Output Matrix
Y = zeros(size(R));
mn = round((sz-1)/2);
Tot = sz(1,1)*sz(1,2);
EImg = padarray(E,mn);
%Variance of the reference Image
Rvar = myvar(R);
%Rvar = var(R(:));
Indx = floor(median(1:Tot));
for i = 1:size(R,1)
for j = 1:size(R,2)
K = EImg(i:i+sz(1,1)-1,j:j+sz(1,2)-1);
Y(i,j) = computelee(Rvar,K(Indx),K(:)');
end
end
end
NOTE: save the above function as Lee_filter_C.m
Function to find the variance:
MATLAB code:
function var_v = myvar(I)
I = I(:);
var_v = sum((I-mean(I)).^2)/numel(I);
end
NOTE: Save the above function as myvar.m
C program: computelee.c
Basics on MEX files in MATLAB:
If you are familiar with C programming then we just need to understand the gateway from MATLAB to C programming. The rest of the procedures will be same as we code in c.
The main gateway function for writing the C program is Mex function and it normally takes 4 parameters.
Nlhs – To find number of left hand side parameters
Plhs – Contains all the output parameters in an array
Nrhs – To find the number of right hand side parameters
Prhs – Contains the input parameters in an array
C code:
#include"mex.h"
/* Find variance and mean of the pixels in the window */
void arrayProduct(double v, double In, double *y, double *z, mwSize n)
{
double VarW,MeanW,W;
mwSize i;
MeanW=0;
for (i=0; i
MeanW=MeanW+y[i];
}
MeanW=MeanW/n;
VarW=0;
for(i=0;i
{
VarW=VarW+((y[i]-MeanW)*(y[i]-MeanW));
}
VarW=VarW/n;
W=VarW/(VarW+v);
z[0]=MeanW+W*(In-MeanW);
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double Rvariance,CIndx,*inMatrix,*out;
size_t ncols;
Rvariance = mxGetScalar(prhs[0]);
CIndx = mxGetScalar(prhs[1]);
inMatrix = mxGetPr(prhs[2]);
ncols = mxGetN(prhs[2]);
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL)
out = mxGetPr(plhs[0]);
/* Call the function arrayProduct */
arrayProduct(Rvariance,CIndx,inMatrix,out,(mwSize)ncols);
}
Let’s compare the calling function in MATLAB and the C code for better understanding.
MATLAB code:
computelee(Rvar,K(Indx),K(:)');
Three parameters are passed to the function computeelee.c
1. Variance of the reference image
2. Centre pixel from the kernel
3. All the pixels from the kernel based on the window size
C code:
Rvariance = mxGetScalar(prhs[0]);
CIndx = mxGetScalar(prhs[1]);
inMatrix = mxGetPr(prhs[2]);
Rvariance contains the variance of the reference image
CIndx contains the centre pixel of the corresponding kernel/patch
inMatrix contains all the pixels of the corresponding kernel/patch
ncols = mxGetN(prhs[2]);
ncols will obtain total number of elements in kernel.
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
out = mxGetPr(plhs[0]);
The final result will be stored in the variable ‘outMatrix’.
The function ‘arrayProduct’ written in C language is called to perform the computation.
Steps to be performed:
Let’s see how Lee filter works on homogeneous area and edge based area.
Homogeneous Patch |
Edges and lines |
The result shows that the filter works well on homogeneous area rather than on edges and lines.
Points to remember when using Mex file:
1. If you are using the C code for the first time, its better to find the appropriate compiler and configure to use it.
2. Compile the C code if the compiler is already present and make sure the compilation is successful.
3. Syntax to setup the compiler: mex - setup
The above syntax will identify the available compilers in your local system and you can configure it manually.
The above syntax will identify the available compilers in your local system and you can configure it manually.
4. For compiling the above c code: mex computelee.c
For successful compilation, the sample output will look like below:
Building with 'lcc-win32'.
MEX completed successfully.
5. The result of successful compilation will generate computelee.mexw32 for 32 bit system and for 64 bit system, you can find computelee.mexw64 file in your local directory.
To sum up, the two functions Lee_filter_C.m and myvar.m should be placed in the same directory. Computelee.c should also be placed in the same directory and the successful compilation of the same is mandatory.
I hope the readers of my blog will be familiar with working on Mex files. If you need any tutorial or post on this topic, kindly post or mail your suggestions.
Keine Kommentare:
Kommentar veröffentlichen