Slash
Slash

Reputation: 295

Operations within matrix avoiding for loops

I have a rather simple question but I can't get the proper result in MATLAB.

I am writing a code in Matlab where I have a 200x3 matrix. This data corresponds to the recording of 10 different points, for each of which I took 20 frames.

This is just in order to account for the error in the measuring system. So now I want to calculate the 3D coordinates of each point from this matrix by calculating an average of the measured independent coordinates.

An example (for 1 point with 3 measurements) would be:

MeasuredFrames (Point 1) =
   x         y         z
1.0000    2.0000    3.0000
1.1000    2.2000    2.9000
0.9000    2.0000    3.1000

Point = mean(MeasuredFrames(1:3, :))

Point =

1.0000    2.0667    3.0000

Now I want to get this result but for 10 points, all stored in a [200x3] array, in intervals of 20 frames.

Any ideas?

Thanks in advance!

Upvotes: 4

Views: 69

Answers (3)

Mohsen Nosratinia
Mohsen Nosratinia

Reputation: 9864

Matrix multiplication can be used:

N=20; 
L=size(MeasuredFrames,1); 
Points = sparse(ceil((1:L)/N), 1:L, 1)*MeasuredFrames/N;

Upvotes: 0

Robert Seifert
Robert Seifert

Reputation: 25232

If you have the Image processing toolbox blockproc could be an option:

A = blockproc(data,[20 3],@(x) mean(x.data,1))

If not the following using permute with reshape works as well:

B = permute(mean(reshape(data,20,10,3),1),[2,3,1])

Explanation:

%// transform data to 3D-Matrix 
a = reshape(data,20,10,3);
%// avarage in first dimension
b = mean(a,1);
%// transform back to 10x3 matrix
c = permute(b,[2,3,1])

Some sample data:

x = [ 1.0000    2.0000    3.0000
      1.1000    2.2000    2.9000
      0.9000    2.0000    3.1000
      1.0000    2.0000    3.0000
      1.1000    2.2000    2.9000
      0.9000    2.0000    3.1000
      1.0000    2.0000    3.0000
      1.1000    2.2000    2.9000
      0.9000    2.0000    3.1000
      1.1000    2.2000    2.9000]
data = kron(1:20,x.').';  

    A = B =

    1.5150    3.1200    4.4850
    3.5350    7.2800   10.4650
    5.5550   11.4400   16.4450
    7.5750   15.6000   22.4250
    9.5950   19.7600   28.4050
   11.6150   23.9200   34.3850
   13.6350   28.0800   40.3650
   15.6550   32.2400   46.3450
   17.6750   36.4000   52.3250
   19.6950   40.5600   58.3050

Upvotes: 4

Hoki
Hoki

Reputation: 11792

If you do not have access to the blockproc function, you can do it with a combination of reshape:

np = 20 ;                       %// number of points for averaging

tmp = reshape( A(:) , np,[] ) ; %// unfold A then group by "np"
tmp = mean(tmp);                %// calculate mean for each group
B   = reshape(tmp, [],3 ) ;     %// reshape back to nx3 matrix

In your case, replace A by MeasuredFrames and B by Points, and group in one line:

Points = reshape(mean(reshape( MeasuredFrames (:) , np,[] )), [],3 ) ; 

Upvotes: 2

Related Questions