Write a function called blur that blurs the input image

390 visualizzazioni (ultimi 30 giorni)
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
Opens in new tab
to use in MATLAB.
I am using the following code but it gives me an error. Can anyone please tell me where I am going wrong?
function output = blur(img,w)
B=double(img);
[m,n] = size(B);
k=2*w+1;
for i = 1:m
for j = 1:n
p=i-fix(k/2);
q=i+fix(k/2);
r=j-fix(k/2);
s=j+fix(k/2);
if p<1
p=1;
end
if q>m
q=m;
end
if r<1
r=1;
end
if s>n
s=n;
end
A=B([p:q],[r:s]);
B(i,j)=mean(A(:));
end
end
output=uint8(B);
end
  10 Commenti
Muhammad
Muhammad il 4 Ago 2022
I'm not understanding this program. Can anyone please explain what's going on?

Accedi per commentare.

Risposta accettata

Aditya Sawant
Aditya Sawant il 22 Lug 2019
Your program is correct. But you are overlapping resultant matrix with input matrix which is creating proble.
For e.g. you have calculated avg pixel for w=1 and for location(1,1) which will store at same matrix at location(1,1). But for (1,2) while avg surrounding cells it will consider (1,1) location of matrix B where on location(1,1) you saved your result/output value not input value.
So just create new output matrix like mentioned below. Hope it will help you.
function output = blur(img,w)
B=double(img);
[m,n] = size(B);
k=2*w+1;
for i = 1:m
for j = 1:n
p=i-fix(k/2);
q=i+fix(k/2);
r=j-fix(k/2);
s=j+fix(k/2);
if p<1
p=1;
end
if q>m
q=m;
end
if r<1
r=1;
end
if s>n
s=n;
end
A=B([p:q],[r:s]);
C(i,j)=mean(A(:));
end
end
output=uint8(C);
end
  11 Commenti
Conor Simpson
Conor Simpson il 21 Mar 2022
I used this function in an upcoming publication and am wondering how I could go about giving you credit through referencing this?
Thanks,
Conor

Accedi per commentare.

Più risposte (13)

Vishal Lodha
Vishal Lodha il 8 Mag 2020
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
try this up
  2 Commenti
Walter Roberson
Walter Roberson il 9 Mag 2020
Do this for each distinct pixel in an image:
Think about a box that is 2*w+1 by 2*w+1 that is centered around the current pixel; for example if w is 2 then that would be a 5 x 5 box with two "before" and two "after" the current pixel, left/right and up/down. Take the average (mean) of those (2*w+1)^2 pixels, and that is the output for the current pixel.
In the case where the pixel is close to an edge, only count the pixels that are inside the box. For example when the current pixel is the location marked with * and w is 2, then include only the pixels marked with Y and * in the average, and not the ones marked with N.
Y*YYNNN
YYYYNNN
YYYYNNN
NNNNNNN

Accedi per commentare.


Walter Roberson
Walter Roberson il 21 Lug 2019
A=B([p:q],[r:s]);
B(i,j)=mean(A(:));
You are overwriting B as you go. You should be storing into a different array than you are using as the source to calculate the values,
  3 Commenti

Accedi per commentare.


Arafat Roney
Arafat Roney il 10 Mag 2020
Modificato: Arafat Roney il 10 Mag 2020
help me finding out the error....this shows "The server timed out while running and assessing your solution.''
function output=blur(img,w)
s=(2*w)+1; %SUB-MATRIX MATRIX DIMENSION
img=double(img); %CONVERTED TO DOUBLE FOR CALCULATIONS
[p,q]=size(img); %SIZE CALCULATED
m=[]; %INITIALIZED TO EMPTY MATRIX FOR OUTPUT MATRIX CALCULATION
for ii=1:p %OUTPUT MATRIX ROR CONTROL
row=[]; %CALCULATES EVERY ROW OF THE OUTPUT
for jj=1:q %OUTPUT MATRIX COLUMN CONTROL
sub=[]; %SUB-MATRIX WHICH IS USED TO CALCULATE MEAN
for i=1:s
sub1=[]; %ALL THE ELEMENTS OF THE ROW ARE STORED IN EVERY STEP
for j=1:s
y=ii-w+i-1;
z=jj-w+j-1;
if (y<1||y>p||z<1||z>q) %IF INDEX IS NOT VALID THEN WE TAKE EMPTY MATRIX
a=[];
else
a=img(y,z); %IF INDEX IS VALID THEN WE TAKE VALUES FROM THE 'img' MATRIX
end
sub1=[sub1 a]; %ROW OF THE SUB-MATRIX
end
sub=[sub sub1]; %SUB-MATRIX
end
b=mean(sub); %MEAN CALCULATED
row=[row b]; %ROW CALCULATED FROM ALL THE LOOPS
end
m=[m; row]; %FINAL MATRIX
end
output=uint8(m); %FINAL MATRIX CONVERTED TO 'uint8'
end
  1 Commento
Walter Roberson
Walter Roberson il 10 Mag 2020
It is not efficient to grow an array in place.
You should pre-allocate sub1 as the maximum possible size, 1 x s, and keep track of how many items are actually used, like
sub1 = zeros(1,s);
sub1c = 0;
for j = 1 : s
y=ii-w+i-1;
z=jj-w+j-1;
if y >= 1 && y <= p && z >= 1 && z <= q
sub1c = sub1c + 1;
sub1(sub1c) = img(y,z);
end
end
sub1 = sub1(1:subs1c);
You can extend this to deal with all of the information you would put into sub, using only one array of length s*s, without having to extend anything in place.
But after that I would point out that you do not need to store all of those values: you can just keep a running total of them as you go, along with a counter of how many you have, and then afterwards the mean is just the running total divided by the counter.

Accedi per commentare.


Prashant Dubey
Prashant Dubey il 10 Mag 2020
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
  9 Commenti
Chandan Kumar
Chandan Kumar il 18 Mar 2021
Well, consider taking the mean of uint8([128 128 128 128]). If you do it by taking uint8(128)+uint8(128)+uint8(128)+uint8(128) then you get uint8(255) because addition of uint8 "saturates" at 255. Then uint8(255)/4 would be 64.. hardly what you would expect
didnt understand this one please some explanation please

Accedi per commentare.


Akhil Thomas
Akhil Thomas il 16 Mag 2020
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
  1 Commento
Fam Kuong
Fam Kuong il 30 Mag 2020
function output=blur(img,w)
[row,colum]=size(img);
img=double(img);
output=zeros(row,colum);
for i=1:row
sub_row_left=max(1,i-w);
sub_row_right=min(row,i+w);
for j=1:colum
sub_colum_top=max(1,j-w);
sub_colum_bottom=min(colum,j+w);
B=img(sub_row_left:sub_row_right,sub_colum_top:sub_colum_bottom);
aver=uint8(mean(B(:)));
output(i,j)=aver;
end
end
output=uint8(output);
end

Accedi per commentare.


Shiladittya Debnath
Shiladittya Debnath il 27 Lug 2020
Function :
function output = blur(img,w)
B=double(img);
[m,n] = size(B);
k=2*w+1;
for i = 1:m
for j = 1:n
p=i-fix(k/2);
q=i+fix(k/2);
r=j-fix(k/2);
s=j+fix(k/2);
if p<1
p=1;
end
if q>m
q=m;
end
if r<1
r=1;
end
if s>n
s=n;
end
A=B([p:q],[r:s]);
C(i,j)=mean(A(:));
end
end
output=uint8(C);
end
  1 Commento
Chandan Kumar
Chandan Kumar il 18 Mar 2021
if p<1
p=1;
end
if q>m
q=m;
end
if r<1
r=1;
what if i change the values from 1 to 1.5

Accedi per commentare.


Shiladittya Debnath
Shiladittya Debnath il 27 Lug 2020
Code to CALL YOUR FUNCTION :
img = imread('vandy.png');
output = blur(img,2);
imshow(output);

Mati Somp
Mati Somp il 7 Ott 2020
lots of interesting codes, here is mine:
function out = blur(img,w);
D = double(img) ;
[row,col]=size(D);
out1=zeros([row,col]);
for a=1:row
for b=1:col
c=a-w;
c(c<1)=1;
d=a+w;
d(d>row)=row;
e=b-w;
e(e<1)=1;
f=b+w;
f(f>col)=col;
out1(a,b)=mean(mean(D(c:d,e:f)));
end
end
out=uint8(out1);

Abdul Quadir Khan
Abdul Quadir Khan il 6 Nov 2020
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

Mohamed El Nageeb
Mohamed El Nageeb il 22 Dic 2020
that's my answer,i know it's quite complicated for a simple problem but am just a beginner.it works fine for w=1, but for any other value it gives a wrong answer.So what's wrong here.
function output = blur(img,w)
[r , c]= size(img);
output=zeros(r,c);
if w== 0
output=uint8(img);
return
end
img = double(img);
for ii = 1:r
for jj= 1:c
n=1;
output(ii,jj)=img(ii,jj);
x = 1;
while (jj-x)>0 && x<=w
output(ii,jj) = output(ii,jj) + img(ii,jj-x);
n=n+1;
if (ii+x) <= r
output(ii,jj) = output(ii,jj) + img(ii+x,jj-x);
n=n+1;
end
if (ii-x) > 0
output(ii,jj) = output(ii,jj) + img(ii-x,jj-x);
n=n+1;
end
x=x+1;
end
x = 1;
while (jj+x)<=c && x<=w
output(ii,jj) = output(ii,jj) + img(ii,jj+x);
n=n+1;
if (ii+x) <= r
output(ii,jj) = output(ii,jj) + img(ii+x,jj+x);
n=n+1;
end
if (ii-x) > 0
output(ii,jj) = output(ii,jj) + img(ii-x,jj+x);
n=n+1;
end
x=x+1;
end
x=1;
while (ii-x)>0 && x<=w
output(ii,jj) =output(ii,jj) + img(ii-x,jj);
n=n+1;
x=x+1;
end
x=1;
while (ii+x)<=r && x<=w
output(ii,jj) =output(ii,jj) + img(ii+x,jj);
n=n+1;
x=x+1;
end
output(ii,jj) =(output(ii,jj)/n);
end
end
output = uint8(output);

绵辉 翁
绵辉 翁 il 31 Lug 2021
function output = blur(img,w)
copyimg = double(img);
for ii = 1:size(img,1)
for jj = 1:size(img,2)
array = zeros(2*w+1,2*w+1)-1;
for kk = -w:w
for ll = -w:w
if ii+kk<=0||ii+kk>size(img,1)||jj+ll<=0||jj+ll>size(img,2)
continue;
else
array(kk+w+1,ll+w+1) = img(ii+kk,jj+ll);
end
end
end
array = array(array~=-1);
num = mean(array);
copyimg(ii,jj) = num;
end
end
output = uint8(copyimg);

Aziz ur Rehman
Aziz ur Rehman il 12 Feb 2023
Modificato: Aziz ur Rehman il 12 Feb 2023
I wrote this code. but its a different approach to solving the problem. The picture does blur to some extent. how will i be able to optimize the code or is this approach even applicable?
function output=blur(img,w)
img=double(img); % converting to double.
[row col]=size(img);
A=2*w+1; % creating the row and column dimensions of the submatrix
%Output zero matrix
output=zeros(row,col);
% First creating a matrix with rows equel to A, and all columns.
for i=0:A:row-A
row_mat=img(i+1:i+A,:);
for j=0:A:col-A
sub_mat=row_mat(:,j+1:j+A); %creating a submatrix by sectioning the row_mat matrix.
% finding the mean value and assigning the value to the output matrix.
mean_value=mean(mean(sub_mat));
output(i+1:i+A,j+1:j+A)=ones(A,A)*mean_value;
end
end
% output conversion.
output=uint8(output);
output=output;
Original picture is
The code that i used is
img = imread('vandy.png');
output = blur(img,2);
imshow(output);
the blurred image is
  1 Commento
DGM
DGM il 12 Feb 2023
That's not really what I would call "blurring", though for some reason people seem to call all sorts of things "blurring".
You can shave a bit more time off:
mean_value = sum(sub_mat(:))/A^2; % faster than two calls to mean()
output(i+1:i+A,j+1:j+A) = mean_value; % no need for explicit expansion

Accedi per commentare.


昱安 朱
昱安 朱 il 18 Mar 2023
function output = blur(img,w)
[row_img,col_img]=size(img);
output=zeros(row_img,col_img);
imgd=double(img); % must convert img to double first for calculate
for ii=1:row_img
for jj=1:col_img
sumi=0; %sumi:sum of all valid element
counti=0; %number of valid element
for subrow=ii-w:ii+w %calculate each number
if subrow<1
continue; %if row is not valid,go to the next
end
if subrow>row_img
continue;
end
for subcol=jj-w:jj+w %then see col
if subcol<1
continue; %if col is not valid,go to the next
end
if subcol>col_img
continue;
end
sumi=sumi+imgd(subrow,subcol); %if row and col are all valid
counti=counti+1;
end
end
output(ii,jj)=sumi/counti;
end
end
output=uint8(output);

Community Treasure Hunt

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

Start Hunting!

Translated by