Reputation: 133
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
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