OpenCV Homography, Transform point, что делает этот код?
Я работаю с гомографией, рассчитанной OpenCV. В настоящее время я использую эту гомографию для преобразования точек, используя приведенную ниже функцию. Эта функция выполняет требуемую задачу, но я не знаю, как она работает.
Может ли кто-нибудь объяснить, точно по строкам логику/теорию за последними 3 строками кода, я понимаю, что это преобразует точку x, y, но я не понимаю, почему это работает:
Почему Z
, px
и py
вычисляются таким образом, что соответствуют элементам в h
?
Ваши комментарии очень благодарны:)
double h[9];
homography = cvMat(3, 3, CV_64F, h);
CvMat ps1 = cvMat(MAX_CALIB_POINTS/2,2,CV_32FC1, points1);
CvMat ps2 = cvMat(MAX_CALIB_POINTS/2,2,CV_32FC1, points2);
cvFindHomography(&ps1, &ps2, &homography, 0);
...
// This is the part I don't fully understand
double x = 10.0;
double y = 10.0;
double Z = 1./(h[6]*x + h[7]*y + h[8]);
px = (int)((h[0]*x + h[1]*y + h[2])*Z);
py = (int)((h[3]*x + h[4]*y + h[5])*Z);
Ответы
Ответ 1
cvFindHomography()
возвращает матрицу, используя однородные координаты:
Однородные координаты повсеместны в компьютерной графике, потому что они позволяют реализовать такие операции, как трансляция, вращение, масштабирование и перспективная проекция в виде матричных операций.
Что происходит в коде:
Декартова точка p_origin_cartesian(x,y)
преобразуется в однородные координаты, затем применяется матрица преобразования 3x3 h
, и результат преобразуется обратно в декартовы координаты p_transformed_cartesian(px,py)
.
UPDATE
Подробнее:
Преобразуйте p_origin_cartesian
в p_origin_homogenous
:
(x,y) => (x,y,1)
Преобразование перспективы:
p_transformed_homogenous = h * p_origin_homogenous =
(h0,h1,h2) (x) (h0*x + h1*y + h2) (tx)
(h3,h4,h5) * (y) = (h3*x + h4*y + h5) = (ty)
(h6,h7,h8) (1) (h6*x + h7*y + h8) (tz)
Преобразуйте p_transformed_homogenous
в p_transformed_cartesian
:
(tx,ty,tz) => (tx/tz, ty/tz)
Ваш перевод текста:
px = tx/tz;
py = ty/tz;
Z = 1/tz;
Ответ 2
Реализация OpenCV Python после ответа @Ben
p = np.array((x,y,1)).reshape((3,1))
temp_p = M.dot(p)
sum = np.sum(temp_p ,1)
px = int(round(sum[0]/sum[2]))
py = int(round(sum[1]/sum[2]))