%% Noise reduction via averaging for images

% This example performs noise reduction for the image of coins by averaging
% m noisy observations of the image

% This command reads in the image
I = imread('coins.png');

% This is the number of noisy images that we will create and then average
m=100;

% This section of the code adds noise to each image and then computes the
% average of all of these images
Iavg=0;
for ind=1:m
    
    % The following two lines of code create noisy versions of the image I.
    % To switch between the types of image, just comment/uncomment the
    % desired line of code.  The second input into imnoise tells the
    % function what type of noise to add.  The third input is a number
    % between 0 and 1 and tells the function how much noise should be
    % added.  The command im2double in front of imnoise is used purely for
    % procedural purposes within Matlab due to the way it stores images.
    % Don't worry for now about what it does.  I will talk a little bit
    % more about it at a later time.
    
    %Ino{ind}=im2double(imnoise(I,'gaussian',0.2));
    Ino{ind}=im2double(imnoise(I,'salt & pepper',0.5));
    
    % This line computes the average of the images    
    Iavg=Iavg+Ino{ind}/m;
    
end

% NOTE: Ino is a new type of data structure than we have seen before.  In
% Matlab, if we use curly brackets { and }, we are dealign with a structure
% called a "cell".  Cells are convenient because we can place other types
% of data in them.  Here, after the data is collected, Ino will be an
% m-dimensional vector of cells, where each cell contains an entire matrix.
% If we want to refer to the 5th cell of Ino, for example, we would type in
% Ino{5}.  Cells are convenient for storing a large number of images in
% Matlab.

% Here is the original image of the coins
figure(1)
imshow(I);
title('Original')

% Here is an example of the image with the specified type of noise
figure(2)
imshow(Ino{1});
title('With Noise')

% Here is what the average of all m images looks like
figure(3)
imshow(Iavg);
title('Average')




%% Linear Filter for images

% This example illustrates how to apply the linear filter to an image.

% This set of commands reads in the image and adds a specified type of
% noise to it, just as we did above.
I = imread('coins.png');
%Ino=imnoise(I,'salt & pepper',0.1);
Ino=imnoise(I,'gaussian',0.1);

% The following code applies the linear filter to the noisy image.

% h is a c by c matrix, where each entry is equal to 1/(c^2).  This matrix
% will be used in the function imfilter to average the pixels that neighbor
% a given pixel.  The value used for c determines how many pixels are
% considered to be nearby.  If you alter c, it should be an odd number.
c=3;
h = ones(c,c)/(c^2);
I2 = imfilter(Ino,h);


% This is a plot of the original image
figure(4);
imshow(I), title('Original Image');

% This is a plot of the image containing the specified type of noise
figure(5);
imshow(Ino), title('Image with noise');

% This is the image after the linear filter has been applied to it.
figure(6);
imshow(I2), title('Filtered Image')

%% Median Filter for images

% This example illustrates how to apply the median filter to an image.
% NOTE: the emdian filter does NOT work for RGB images.

% This set of commands reads in the image and adds a specified type of
% noise to it, just as we did above.
I = imread('coins.png');
Ino=imnoise(I,'salt & pepper',0.3);
%Ino=imnoise(I,'gaussian',0.1);

% The value for c again determines how many pixels are considered to be
% nearby a given pixel.  As before, c should be an odd number.
c=3;

% This command applies the median filter to the noisy image.
I2 = medfilt2(Ino,[c c]);


% This is a plot of the original image
figure(7);
imshow(I), title('Original Image');

% This is a plot of the image containing the specified type of noise
figure(8);
imshow(Ino), title('Image with noise');

% This is the image after the median filter has been applied to it.
figure(9);
imshow(I2), title('Filtered Image')




