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

4 Ansichten (letzte 30 Tage)
Aiden
Aiden am 21 Okt. 2023
Kommentiert: Voss am 21 Okt. 2023
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 Kommentare
Matt J
Matt J am 21 Okt. 2023
We can't copy/paste your code (because it's an image).
Aiden
Aiden am 21 Okt. 2023
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.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Voss
Voss am 21 Okt. 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
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 Kommentare
Aiden
Aiden am 21 Okt. 2023
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.
Voss
Voss am 21 Okt. 2023
You're very welcome!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (2)

DGM
DGM am 21 Okt. 2023
Bearbeitet: DGM am 21 Okt. 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 Kommentare
Aiden
Aiden am 21 Okt. 2023
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.
Aiden
Aiden am 21 Okt. 2023
I see, never mind. I upvoted you, enjoy your day!

Melden Sie sich an, um zu kommentieren.


Matt J
Matt J am 21 Okt. 2023
Bearbeitet: Matt J am 21 Okt. 2023
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

Produkte


Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by