我想从OpenCV的findHomography
函数返回透视变换矩阵,并将其转换(在C ++或Objective-C中)到iOS'CATransform3D
。我希望它们尽可能地准确地再现核心图形方面的“扭曲”效果。示例代码真的很感激!
来自iOS'CATransform3D.h:
/* Homogeneous three-dimensional transforms. */
struct CATransform3D
{
CGFloat m11, m12, m13, m14;
CGFloat m21, m22, m23, m24;
CGFloat m31, m32, m33, m34;
CGFloat m41, m42, m43, m44;
};
类似的问题:
答案 0 :(得分:5)
<强>声明强>
我从来没有尝试过这种方式,所以请耐心等待。
CATRansform3D是一个4x4矩阵,它在3维齐次矢量(4x1)上运算,以产生相同类型的另一个矢量。我假设在渲染时,4x1向量描述的对象将每个元素除以第4个元素,而第3个元素仅用于确定哪些对象出现在其中。假设这是正确的......
<强>推理强>
findHomography返回的3x3矩阵在2维均匀向量上运行。可以通过4个步骤考虑该过程
您需要在4x4向量中复制此过程,其中我假设结果向量中的第3个元素对于您的目的而言毫无意义。
<强>解决方案强>
像这样构造你的矩阵(H是你的单应矩阵)
[H(0,0), H(0,1), 0, H(0,2),
H(1,0), H(1,1), 0, H(1,2),
0, 0, 1, 0
H(2,0), H(2,1), 0, H(2,2)]
这显然满足1,2和3. 4因为均匀元素总是最后一个。这就是为什么“同质排”,如果你不得不被撞到一行。第3行的1是让向量的z分量通过unmolested。
以上所有内容都以行主要表示法(如openCV)完成,以避免混淆。您可以查看Tommy的答案,了解转换为专业列的外观(基本上只是转置它)。但请注意,目前Tommy和我不同意如何构建矩阵。
答案 1 :(得分:3)
在阅读文档时,m11
中的CATransform3D
相当于a
中的CGAffineTransform
,m12
相当于b
,等等。
根据你在下面的评论,我理解矩阵OpenCV返回3x3(回想起来,它是你期望的大小)。因此,您将使用与单位矩阵等效的元素填充其他元素。根据Hammer的回答,你想要保留处理(通常是隐含的)同质坐标的部分,同时用身份填充其他所有内容。
[旁白:我原来的回答是错误的。我编辑它是正确的,因为我发布了代码而Hammer没有。这篇文章被标记为社区维基,以反映它绝不仅仅是我的答案]
所以我认为你想要:
CATransform3D MatToTransform(Mat cvTransform)
{
CATransform3D transform;
transform.m11 = cvTransform.at<float>(0, 0);
transform.m12 = cvTransform.at<float>(1, 0);
transform.m13 = 0.0f;
transform.m14 = cvTransform.at<float>(2, 0);
transform.m21 = cvTransform.at<float>(0, 1);
transform.m22 = cvTransform.at<float>(1, 1);
transform.m23 = 0.0f;
transform.m24 = cvTransform.at<float>(2, 1);
transform.m31 = 0.0f;
transform.m32 = 0.0f;
transform.m33 = 1.0f;
transform.m34 = 0.0f;
transform.m41 = cvTransform.at<float>(0, 2);
transform.m42 = cvTransform.at<float>(1, 2);
transform.m43 = 0.0f;
transform.m44 = cvTransform.at<float>(2, 2);
return transform;
}
如果您要保留C ++,请使用cvGetReal1D
。
答案 2 :(得分:0)
Tommy答案对我有用,但是我需要使用double而不是float。这也是代码的简化版本:
CATransform3D MatToCATransform3D(cv::Mat H) {
return {
H.at<double>(0, 0), H.at<double>(1, 0), 0.0, H.at<double>(2, 0),
H.at<double>(0, 1), H.at<double>(1, 1), 0.0, H.at<double>(2, 1),
0.0, 0.0, 1.0, 0.0,
H.at<double>(0, 2), H.at<double>(1, 2), 0.0f, H.at<double>(2, 2)
};
}