How Do I Create a Mean Filtered Image using For Loops?

4 次查看(过去 30 天)
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 个评论
Aiden
Aiden 2023-10-21
I am sorry about that! In the future, I will attach a file of my code as well for questions.
I was simply panicking because this is a part of a project that I need to get through, and I forgot to consider how difficult it would be to re-type.

请先登录,再进行评论。

采纳的回答

Voss
Voss 2023-10-21
[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
ans = 1×0 empty double row vector
2:3:0
ans = 1×0 empty double row vector
2:3:-1
ans = 1×0 empty double row vector
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');
  2 个评论
Aiden
Aiden 2023-10-21
Thank you, I did not know if I could use row-column indexing this way and did not know how to try.
Also, your explanation of what I did wrong was fantastic and told me exactly what I needed to know. The simplification of code was also quite helpful and you are very appreciated.

请先登录,再进行评论。

更多回答(2 个)

DGM
DGM 2023-10-21
编辑:DGM 2023-10-21
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 个评论
Aiden
Aiden 2023-10-21
Really? It won't let me, it just says "Accept Answer" and then the option to do so on every other question dissappeared once I clicked one.

请先登录,再进行评论。


Matt J
Matt J 2023-10-21
编辑:Matt J 2023-10-21
grayImg=reshape(1:49,7,7)
grayImg = 7×7
1 8 15 22 29 36 43 2 9 16 23 30 37 44 3 10 17 24 31 38 45 4 11 18 25 32 39 46 5 12 19 26 33 40 47 6 13 20 27 34 41 48 7 14 21 28 35 42 49
[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)
meanFltImg = 7×7
9 9 9 30 30 30 43 9 9 9 30 30 30 44 9 9 9 30 30 30 45 12 12 12 33 33 33 46 12 12 12 33 33 33 47 12 12 12 33 33 33 48 7 14 21 28 35 42 49

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

产品


版本

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by