Точки деформации на плоскости

Точка :: (x y) известна.

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

Теперь я хочу узнать окончательные координаты всех точек внутри треугольной области.

На рисунке ниже показаны точки в начальном и конечном положениях.

введите здесь описание изображениявведите здесь описание изображения

Может ли кто-нибудь сказать мне, как это сделать на платформе OpenCV и C++?

Могу ли я сделать это и для контура произвольной формы?


person 2vision2    schedule 27.02.2013    source источник


Ответы (2)


Я использую 3D-координаты для учета

  • перевод по вектору [u v]
  • 2D линейное преобразование, сделанное matrixabcd

Общая матрица преобразования будет иметь вид

    [ a b u]
M = [ c d v]
    [ 0 0 1]
  1. Возьмите 3 точки A=[x1 y1 1] и B=[x2 y2 1] и C=[x3 y3 1] из треугольника
  2. Сравните их с их положением после трансформации A' = [x1' y1' 1] и B'=[x2' y2' 1] и C'=[x3' y3' 1]. Id est: Посчитайте, чтобы получить матрицу преобразования M так, чтобы A' = M A и B' = M B и C' = M C
  3. Применить x -> M x к каждой входной точке

Изменить: включить перевод в матрицу M, используя Перевод в матрице преобразования

Изменить: кажется, что «сделайте свою математику» для вас неясно.

Вы поймете, что 3 уравнения могут быть записаны как:

[x1' x2' x3']     [x1 x2 x3]
[y1' y2' y3'] = M [y1 y2 y3]
[1   1   1  ]     [1  1  1 ]

or

X' = M X

Or

M = X . X'^-1

и да, в OpenCV есть функция inv() для матриц.

person rds    schedule 27.02.2013
comment
Теперь у меня есть 6 неизвестных переменных (4 в M и 2 в T) и 6 уравнений (по 2 на каждое преобразование * 3 преобразования). Все звучит хорошо :) - person rds; 27.02.2013
comment
Спасибо за редактирование :: Можете ли вы также подсказать мне, как решать уравнения с помощью OpenCV... - person 2vision2; 27.02.2013
comment
@ 2vision2 Какой у вас вопрос, когда вы применяете это к CvMat и CvPoint ? - person rds; 27.02.2013
comment
Извините, я не понял вас... Я повторю свой вопрос... Мне нужно решить 6 переменных и 6 уравнений.. Как мне это сделать в OpenCV?? Есть ли какая-нибудь функция для этого?? - person 2vision2; 27.02.2013
comment
Существует cv::solve(), который явно делает то, что вы хотите. Вы также можете использовать Mat::inv(), который использует тот же механизм. - person comingstorm; 13.03.2013

Математически это можно сделать, вычислив барицентрические координаты каждой точки в исходном треугольнике и вернув их обратно к положению, используя новые координаты:

given initial triangle vertices A, B, and C, and point p,
find barycentric coordinates (a,b,c) such that a+b+c=1 and p = a*A + b*B + c*C:
  -> solve  [A.x B.x C.x]   [a]     [p.x]
            [A.y B.y C.y] * [b]  =  [p.y]
            [ 1   1   1 ]   [c]     [ 1 ]

then, given new vertices D, E, and F,
resulting point q = a*D + b*E + c*F:
  -> compute  [q.x]  =  [D.x E.x F.x] * [a]
              [q.y]     [D.y E.y F.y]   [b]
                                        [c]

Итак, в OpenCV:

float p_data[3] =
  { p.x,
    p.y,
    1.0
  };
Mat_<float> p(3, 1, p_data);

float m_data[9] =
  { A.x, B.x, C.x,
    A.y, B.y, C.y,
    1.0, 1.0, 1.0
  };
Mat_<float> M(3, 3, m_data);

Mat_<float> bary(3,1);
cv::solve(M, p, bary, DECOMP_LU);

float n_data[6] =
  { D.x, E.x, F.x,
    D.y, E.y, F.y
  };
Mat_<float> N(2, 3, n_data);

Mat_<float> result(2,1) = N * bary;

Чтобы сопоставить point_count точек одновременно, установите количество столбцов p, bary и result на point_count вместо 1 (при этом соответственно увеличив размер p_data и т. д.)

В зависимости от приложения может быть более удобным/эффективным сначала явно вычислить аффинную матрицу и применить ее напрямую:

Mat_<float> Affine = N * M.inv();
Mat_<float> result = Affine * p;
person comingstorm    schedule 28.02.2013