Lets Learn together... Happy Reading

" Two roads diverged in a wood, and I,
I took the one less traveled by,
And that has made all the difference "-Robert Frost

Lee filter


Let’s realize a Lee filter using MATLAB and C for despeckling of an image. For Lee filter using MATLAB explicitly check : https://www.imageeprocessing.com/2020/07/lee-filter-using-matlab_16.html
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.
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.








like button Like "IMAGE PROCESSING" page

Tile Memory Game



Tile Memory game - Win the game by matching equivalent tiles.



Initially, there will be a 2 by 2 matrix having 2 pairs of equivalent images hidden behind. User will be allowed to select 2 tiles in random. If both the images are equivalent, both the tiles will disappear. If not, it goes back to its original form. When all the pairs are matched, the level is completed and the user can proceed to the next level.

We will try to implement this game using pushbutton in the uicontrol and with some images.



Let’s write a main function called tile_memory_game
We will initialize our variables here and then fetch some images details.
Inside this function, we will have the following functions arrange_tile, display_tile, chk_new_tiles and calculate_moves.

The overall flow of our code:
MATLAB CODE:
function tile_memory_game
clear all;
clc
close all

%GLOBAL VARIABLES
global pname randicon sz flag PId fname items pv ni nj lc Ic Fg nm ;

%FIGURE WINDOW
Fg=figure('Position',[300 200 800 550] ,'Name','TILE MEMORY GAME','NumberTitle','off','MenuBar','None');

%FETCH PNG FORMAT FILES/IMAGES
files = dir('*.png');
fname = {files.name};


%INITIALIZATION
items=2;
ni=2;
nj=2;
sz=100;
lc=1;
nm= uicontrol('Style','Pushbutton','Position',[650 320 150 50]);
arrange_tile;


    function arrange_tile

    end
   
    function display_tile(obj,~) 
        
    end

    function chk_new_tiles
    end

    function calculate_moves
           
           
    end

end

Now let us try to explain in brief what each of the function does.

In tile_memory_game, all the global variables which will be used in other user defined functions will be mentioned.
Then the figure window which will be used to display the tiles (pushbuttons) is defined. By changing the values in  'Position', the window size can be increased or decreased based on our requirement.

The images used in the game are downloaded from web which are freely usable.

The images used in the game are downloaded from the web which are freely usable.These icons can be found in Iconfinder for free usage, but the license has to be read prior to usage. Usually a link has to be provided to the author's webpage if you are using for commercial purpose.

Initialize the number of rows and columns and the size of the pushbutton.
The function arrange_tile is called to arrange the tiles randomly.


Function arrange_tile
Level 1 contains 2x2 tiles. From the available PNG format icons, select two random icons and double it. That is, each icon should occur twice. A random shuffling will arrange the icons at different positions. See picture below:


 The built-in function 'randperm' is used for random shuffling. The syntax randperm(30,2) will randomly select two distinct numbers between 1 and 30. For instance say it selects 28 and 10.
Now we replicate the two numbers selected. Now they become 10,28,10,28.
Again 'randperm' is used for randomly placing these 4 values in the 2x2 matrix.

Pushbuttons are created and the indices are stored as user data for checking in the later part.

MATLAB CODE:
function arrange_tile

Ic=0;
pv=0;

%RANDOMIZE THE TILES
rndno = randperm(numel(fname),items);
row = [rndno rndno];
randicon = row(:,randperm(numel(row)));

inc=1;
flag=0;


%CREATE PUSHBUTTONS
for i = 1 : ni
    for j = 1:nj
  pname(inc)=  uicontrol('Style','Pushbutton','Position',[5+(i*sz) 90*5-(j*sz) sz-2 sz-2],'UserData',inc,'callback',@display_tile);

  inc=inc+1;
    end
end

lstat ='Number of Moves: 0 ';          
set(nm,'String',lstat);
end

Now the figure window will contain 2x2 tiles/pushbuttons. See figure below



Function display_tile

When a pushbutton is clicked/pressed, an icon/image will appear on it. 
 
FIRST CLICK
When another pushbutton is clicked, another icon/image will appear on it. 


SECOND CLICK
If both icons match then the icons will disappear.

ICONS SAME - DISAPPEAR


If both the icons do not match , then it will go back to its original form. The images are displayed for certain duration of time before its hidden back. I use a duration of 0.35 seconds to show the images. See the code below ‘pause(0.35);’
 
ICONS DIFFERENT

Pushbutton Reset

To give it a more sportive look, the number of moves used to complete the game  is calculated. The user has to complete the game within the specified number of moves failing which the game is lost. The time taken can also be calculated and points given as per the time taken to complete the same.

MATLAB CODE:
function display_tile(obj,~)
   
    %OBTAIN THE USERDATA FROM THE PUSHBUTTON CLICKED
    currvalue=get(obj,'UserData');
    img = imread(cell2mat(fname(randicon(currvalue))));
   
    %DISPLAY THE ICON/IMAGE ON THE PUSHBUTTON
    cimg = imresize(img,[sz-8 sz-8]);
    set(pname(currvalue),'CData',cimg);
       
         if(flag==0)
            PId = currvalue;
            flag=1;
         elseif(currvalue~=PId)
            
             pause(0.35);
%                IF TWO ICONS ARE SAME                        
            if(randicon(currvalue)==randicon(PId))
%                TO SET THE PUSHBUTTONS INVISIBLE               
%                set(pname(currvalue),'visible','off');
%                set(pname(PId),'visible','off');
   
%                TO SET THE PUSHBUTTONS BLACK
                 set(pname(PId),'CData',zeros([sz sz 3]),'callback','default','String','n');
                 set(pname(currvalue),'CData',zeros([sz sz 3]),'callback','default','String','n');
          
            pv=pv+1;
                
            else
%                IF TWO ICONS ARE DIFFERENT                  
                 set(pname(currvalue),'CData','default');
                 set(pname(PId),'CData','default');
                
               
            end
           
            if(Ic>=(items*2))
                
               %Use your own ideas here
             else
            
             flag=0;
             calculate_moves;
             chk_new_tiles;
            end
            
            
         end
        
    end
       

Function calculate_moves
This function is just to display the number of moves during each pair of pushbutton clicks.

Function chk_new_tiles
Check whether all the tiles are matched in the current level. If yes, then increment either row or column or both according to the programmer's wish and proceed to the next level. If all the pairs are matched then increment either the rows or columns or both according to your requirement. When the user succeeds in completing 4x4 ie 16 tiles , a message box with the ‘Winner’ title is displayed and the game is terminated. You can also increase the maximum number of rows and columns based on your requirement.

Winner

GAME LOST

MATLAB CODE:
function chk_new_tiles
       if(pv==items)
           
         if(items==8)
                
                %END OF THE GAME
               
            else
                %INCREASE THE TILE SIZE
               
             lc=lc+1;
            
             %Increment ni or nj or both
             %ni = ni+1;
             %nj = nj+1;
            
             items=(ni*nj)/2;
            
             arrange_tile;
         end
      end
 end




The level of difficulty can be increased either by increasing the number of rows and columns or decreasing the duration of keeping the images open after wrong match or both.
Kindly note that the full MATLAB code for the game is not provided here.








like button Like "IMAGE PROCESSING" page
Previous Post Next Post Home
Google ping Hypersmash.com