Search code examples
matlabimage-processingsmoothing

Trying to implement imfilter, but the image turns red


So I want to implements imfilter in matlab, without using the function itself. Here's what I came up through until now:

   % Menampilkan gambar sebelum di smoothing
    gambar = imread('bird.jpg');
    ukuran = size(gambar);
    figure
    imshow(gambar)

    % Menampilkan gambar setelah di smoothing
    gambardouble = im2double(gambar);
    filter = ones(3) * 1/9;
    gambarfinal = zeros(ukuran);

for i = 2:ukuran(1)-1
    for j = 2:ukuran(2)-1
        temp= gambardouble(i-1:i+1,j-1:j+1) .* filter;
        gambarfinal(i,j) = sum(temp(:));
    end
end

disp(gambarfinal);
figure
imshow(gambarfinal);

Now, the normal image is fine. But the output is become red like this: enter image description here

Any ideas what went wrong?


Solution

  • gambar seems to be a RGB image, size NxMx3. In gambarfinal = zeros(ukuran); you generate a zero matrix of size NxMx3. But then you apply the filter only to the red band, leaving the other two bands zero = black, which yields a red image.

    To also apply the filter to the other bands, you could e.g. apply the filter on all 3 bands at once:

    ...
    
    % generate 3-d filter
    filter = ones(3,3,3) * 1/9;
    
    ...
    
    % extract a 3x3x3 cube instad of a 3x3 patch
    temp= gambardouble(i-1:i+1,j-1:j+1,:) .* filter;
    
    % sum first along 1. dimension, then along the 2.dimension. This gives a 1x1x3 column.
    gambarfinal(i,j,:) = sum(sum(temp,1),2); 
    

    If you feel more comfortable with it, you could instead generate a loop over the other two bands - but that would be much slower.

    Edit

    The colon operator : returns all elements of a matrix in that dimension. E.g. for a 2 dimensional matrix A, A(:,2) will return the second column of A. Likewise, for a 3 dimensional matrix A(2,5,:) will return all elements along the 3. Dimension (a vector). Also note that A(2,5) is implicit the same as A(2,5,1).

    In your case gambardouble(i-1:i+1,j-1:j+1) will returns a 3x3 window of the 1. layer (red) of the 3-dimensional matrix. By changing it to gambardouble(i-1:i+1,j-1:j+1,:) you will like the examples above also get the same pixels in the other layers. Therefore in your case, temp will be a 3x3x3 cube.

    sum(temp,1) sums the cube along the 1. dimension, returning a 1x3x3 matrix. Then by also taking the sum along the 2. dimension with sum(... , 2) you turn it into a 1x1x3 vector, where each element belongs to one band.

    gambarfinal(i,j,:) is the RGB values at position (i,j) which we replace with the new values.

    For more information, read the colon documentation