OpenCV单应性变换,转换一个点,这段代码在做什么?

18
我正在使用OpenCV计算的单应矩阵。我目前使用下面的函数来使用这个单应矩阵转换点。尽管这个函数能完成我需要的任务,但是我不知道它是如何工作的。
有人可以解释一下代码的最后三行的逻辑/理论吗?我知道这个函数可以转换点x,y,但是我不清楚它为什么有效:
为什么以这种方式计算Zpxpyh中的元素代表什么?
非常感谢您的帮助 :)
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);
2个回答

35

cvFindHomography()使用齐次坐标返回一个矩阵:

齐次坐标在计算机图形学中非常普遍,因为它们允许将常见操作(如平移、旋转、缩放和透视投影)实现为矩阵运算。

代码中发生了什么: 笛卡尔点p_origin_cartesian(x,y)被转换为齐次坐标,然后应用3x3透视变换矩阵h,最后将结果转换回笛卡尔坐标p_transformed_cartesian(px,py)

更新

详细说明:

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;

z是三维齐次坐标系中的第三个坐标。在此不详细解释齐次坐标系的工作原理。但是,p_homogenous(x,y,z)对应于p_cartesian(x / z,y / z)。 - Ben
我刚刚编辑了我的答案,现在你的代码应该清楚地说明了发生了什么。 - Ben
好的,如果是tx/tz,为什么代码中是tx * Z呢?我想我已经回答了自己的问题,tx * Z和tx/tz是一样的吗? - Jayson
1
是的。txZ = tx(1/tz) = tx/tz ;) - Ben

6

根据@Ben的回答,实现了OpenCV的Python版本。

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]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接