How Do I Create a Mean Filtered Image using For Loops?
3 views (last 30 days)
Show older comments
My code is the one above. I am having trouble figuring out what I am doing wrong in particular. It just outputs the same image it received.
Now, some things to explain. I was specifically told not to worry about edge elements that can not be covered by the whole mean filter; hence the modulus if-statements to specify the for-loop range. So, my code was meant to just pick the middle value, starting at [row 2, column 2], and then replace the surrounding [3 x 3] elements (inclusive) in the tempArray with the generated mean value.
Am I over-simplifying how to find the mean? Is the reason that it is not carrying over because it is a for loop, and therefore not in the same scope? What am I doing wrong? How would I fix these issues?
2 Comments
Accepted Answer
Voss
on 21 Oct 2023
[gRow, gCol, ~] = size(grayImg);
gRow and gCol are non-negative scalar integers.
if mod(gRow, 3) < 3
mod(_,3) of something will be 0, 1, or 2, i.e., always less than 3, so this if condition is always true.
Later you use length(gRow) and length(gCol) to define your for loops. Both lengths are 1 since gRow and gCol are scalars.
So this:
for r = 2:3:(length(gRow) - cRow)
for c = 2:3:(length(gCol) - cCol)
is the same as this:
for r = 2:3:(1 - cRow)
for c = 2:3:(1 - cCol)
Given that cRow can be 0, 1, or 2, then 1-cRow will be 1, 0, or -1 (same for cCol), so those vectors that start with 2 are always empty
2:3:1
2:3:0
2:3:-1
so your for loops never iterate. That's the reason why you always get the same image back.
For the code inside the loops, it can written more simply as:
mn = mean(greyImg(r-1:r+1,c-1:c+1),'all');
tempArray(r-1:r+1,c-1:c+1) = mn;
That is, you don't have to reference each element individually, and you don't need to use deal to assign the result. More succintly would be to get rid of the temporary variable mn and say:
tempArray(r-1:r+1,c-1:c+1) = mean(greyImg(r-1:r+1,c-1:c+1),'all');
More Answers (2)
DGM
on 21 Oct 2023
Edited: DGM
on 21 Oct 2023
There are a bunch of examples of basic sliding window (and probably blockwise) filters on the forum. I don't have my bookmarks with me, so:
In practice, you'd use imfilter() or blockproc() depending on your intent, but I assume this is homework and you're supposed to avoid those.
For this case, here's a start
% single channel, uint8
grayImg = imread('cameraman.tif');
[gRow,gCol,~] = size(grayImg);
tempArray = grayImg;
% these are some problems:
% mod(x,n) is always <n, so these if-statements don't do anything
% if mod(gRow,3) < 3
% cRow = mod(gRow,3);
% else
% cRow = 0;
% end
%
% if mod(gCol,3) < 3
% cCol = mod(gCol,3);
% else
% cCol = 0;
% end
%
% gRow,gCol are scalar, so its length is always 1
% consequently, the loop doesn't increment as expected
%for r = 2:3:(length(gRow) - cRow)
% for c = 2:3:(length(gCol) - cCol)
% this is a blockwise filter
for r = 2:3:floor(gRow/3)*3 - 1
for c = 2:3:floor(gCol/3)*3 - 1
% good gravy, i'm not retyping all that
mn = sum(grayImg(r-1:r+1,c-1:c+1),'all')/9;
% i think this is what you meant to do?
tempArray(r-1:r+1,c-1:c+1) = mn;
end
end
imshow(tempArray,'border','tight')
% maybe you wanted a regular sliding-window filter instead?
for r = 2:gRow-1
for c = 2:gCol-1
% good gravy, i'm not retyping all that.
mn = sum(grayImg(r-1:r+1,c-1:c+1),'all')/9;
% i think this is what you meant to do?
tempArray(r-1:r+1,c-1:c+1) = mn;
end
end
imshow(tempArray,'border','tight')
4 Comments
Matt J
on 21 Oct 2023
Edited: Matt J
on 21 Oct 2023
grayImg=reshape(1:49,7,7)
[m,n]=size(grayImg);
dm=repmat(3,1,ceil(m/3)); dm(end)=dm(end)-(sum(dm)-m);
dn=repmat(3,1,ceil(n/3)); dn(end)=dn(end)-(sum(dn)-n);
Blocks=mat2cell(grayImg,dm,dn);
for i=1:numel(Blocks)
if numel(Blocks{i})==9
Blocks{i}(:)=mean(Blocks{i}(:));
end
end
meanFltImg=cell2mat(Blocks)
0 Comments
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!