2012-06-05 4 views
6

Я ищу подходящую плоскость к набору ~ 6-10k 3D-точек. Я стараюсь сделать это как можно быстрее, и точность не является наивысшей проблемой (откровенно говоря, плоскость может быть на +10 градусов в любой из кардинальных осей).Ускоренное плоское прилегание ко многим точкам

Мой нынешний подход - использовать наилучшее из лучших, но он невероятно медленный (я надеюсь извлечь самолеты со скоростью примерно 10-50 килограмм каждый раз, когда я запускаю алгоритм, и при таком значении он завершит в неделях, в отличие от часов), поскольку он работает во всех возможных комбинациях из 6000 пунктов, поэтому ~ 35 000 000 000 итераций, и, откровенно говоря, он имеет гораздо более высокую точность, чем мне нужно.

Кто-нибудь знает о каких-либо более слабых методах крепления самолета, которые могут значительно ускорить мой алгоритм?

EDIT:

мне удалось получить число итераций до ~ 42k путем создания плоскостей в каждом возможном 3D угол (пошагового на 5 градусов каждый раз) и тестирование существующих точек против них, чтобы найти лучшая плоскость, вместо того, чтобы подгонять плоскости к точкам, которые у меня есть.

Я уверен, что здесь есть что-то, что можно разделить и победить, хотя я волнуюсь, что могу прыгнуть прямо через лучший самолет.

+0

У вас есть доступ к [Curve Место Toolbox] (Http: //www.mathworks. ком/помощь/набор инструментов/CurveFit/brviv3f-1.html # bs1cj4_-1)? – kevlar1818

+0

К сожалению, нет, я застрял с ванильным MATLAB, хотя у меня много опыта программирования в целом, поэтому я должен уметь обрабатывать довольно сложный алгоритм. –

+4

Если точность не является вашей основной задачей, попробуйте уменьшить сложность ввода данных. Запустите kmeans или что-то в исходном наборе 6-10k точек, а затем установите плоскость на образцы. – Ansari

ответ

13

Используйте стандартное уравнение плоской Ax + By + Cz + D = 0, и записать уравнение в виде матричного умножения. P это ваш неизвестный 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 

Теперь расширьте это все ваши фактические точки, матрицы NX4 G. Результат больше не равен 0, это ошибка, которую вы пытаетесь свести к минимуму.

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

Так что вы хотите ближайший вектор к нуль-пространстве G, которая может быть найдена из СВД. Тестирование:

% 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 

ОК, помните, что P может варьироваться в зависимости от скаляра. Так просто, чтобы показать, что мы сопоставляем:

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

ANS = 2,0000 3,0038 2.5037 -0.9997

1

Похоже, что griddata может быть тем, что вы хотите. В этом примере есть ссылка.

Если это не поможет, возможно, зарегистрируйтесь gridfit на MATLAB File Exchange. Это сделано для более общего случая, чем griddata.

Возможно, вы не хотите, чтобы вы наматывали свою собственную поверхность, так как есть несколько хорошо документированных инструментов.

Возьмем пример из 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 
+1

Большое спасибо, я сразу изучу это. Я, как правило, больше из CS-фона, поэтому моя математика по матовой поверхности немного отстает. Поэтому я более чем счастлив, если кто-то другой код выполнит задание –

+0

Хмм моя проблема с гриддата заключается в том, что для того, чтобы заставить его предоставить мне самолет, я должен (исходя из их первого примера) сказать ему генерировать zq, используя 4 точки в (-1, -1), (-1,1), (1, -1), (1,1) (используя 2: -2 - границы набора данных в примере - по какой-то причине возвращает NaN). К сожалению, это, по-видимому, гарантирует, что углы плоскости будут находиться в (-1, -1), (-1,1), (1, -1), (1,1) и, похоже, не принимают больше вопросов. Если я увеличиваю количество очков, я больше не получаю самолет. –

+0

@NickUdell Поместите код, который вы пробовали в ответ, чтобы я мог больше помочь вам. – kevlar1818

0

Вы можете попробовать consolidator Джоном D'Errico. Он объединяет точки в пределах данного допуска, что позволит уменьшить объем данных и увеличить скорость.Вы также можете проверить функцию John's gridfit, которая обычно быстрее и гибче, чем griddata

5

В компьютерном зрении стандартным способом является использование RANSAC или MSAC в вашем случае;

  1. Принимать 3 случайных точек из популяции
  2. Вычислить плоскости, определяемой точками 3
  3. Sum ошибки (расстояние до плоскости) для всех точек в этой плоскости.
  4. Держите 3 точки, которые показывают наименьшую сумму ошибок (и попадают в порог).
  5. Повторите N итераций (? См теорию RANSAC выбрать N, я могу предложить 50)

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