MATLAB Answers

Right and Bottom Edge Cases Causing Issues in Matrix Transformation: Blur Image Assignment

5 views (last 30 days)
Hello,
I'm working on the Blur Image problem where a function needs to accept a matrix and average out pixel values using a submatrix around each. As far as I can tell, my code works perfectly everywhere except in the last row and column and I'm struggling to find what the error is. The full assignment prompt is below.
Write a function called blur that blurs the input image. The function is to be called like this:
output = blur(img,w);
where img, the input image is a two-dimensional matrix of grayscale pixel values between 0 and 255. Blurring is to be carried out by averaging the pixel values in the vicinity of every pixel. Specifically, the output pixel value is the mean of the pixels in a square submatrix of size 2w+1 where the given pixel sits in the center. For example, if w is 1, then we use a 3x3 matrix, that is, we average all the neighboring pixels of the given pixel and itself. Only use valid pixels when portions of the blurring matrix fall outside the image. For example, the blurred value corresponding to w = 1 at index (1,1) would be the mean of of elements (1,1), (1, 2), (2,1) and (2, 2). Both input img and output output are of type uint8.
You can download the test image here
M = % Input Matrix
1 2 3 4 5
5 4 3 2 1
10 10 11 12 199
200 198 105 101 254
0 255 100 199 99
function [output] = blur(img, w)
img = im2double(img); % Convert uint8 to double
[rowImg, colImg] = size(img);
imgBlur = [];
for ii=1:rowImg % Row marker
for jj=1:colImg % Col marker
if ii+w <= rowImg && jj+w <= colImg % Loop for Top and Left
% Left & Top Edge cases
if ii-w < 1 && jj-w < 1 % Top Left Case
empty = img(ii:ii+w, jj:jj+w);
elseif ii-w < 1 % Top Edge Case
empty = img(ii:ii+w, jj-w:jj+w);
elseif jj-w < 1 % Left Edge Case
empty = img(ii-w:ii+w, jj:jj+w);
else % Middle Area Case
empty = img(ii-w:ii+w,jj-w:jj+w);
end
elseif ii+w >= rowImg && jj+w >= colImg % Loop for Bottom and Right
if ii+w > rowImg && jj+w > colImg % Bottom Right Case
empty = img(ii-w:ii, jj-w:jj);
elseif ii+w > rowImg % Bottom Edge Case SOMETHING WRONG
empty = img(ii-w:ii, jj-w:jj+w);
else % jj+w > colImg % Right Edge Case SOMETHING WRONG
empty = img(ii-w:ii+w, jj-w:jj);
end
elseif ii-w < rowImg && jj+w > colImg % Top Right Case
empty = img(ii:ii+w, jj-w:jj);
else % ii+w > rowImg && jj-w < colImg % Bottom Left Case
empty = img(ii-w:ii, jj:jj+1);
end
newPixelVal = mean(empty, 'all'); % Mean of submatrix(w)
imgBlur(ii,jj) = newPixelVal; % Save new pixel value in location (ii,jj). This is the final matrix
end
end
output = uint8(imgBlur);
end
Below I've provided my output as well as the output of known good code using w = 1:
output = % This is my solution using w=1
5×5 uint8 matrix
3 3 3 3 3
5 5 6 27 54
71 61 50 76 142
112 99 110 120 144
163 165 126 143 163
testsltn = % Correct Solution using w = 1
5×5 uint8 matrix
3 3 3 3 3
5 5 6 27 37
71 61 50 76 95
112 99 110 120 144
163 143 160 143 163
They're very close but obviously something is wrong in my function. I appreciate any help or advice. Thanks!

  0 Comments

Sign in to comment.

Accepted Answer

Hussein Ammar
Hussein Ammar on 29 Aug 2020
Hello, why don't you use the following:
function [output] = blur(img, w)
img = im2double(img); % Convert uint8 to double
[rowImg, colImg] = size(img);
imgBlur = zeros(rowImg, colImg); % preallocate for speed
for ii=1:rowImg % Row marker
for jj=1:colImg % Col marker
i_start = max(1, ii-w);
i_end = min(rowImg, ii+w);
j_start = max(1, jj-w);
j_end = min(colImg, jj+w);
myBlock = img(i_start:i_end, j_start:j_end);
imgBlur(ii,jj) = mean(myBlock(:)); % reshape and get the mean of the resulted vector
end
end
output = uint8(imgBlur);
end
Output:
imgBlur =
3.0000 3.0000 3.0000 3.0000 3.0000
5.3333 5.4444 5.6667 26.6667 37.1667
71.1667 60.6667 49.5556 76.4444 94.8333
112.1667 98.7778 110.1111 120.0000 144.0000
163.2500 143.0000 159.6667 143.0000 163.2500
output =
5×5 uint8 matrix
3 3 3 3 3
5 5 6 27 37
71 61 50 76 95
112 99 110 120 144
163 143 160 143 163

  2 Comments

Marcin Laszkiewicz
Marcin Laszkiewicz on 29 Aug 2020
Hey Hussein thanks for the response! Your code is much simpler than mine although I'm really more interested in why my methodology isn't working. If none of it worked than I would definitely look into rewriting everything but when only a few elements are coming out wrong I really went to understand what is going wrong.
Hussein Ammar
Hussein Ammar on 31 Aug 2020
In your code, there is a problem in the precedence of the if conditions, also when you change the precedence, you end up with mixed cases. I suggest that you redefine the if condtions from scratch.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!