user2475404
user2475404

Reputation: 133

Manual Mean Filtering

Before I begin, I would just like to clarify that I understand how to use kernels and the conv2() function in order to mean filter an image, but I have been tasked with doing this manually by calling up each pixel.

My goal here is to call up each pixel, find its neighbors, average them out, and replace previous values with the acquired mean, without using kernels or conv2(). I have so far attempted to find the neighbors of each pixel using

for
   I = 1:512;
     for
        J = 1:683;
A = myimage;
neighbor_offsets = [-1, A, 1, -A, A + 1, -A + 1, -A-1, A - 1];
idx = [I J];
neighbors = bsxfun(@plus,idx,neighbor_offsets);

but it does not seem to work, and I am a bit lost in trying to fix it. I think I could finish the job if I were able to get the neighbors by using something like

sum(neighbors) / 9

then replace the previous values with that answer, but please correct me if I'm. I've developed somewhat of a tendency to ask poor questions, so if anything is unclear, please let me know so I can clarify for you. Thanks

Upvotes: 2

Views: 634

Answers (1)

plesiv
plesiv

Reputation: 7028

Example below treats pixels at the edge in the manner that it only considers pixels that are inside the image. For example when program is computing average with kernel dy = (-1:1) and dx = (-1:1) on top-left corner, it only considers top-left corner and its immediate 3 neighbors (right, right-bottom, right), and does average of those 4 pixels.

I would strongly advise you to test every line separately in Matlab's command window to see it's behavior!

% find image size
imsz = size( myimage );

% initialize output image
imavg = zeros( imsz );

% iterate over pixels
for yy = 1 : imsz(1)
    for xx = 1 : imsz(2)

        % define rectangle-kernel width
        dy = (-1:1);    % 1 up, to 1 down and ...
        dx = (-1:1);    % 1 left, to 1 right from current pixel

        % get indexes of image
        indy = yy + dy;
        indx = xx + dx;

        % [!!!] keep indexes that are inside image
        indy = indy( indy>0 & indy<=imsz(1) );
        indx = indx( indx>0 & indx<=imsz(2) );

        % create all the pairings of chosen indexes
        [ IY, IX ] = meshgrid( indy, indx );

        % take all values of chosen pixels
        pixs = myimage( sub2ind(imsz,IY(:),IX(:)) );

        % save mean of chosen pixels to the given location
        imavg(yy,xx) = mean( pixs );
    end
end

You can create function from the above code with creating mean_filter.m file with this contents:

function imagv = mean_filter( myimage )

    % code from above ...

You can call function from command window by positioning yourself in the directory where it's at and executing filtered = mean_filter( myimage );.


You can repeatedly filter the same image with:

filtered_3_times = myimage;
for ii = 1 : 3
    filtered_3_times = mean_filter( filtered_3_times );
end

Upvotes: 1

Related Questions