Matrix addition and means
Show older comments
I am trying to take a matrix of any size , whether it has one row or 9, and write a function file that add the each element by its immediate neighbor then average it and replace. So if
a=[1,2,0,1]
the function would produce
ans =
1.5 1 1 .5
here is what I have so far, but for some reason it wont add the edges.
function [ b] = Avg_Num(a )
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
[r,c]=size(a);
if (r*c) == 1
b=a;
elseif r ==1
b(1,1)=(a(1,1)+a(1,2))/2;
for j= 2:(c-1)
b(1,j)=(a(1,j)+a(1,j-1)+a(1,j+1))/3;
b(1,max(j)+1)=(a(1,max(j))+a(1,max(j)+1))/2;
end
elseif r >1
b(1,1)=(a(1,1)+a(1,2)+a(2,2)+a(2,1))/4;
b(1,c)=(a(1,c)+a(1,c-1)+a(2,c)+a(2,c-1))/4;
b(r,1)=(a(r,1)+a(r-1,1)+a(r,2)+a(r-1,2))/4;
b(r,c)=(a(r,c)+a(r-1,c)+a(r-1,c-1)+a(r,c-1))/4;
for i=2 :(r-1)
for j=2:(c-1)
b(i,j)=(a(i,j)+a(i+1,j)+a(i-1,j)+a(i,j+1)+a(i,j-1)+a(i-1,j-1)+a(i-1,j+1)+a(i+1,j-1)+a(i+1,j+1))/9;
end
end
end
end
any ideas
1 Comment
Azzi Abdelmalek
on 11 Apr 2014
How did you get the result from a=[1,2,0,1] ?
Answers (1)
Image Analyst
on 11 Apr 2014
Edited: Image Analyst
on 11 Apr 2014
Wow. How would you like to do all that in a single line? If so, how about using convolution:
% First with a 1D "a"
a=[1,2,0,1];
output = conv2(a, [1, 1]/2, 'same')
% Now with a 2D "a" - use a 3 by 3 array to do the scanning.
windowSize = 3
a = magic(windowSize); % Sample data
output = conv2(a, [windowSize, windowSize]/windowSize^2, 'same')
12 Comments
Joseph Pauwels
on 11 Apr 2014
Joseph Pauwels
on 11 Apr 2014
Image Analyst
on 11 Apr 2014
Window size is how big you want the window to be. Like 9. It's usually an odd number because you want the output element to be at the center of the window. But it doesn't have to be, you'll just have a half-element shift otherwise.
'same' means that the window travels over the entire array and quits if the scanning widow is not centered over the last element. For example, what if the array was 10 wide and your window was 7 wide. When the center element of the window (#4) is over the last element of your array (#10), it quits. If you use 'valid, it quits when the scanning window's outer edge hits the outer edge of the array its scanning. If it's full, it will go until there are no more overlapping elements. For example the last over lap at 10, when the scanning kernel goes from element 10 to 16, but only the elements at 10 are overlapped. The elements under the kernel that are not part of the original array are assumed to be zero when it does the multiply and add. You need to know how you want to handle it when you have these situations, called "edge effects" or "boundary effects".
Joseph Pauwels
on 11 Apr 2014
Image Analyst
on 11 Apr 2014
Edited: Image Analyst
on 11 Apr 2014
What is your desired b? Are you doing 4 connected or 8 connected neighbors? In other word, North, south, east and west? Or do you want to include neighbors on the diagonals (NW, NE, SE, SW)? Try this:
a=[1,1 ,1 ,1 ,1;
1,2,3,1,1;
1,3,6,1,1;
8,1,6,2,2;
3,5,7,2,2;
4,9,2,2,2]
% Now with a 2D "a" - use a 3 by 3 array to do the scanning.
windowSize = 3
% 4 connected neighbors.
kernel = [0 1 0; 1 1 1; 0 1 0] / 5; % four connected
output4 = conv2(a, kernel, 'same')
% 8-connected
kernel = [1 1 1; 1 1 1; 1 1 1] / 9; % eight connected
output8 = conv2(a, kernel, 'same')
Joseph Pauwels
on 11 Apr 2014
Joseph Pauwels
on 11 Apr 2014
Image Analyst
on 11 Apr 2014
Yes, that's the 8 connected scenario. If you want different boundary conditions, experiment with 'same', 'valid', and 'full' - they give different size matrices. If you want the "window" to shrink when it gets to the edge, then you need to do things differently than conv2() which has a fixed size window. For example if you're on the last pixel and you want to average just the N,S,NW,W, and SW pixels (a 3 by 2 window) then let me know. It's a little trickier but is possible using sum() twice, so hopefully you don't want to do that. Actually what is your "use case" for this anyway?
Joseph Pauwels
on 11 Apr 2014
Image Analyst
on 11 Apr 2014
Then do it this way:
a= [1,1,1;
1,2,3;
1,3,6]
output=[1.25 1.50 1.75
1.5 2.11 2.6667
1.75 2.6667 3.5]
sum_Of_a = conv2(a, ones(3), 'same')
count_in_window = conv2(ones(size(a)), ones(3), 'same')
theMean = sum_Of_a ./ count_in_window % Same as "output"
Joseph Pauwels
on 12 Apr 2014
Image Analyst
on 12 Apr 2014
You're welcome. Can you mark the answer as "Accepted" then?
Categories
Find more on Descriptive Statistics in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!