Question

I have a point cloud from real world and I want to fit a surface on them and calculate curve of the points(!). since points are in the real world so amplitude of difference between x, y and z of points is very large and when I use the code in here I meet the below error in matlab:

Warning: Rank deficient, rank = 2,  tol =   7.9630e-007.

this means that my data are bad conditioned. a few of my data are:

32512032.3900000    5401399.69000000    347.030000000000
32512033.1400000    5401399.79000000    346.920000000000
32512036.3000000    5401399.62000000    346.840000000000
32512037.3900000    5401399.95000000    346.870000000000
32512034.4800000    5401400                 346.930000000000
32512035.6000000    5401400.05000000    346.950000000000
32512036.6900000    5401400.38000000    346.980000000000
32512037.9600000    5401400.30000000    346.910000000000
32512033.7600000    5401400.42000000    346.880000000000
32512034.8700000    5401400.48000000    346.960000000000

also I use the fit formula in matlab.

sf = fit( [x, y], z, 'poly23');

and saw the same error:

Warning: Equation is badly conditioned. Remove repeated data points
         or try centering and scaling.

Is a way that fit a surface or smooth curve on the this type of points?

Was it helpful?

Solution

Edit

You can try:

Centering

%% Centering
oldData = data
center = mean(data);
centerMatrix = ones(size(data,1),1)*center; 
data = data - centerMatrix;         

Scaling

%% Scaling
scale = max(abs(data));
scaleMatrix = ones(size(data,1),1)*scale;
data = data./scaleMatrix;

But don't forget at the end . . .

xx = scale(1)*xx + center(1)
yy = scale(2)*yy + center(2)
zz = scale(3)*zz + center(3)

Centering moves your data to the origin. Scaling makes the spread more equal, so you don't fit one axis much better than the others. You have to un-scale and un-center the results afterwards.

Centering is safe. It should do what you expect and make the result more stable. Scaling is not as safe. Make sure it gives you what you want; if centering is enough, you might find that is all you need.

In any case, because a point cloud is huge, you should apply this to local patches at a time.

Why I said "quick and dirty?" I meant quick as in quick to code. There are many publications that deal with this specifically, and they will run faster. Will they produce a better result? Well, it depends on what you define as better.

There isn't a lot of ground-truth data out there for real scanned environments, if you are talking about a scanning laser. If your point cloud is from something else (stereo vision, structure from motion) there are a lot more data sets you can try.

Without ground truth, it's hard to say what is "good" and "bad". Usually its pretty obvious. But point cloud manipulation is not trivial because of the quantities of data.

Old answer Centering is exactly what I would suggest if you want to try a quick and dirty solution using fit. Of course, you can't do this with all of your data at once, but if you select just a few local points (even a few hundred or thousand) and center it first, you should get a much better result.

The problem is occurring because the difference between any two of your points is tiny, but the magnitude of the vectors themselves is quite large. If you take your data, center it (you can even scale if you like), you can then fit it and reverse the operations. Do this for a chunk at a time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top