Математически это можно сделать, вычислив барицентрические координаты каждой точки в исходном треугольнике и вернув их обратно к положению, используя новые координаты:
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