Fast plane fitting to many points

送分小仙女□ 提交于 2019-11-29 04:36:42

Use the standard plane equation Ax + By + Cz + D = 0, and write the equation as a matrix multiplication. P is your unknown 4x1 [A;B;C;D]

g = [x y z 1];  % represent a point as an augmented row vector
g*P = 0;        % this point is on the plane

Now expand this to all your actual points, an Nx4 matrix G. The result is no longer exactly 0, it's the error you're trying to minimize.

G*P = E;   % E is a Nx1 vector

So what you want is the closest vector to the null-space of G, which can be found from the SVD. Let's test:

% Generate some test data
A = 2;
B = 3;
C = 2.5;
D = -1;

G = 10*rand(100, 2);  % x and y test points
% compute z from plane, add noise (zero-mean!)
G(:,3) = -(A*G(:,1) + B*G(:,2) + D) / C + 0.1*randn(100,1);

G(:,4) = ones(100,1);   % augment your matrix

[u s v] = svd(G, 0);
P = v(:,4);             % Last column is your plane equation

OK, remember that P can vary by a scalar. So just to show that we match:

scalar = 2*P./P(1);
P./scalar

ans = 2.0000 3.0038 2.5037 -0.9997

In computer vision a standard way is to use RANSAC or MSAC, in your case;

  1. Take 3 random points from the population
  2. Calculate the plane defined by the 3 points
  3. Sum the errors (distance to plane) for all of the points to that plane.
  4. Keep the 3 points that show the smallest sum of errors (and fall within a threshold).
  5. Repeat N iterations (see RANSAC theory to choose N, may I suggest 50?)

http://en.wikipedia.org/wiki/RANSAC

It looks like griddata might be what you want. The link has an example in it.

If this doesn't work, maybe check out gridfit on the MATLAB File Exchange. It's made to match a more general case than griddata.

You probably don't want to be rolling your own surface fitting, as there's several well-documented tools out there.

Take the example from griddata:

x = % some values 
y = % some values
z = % function values to fit to

ti = % this range should probably be greater than or equal to your x,y test values
[xq,yq] = meshgrid(ti,ti);
zq = griddata(x,y,z,xq,yq,'linear'); % NOTE: linear will fit to a plane!
Plot the gridded data along with the scattered data.

mesh(xq,yq,zq), hold
plot3(x,y,z,'o'), hold off

You may try the consolidator by John D'Errico. It aggregates the points within a given tolerance, this will allow to reduce the amount of data and increase the speed. You can also check John's gridfit function which is usually faster and more flexible than griddata

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!