MATLAB: Introduction to MATLAB programming – image blur problem

blurring the input imagecourseraintroduction to matlab programming

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

Best Answer

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.