Introduction to MATLAB programming - image blur problem

1 次查看(过去 30 天)
Hello all,
I am trying to work through one of the problems for the 'introduction to matlab programming' course by coursera, known as the 'image blur' problem (lesson 8 - final problems, week 9). The system keeps telling me that my values are incorrect, but I am struggling to understand why? I have attached my code below. I would be very grateful if anyone could give me a helping hand.
%The code to call the function:
img = imread('vandy.png')
output = blur(img,2) % I have specified the function 'blur' below
imshow(output);
% The function:
function[output] = blur(img,w)
here = 2*w + 1;
change = w;
%setting an epmpty matrix
emptymatrix = zeros(length(img(:,1)),length(img(1,:)));
%working out the output pixel value for each corner
added = img((1):(1+change),(1):(1+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(1,1) = answer;
i = length(img(:,1));
z = 1;
added = img((i-change):(i),(z):(z+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
i = 1;
z = length(img(1,:));
added = img((i):(i+change),(z-change):(z));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
i = length(img(:,1));
z = length(img(1,:));
added = img((i-change):(i),(z-change):(z));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
% working out the pixel values for the inner square
for i = 1:length(img(:,1))
for z = 1:length(img(1,:))
if ((i + change) <= length(img(:,1))) && ((i-change) > 0) && ((z+change) <= length(img(1,:))) && ((z-change) > 0)
added = img((i-change):(i+change),(z-change):(z+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/(here*here);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
end
end
end
% working out the output pixel values for the outer rows and columns (excluding the corners)
for i = 2:(length(img(:,1))-1)
if (i-change) > 0 && (i+change) < length(img(:,1))
z = 1;
added = img((i-change):(i+change),(z):(z+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
end
end
for i = 2:(length(img(:,1))-1)
if (i-change) > 0 && (i+change) < length(img(:,1))
z = length(img(1,:));
added = img((i-change):(i+change),(z-change):(z));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
end
end
for i = 2:(length(img(1,:))-1)
if (i-change) > 0 && (i+change) < length(img(1,:))
z = 1;
added = img((z):(z+change),(i-change):(i+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(z,i) = answer;
output = uint8(emptymatrix);
end
end
for i = 2:(length(img(1,:))-1)
if (i-change) > 0 && (i+change) < length(img(1,:))
z = length(img(:,1));
added = img((z-change):(z),(i-change):(i+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(z,i) = answer;
output = uint8(emptymatrix);
end
end
end
  5 个评论
ey21
ey21 2020-4-9
编辑:ey21 2020-4-9
@Geoff Hayes
I have attached a screenshot below for what the code is supposed to be doing.
This code here is working out the averaged pixel value for each of the corners of the n-by-n matrix:
%working out the output pixel value for each corner
added = img((1):(1+change),(1):(1+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(1,1) = answer;
i = length(img(:,1));
z = 1;
added = img((i-change):(i),(z):(z+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
i = 1;
z = length(img(1,:));
added = img((i):(i+change),(z-change):(z));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
i = length(img(:,1));
z = length(img(1,:));
added = img((i-change):(i),(z-change):(z));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
This code below works out the average pixel values for the indices (pixels) in the centre of the matrix. If the matrix is a 5-by-5 by matrix, the inner 3-by-3 square of pixel values would be calculated using the formula below:
% working out the pixel values for the inner square
for i = 1:length(img(:,1))
for z = 1:length(img(1,:))
if ((i + change) <= length(img(:,1))) && ((i-change) > 0) && ((z+change) <= length(img(1,:))) && ((z-change) > 0)
added = img((i-change):(i+change),(z-change):(z+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/(here*here);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
end
end
end
The code below is trying to work out the average value for each pixel on the outer edges of the matrix. For example, if the matrix is a 5-by-5 matrix, the code below would work out the average value for each pixel (indice) in the first and last column and row of the matrix, excluding the values of the four corners (as these have already been calculated above).
for i = 2:(length(img(:,1))-1)
if (i-change) > 0 && (i+change) < length(img(:,1))
z = 1;
added = img((i-change):(i+change),(z):(z+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
end
end
for i = 2:(length(img(:,1))-1)
if (i-change) > 0 && (i+change) < length(img(:,1))
z = length(img(1,:));
added = img((i-change):(i+change),(z-change):(z));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(i,z) = answer;
output = uint8(emptymatrix);
end
end
for i = 2:(length(img(1,:))-1)
if (i-change) > 0 && (i+change) < length(img(1,:))
z = 1;
added = img((z):(z+change),(i-change):(i+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(z,i) = answer;
output = uint8(emptymatrix);
end
end
for i = 2:(length(img(1,:))-1)
if (i-change) > 0 && (i+change) < length(img(1,:))
z = length(img(:,1));
added = img((z-change):(z),(i-change):(i+change));
addition = sum(added);
additionally = sum(addition);
mean = additionally/numel(added);
answer = uint8(mean);
emptymatrix(z,i) = answer;
output = uint8(emptymatrix);
end
end
end
Image Analyst
Image Analyst 2020-4-9
Can you use imfilter() or conv2()? It would be a lot shorter.

请先登录,再进行评论。

采纳的回答

Geoff Hayes
Geoff Hayes 2020-4-9
编辑:Geoff Hayes 2020-4-9
ey21 - I think that you need to simplify your code. For the block that is concerned with the inner rows and columns, I've reduced it to
for i = 1:length(img(:,1))
for z = 1:length(img(1,:))
if ((i + w) <= length(img(:,1))) && ((i-w) > 0) && ((z+w) <= length(img(1,:))) && ((z-w) > 0)
submatrix = img((i-w):(i+w),(z-w):(z+w));
output(z,i) = uint8(sum(submatrix(:))/numel(submatrix));
end
end
end
There is only one sum since submatris(:) will return a column of all elements in the submatrix, and then we can just sum those elements. numel is used to return the number of elements in the submatrix so that we can do the appropriate average. I've eliminated the emptymatrix since it is redundant. (I've replaced the change with w since they are identical.)
You still have two other blocks of code, so can all of this be simplified further? I think so...so long as you choose the correct submatrix for each element in the input matrix. In fact, I think that you can do all of this work in one loop regardless as to the pixel if you choose the correct minimum and maximum row and column to create the submatrix from. The example in your assignment tells you what to do if your code is considering the pixel at (1,1) so you could use that information to determine what to do.Your code to get the submatrix of an inner pixel is
submatrix = img((i-w):(i+w),(z-w):(z+w));
because you know that i-w is valid, i+w is valid, z-w is valid, and z+w is valid. This could be made more general if you do
minValidRowIndex = max(1,i-w);
maxValidRowIndex = min(numRows,i+w);
minValidColIndex = max(1,z-w);
maxValidColIndex = min(numCols,z-w);
The above four variables can now be used to get your submatrix for any (I think) pixel. We use max and min to ensure that we never use row or column indices that are outside of the matrix.
  2 个评论
ey21
ey21 2020-4-13
@geoff hayes,
the code below seems to be more successful but not perfect yet...
function[output] = blur(img,w)
here = 2*w + 1;
change = w;
emptymatrix = zeros(length(img(:,1)),length(img(1,:)));
for z = 1:length(img(1,:))
for i = 1:length(img(:,1))
if (i + change) <= length(img(:,1)) && (i - change) >= 1 && (z + change) <= length(img(1,:)) && (z - change) >= 1
submatrix = img((i-change):(i+change),(z-change):(z+change));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif i == 1 && z == 1
submatrix = img((i):(i+change),(z):(z+change));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif i == length(img(:,1)) && z == length(img(1,:))
submatrix = img((i-change):(i),(z-change):(z));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif i == 1 && z == length(img(1,:))
submatrix = img((i):(i+change),(z-change):(z));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif i == length(img(:,1)) && z == 1
submatrix = img((i-change):(i),(z):(z+change));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif i == 1 && z-change >= 1 && z+change <= length(img(1,:))
submatrix = img((i):(i+change),(z-change):(z+change));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif i == length(img(:,1)) && z-change >= 1 && z+change <= length(img(1,:))
submatrix = img((i-change):(i),(z-change):(z+change));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif z == 1 && i-change >= 1 && i+change <= length(img(:,1))
submatrix = img((i-change):(i+change),(z):(z+change));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
elseif z == length(img(1,:)) && i-change >= 1 && i+change <= length(img(:,1))
submatrix = img((i-change):(i+change),(z-change):(z));
emptymatrix(i,z) = uint8(sum(submatrix(:))/numel(submatrix));
output = uint8(emptymatrix);
end
end
end
end
Geoff Hayes
Geoff Hayes 2020-4-14
Do you really need to consider all of those cases? I really don't think that you need any if/elseif statements and so could perhaps reduce the code to simply
for z = 1:length(img(1,:)) % iterating over columns
for i = 1:length(img(:,1)) % iterating over rows
minValidRowIndex = max(1,i-w);
maxValidRowIndex = min(numRows,i+w);
minValidColIndex = max(1,z-w);
maxValidColIndex = min(numCols,z-w);
submatrix = img(minValidRowIndex:maxValidRowIndex, minValidColIndex:maxValidColIndex);
output(z,i) = uint8(sum(submatrix(:))/numel(submatrix));
end
end

请先登录,再进行评论。

更多回答(1 个)

Swapnil Yadav
Swapnil Yadav 2020-6-22
function out = blur(img,w) % convert to double for doing calculations imgD = double(img); [row, col] = size(img); out = zeros(row, col); for ii = 1:row for jj = 1:col % Get the indices for a submatrix r1 = ii-w; r2 = ii+w; c1 = jj-w; c2 = jj+w; % Test that indices are valid % If not, set to min/max that is valid if r1 < 1 r1 = 1; end if r2 > row r2 = row; end if c1 < 1 c1 = 1; end if c2 > col c2 = col; end % Get the submatrix and assign the mean to the output pixel m = imgD(r1:r2, c1:c2); out(ii,jj) = mean(m(:)); end end % convert back to uint8 out = uint8(out); end

类别

Help CenterFile Exchange 中查找有关 Matched Filter and Ambiguity Function 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by