Что является ближайшим эквивалентом функции fitgeotrans в 3D? [Дубликат]

На практике все переменные должны быть инициализированы перед их использованием.

Я не могу думать о времени, когда вы хотите использовать переменную перед ее значением (если вы не сравниваете ее с нуль).

1
задан Zheden 29 October 2014 в 17:05
поделиться

2 ответа

Ответ @rayryeng правильный, учитывая, что у вас есть набор до 3 точек в пространстве 3-dimensional. Если вам нужно преобразовать m точки в пространстве n-dimensional (m>n), вам сначала нужно добавить m-n координаты к этим m точкам, чтобы они существовали в пространстве m-dimensional (т.е. a ] в @rayryeng становится квадратной матрицей) ... Тогда процедура, описываемая @rayryeng, даст вам точное преобразование точек, тогда вам просто нужно выбрать только координаты преобразованных точек в исходном пространстве n-dimensional.

В качестве примера скажем, что вы хотите преобразовать точки:

(2 -2 2) -> (-3 5 -4)
(2 3 0) -> (3 4 4)
(-4 -2 5) -> (-4 -1 -2)
(-3 4 1) -> (4 0 5)
(5 -4 0) -> (-3 -2 -3)

Обратите внимание, что у вас есть m=5 точки, которые n=3 -мерны. Поэтому вам нужно добавить координаты в эти точки, чтобы они были n=m=5 -мерными, а затем применили процедуру, описанную @rayryeng.

Я реализовал функцию, которая делает это (найти ее ниже). Вам просто нужно организовать такие точки, чтобы каждая из исходных точек была столбцом в матрице u, и каждая из целевых точек является столбцом в матрице v. Матрицы u и v будут, таким образом, 3 на 5 каждый.

ПРЕДУПРЕЖДЕНИЕ:

  • матрица A в функции может потребоваться МНОГО памяти для умеренно большого количества точек nP, поскольку у него есть nP^4 элементы.
  • Чтобы преодолеть это, для квадратных матриц u и v вы можете просто использовать T=v*inv(u) или T=v/u в нотации MATLAB.
  • Код может работать очень медленно ...

В MATLAB:

u = [2 2 -4 -3 5;-2 3 -2 4 -4;2 0 5 1 0]; % setting the set of source points
v = [-3 3 -4 4 -3;5 4 -1 0 -2;-4 4 -2 5 -3]; % setting the set of target points
T = findLinearTransformation(u,v); % calculating the transformation

Вы может проверить, что T является правильным:

I = eye(5);
uu = [u;I((3+1):5,1:5)]; % filling-up the matrix of source points so that you have 5-d points
w = T*uu; % calculating target points
w = w(1:3,1:5); % recovering the 3-d points
w - v % w should match v ... notice that the error between w and v is really small

Функция, которая вычисляет матрицу преобразования:

function [T,A] = findLinearTransformation(u,v)
% finds a matrix T (nP X nP) such that T * u(:,i) = v(:,i)
% u(:,i) and v(:,i) are n-dim col vectors; the amount of col vectors in u and v must match (and are equal to nP)
%
    if any(size(u) ~= size(v))
        error('findLinearTransform:u','u and v must be the same shape and size n-dim vectors');
    end
    [n,nP] = size(u); % n -> dimensionality; nP -> number of points to be transformed
    if nP > n % if the number of points to be transform exceeds the dimensionality of points
        I = eye(nP);
        u = [u;I((n+1):nP,1:nP)]; % then fill up the points to be transformed with the identity matrix
        v = [v;I((n+1):nP,1:nP)]; % as well as the transformed points
        [n,nP] = size(u);
    end
    A = zeros(nP*n,n*n);
    for k = 1:nP
        for i = ((k-1)*n+1):(k*n)
            A(i,mod((((i-1)*n+1):(i*n))-1,n*n) + 1) = u(:,k)';
        end
    end
    v = v(:);
    T = reshape(A\v, n, n).';
end
1
ответ дан Girardi 17 August 2018 в 09:04
поделиться

Если я правильно истолковываю ваш вопрос, вы пытаетесь найти все коэффициенты в матрице 3D-преобразования, которые наилучшим образом деформируют одну точку на другую. Все, что вам действительно нужно сделать, это поставить эту проблему в линейную систему и решить. Напомним, что деформирование одной точки в другую в 3D просто:

A*s = t

s = (x,y,z) является исходной точкой, t = (x',y',z') является целевой точкой, а A будет матрицей преобразования 3 x 3, которая форматируется так, что:

A = [a00 a01 a02]
    [a10 a11 a12] 
    [a20 a21 a22]

Выписывая фактическую систему уравнений A*s = t, получаем:

a00*x + a01*y + a02*z = x'
a10*x + a11*y + a12*z = y'
a20*x + a21*y + a22*z = z'

Коэффициенты в A - это то, что нам нужно для решения. Переписывая это в матричной форме, получаем:

[x y z 0 0 0 0 0 0]   [a00]   [x']
[0 0 0 x y z 0 0 0] * [a01] = [y']
[0 0 0 0 0 0 x y z]   [a02]   [z']
                      [a10] 
                      [a11]
                      [a12]
                      [a20]
                      [a21]
                      [a22]

Учитывая, что у вас есть четыре точки, вы просто объединяете строки матрицы слева и вектор справа

[x1 y1 z1 0 0 0 0 0 0]   [a00]   [x1']
[0 0 0 x1 y1 z1 0 0 0]   [a01]   [y1']
[0 0 0 0 0 0 x1 y1 z1]   [a02]   [z1']
[x2 y2 z2 0 0 0 0 0 0]   [a10]   [x2']
[0 0 0 x2 y2 z2 0 0 0]   [a11]   [y2']
[0 0 0 0 0 0 x2 y2 z2]   [a12]   [z2']
[x3 y3 z3 0 0 0 0 0 0] * [a20] = [x3']
[0 0 0 x3 y3 z3 0 0 0]   [a21]   [y3']
[0 0 0 0 0 0 x3 y3 z3]   [a22]   [z3']
[x4 y4 z4 0 0 0 0 0 0]           [x4']
[0 0 0 x4 y4 z4 0 0 0]           [y4']
[0 0 0 0 0 0 x4 y4 z4]           [z4']

          S            *   a   =   T

S теперь будет матрицей, которая содержит ваши четыре точки источника в формате, показанном выше, a теперь является вектором коэффициентов преобразования в матрице, которую вы хотите решить (упорядоченно в строке format), а T - вектор целевых точек в формате, показанном выше.

Для решения этих параметров вам просто нужно использовать оператор mldivide или \ в MATLAB, который будет вычислять для вас оценку наименьших квадратов. Поэтому:

a = S^{-1} * T

По существу, просто создайте свою матрицу, как указано выше, затем используйте оператор \ для решения ваших параметров преобразования в вашей матрице. Когда вы закончите, измените форму T на матрицу 3 x 3. Поэтому:

S = ... ; %// Enter in your source points here like above
T = ... ; %// Enter in your target points in a right hand side vector like above

a = S \ T;
similarity_matrix = reshape(a, 3, 3).';

Что касается вашей ошибки при малых возмущениях каждой из координат, тем больше у вас очков. Использование 4, безусловно, даст вам решение, но этого недостаточно, чтобы смягчить любые ошибки, на мой взгляд.

Незначительное примечание. Это (более или менее) то, что fitgeotrans делает под капотом. Он вычисляет лучшую гомографию, учитывая кучу исходных и целевых точек, и определяет это с использованием наименьших квадратов.

Надеюсь, это ответили на ваш вопрос!

6
ответ дан rayryeng 17 August 2018 в 09:04
поделиться
  • 1
    Привет, спасибо за ответ. Но с 4 очками (у меня их больше нет) найду S-матрицу, которая не будет похожа. Верхняя левая часть 3х3 будет не вращением из-за ошибок в точках. Я хочу получить S, а затем исправить его (да, с некоторыми нелинейными методами) в матрицу с красивой частью вращения. Поэтому я думал, что для этого должны быть некоторые функции. – Zheden 30 October 2014 в 12:57
  • 2
    @Zheden - Вероятно, вы должны добавить эту информацию в свой пост. Без этой информации ваш вопрос вводит в заблуждение. Вы также должны добавить некоторые примеры данных и желаемый результат. Мы не здесь, чтобы угадать, что вы хотите. – rayryeng 30 October 2014 в 16:45
Другие вопросы по тегам:

Похожие вопросы: