简体   繁体   中英

matlab image smoothing with conv2

I am a newbie to imaging processing and I found some difficulties in implementing image smoothing.

Basically, I have an image A and I would like to replace everything pixel by its local average. So I define masks M1 = ones(10) and use

 newImage = conv2(A, M1,'same')

It works fine. But in image A, there are meaningless pixels fully due to noise and I don't want to include them in the averaging. How do I do that, say the meaningful pixels are defined via another mask M2?

I made a simple loop over the image. It works but is way slower than the conv2().

for i = 1:self.row
    for j = 1:self.col
        if self.M2(i,j) % only treat meaningful pixels
            A(i,j) = self.createAvgPhasor(i,j);
        end
    end
end

    function [s_avg]=createAvgPhasor(self,m,n)
        % bound box along x 
        if m > self.rB
            xl = m - self.rB;
        else
            xl = 1;
        end
        if m < self.row_rB
            xu = m + self.rB;
        else
            xu = self.row;
        end
        % bound box along y 
        if n > self.rB
            yl = n - self.rB;
        else
            yl = 1;
        end
        if n < self.col_rB
            yu = n + self.rB;
        else
            yu = self.col;
        end
        M1 = false(self.row,self.col);
        M1(xl:xu,yl:yu) = true;
        msk = M1 & self.M2;
        s_avg = mean(self.Phi(msk));
    end

Thanks very much for your help.

One quick fix is to replace all the values in the masked pixels with the total average.

A more refined way would be to convolve a large (very large) smoothing filter (like the one you already using but larger) with the image and only use the result to fill the masked pixels in the original image, now that you have reasonable values for the masked pixels in your original image, you can use the convolve as you are doing it now.

Excluding the bad points from the convolution is easy. If M2 contains a 1 for pixels that you want to include, and a 0 for those that you don't, then you just do this:

newImage = conv2(A.*M2, M1,'same');

This might be sufficient for your purposes, but you have to decide exactly what you mean by 'averaging". For example, given your kernal ones(10) , at the end you may want to do something like this:

npts = conv2(ones(size(A)).*M2, M1, 'same')
newImage = newImage./npts

Ie, divide each pixel by the number of pixels that were actually included in in the convolution for that pixel.

Actually, the above might also do the right thing even if you weighted different points differently. But it really depends on exactly what you want to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM