Search code examples
matlabimage-processingnoise-reduction

Why does my denoised image get darker after using non local means algorithm and why is the noise not reduced significantly?


I have implemented the naive version of non local means without integral images. First image acquisition:

row = 10;
col = 10;

% Patchsize - make sure if code works for different values
patchSize = 4;

% Search window size - make sure if code works for different values
searchWindowSize = 10;

image = imread('r.jpg');
new=imnoise(image,'gaussian');
imshow(new)
ws=floor(searchWindowSize/2);
ps=floor(patchSize/2);
new= padarray(new, [searchWindowSize,searchWindowSize], 'both');
new= padarray(new, [patchSize,patchSize], 'both');

Now, the main non local means function:

unew=zeros(size(new,1),size(new,2));
for i=1+ws+ps:size(new,1)-ws-ps
    for j=1+ws+ps:size(new,2)-ws-ps
        sear=new(i-ws:i+ws,j-ws:j+ws);
        %imshow(new(i-ws:i+ws,j-ws:j+ws))
        sear=padarray(sear,[ps,ps],'both');
        patch=new(i-ps:i+ps,j-ps:j+ps);
        dis=[];
        ind=1;
        sums=0;
        for ii=1+ps:size(sear,1)-ps
            for jj=1+ps:size(sear,1)-ps
                patchn=new(ii-ps:ii+ps,jj-ps:jj+ps);
                ssd=(patchn-patch).*2;
                psum=0;
                for mj=1:patchSize
                    for gj=1:patchSize
                        psum= psum+ssd(mj,gj);
                    end
                end
                dis(ind)=psum;
                sums=sums+exp(-max(dis(ind)*dis(ind)-2*0.1*0.1,0)/0.75*0.75);                

                ind=ind+1;
            end
        end
        new(i,j)=sums;
    end
end

My initial image:

enter image description here

My final image:

enter image description here


Solution

  • There are many issues with the code. Here is a non-exhaustive list:

    • You don’t do anything with color, it looks like your code is written for a grey-value image. But you put a color image through it. Consequently, only the red channel is modified.

    • You write into the same image you read from. You cannot do this, as you’re using a combination of input and output pixels to generate the next output pixel. Instead, read from one image, write to another one.

    • A weighted mean is computed by summing value*weight, and then dividing by the sum of the weights at the end. You don’t do this division.

    • You crop your search area from your image, then pad it. This makes no sense. You should crop a larger region from your image.

    • You keep an array dis, you write to it, but you don’t make use of it. That is, you write a new element, then only read this new element; you never go back and look at the older values. Why does this array exist?

    • Your inner two loops can be written as psum = sum(ssd(:)).

    • ssd is twice the difference. You probably want to look at the square difference, or the absolute difference.