将OpenCV的findHomography透视matrix转换为iOS的CATransform3D

我想从OpenCV的findHomography函数返回的透视变换matrix,并将其转换(iOS或C的Objective-C)到iOS的CATransform3D 。 我希望他们尽可能地接近Core Graphics方面的“warp”效果。 示例代码真的很感谢!

从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; }; 

类似的问题:

使用Core Graphics应用单应性matrix

将一个opencv仿射matrix转换为CGAffineTransform

放弃

我从来没有尝试过,所以把它与一粒盐。

CATRansform3D是一个4×4的matrix,它在一个3维齐次向量(4×1)上运行,以产生相同types的另一个向量。 我假设在渲染时,由4×1向量描述的对象将每个元素除以第四个元素,而第三个元素仅用于确定哪个对象出现在其上。 假设这是正确的…

推理

findHomography返回的3x3matrix在2维齐次向量上运算。 这个过程可以分四步来考虑

  1. 单应性的第一列乘以x
  2. 单应性的第二列乘以y
  3. 单应性的第三列乘以1
  4. 得到的第一和第二vector元素被第三个分割

你需要这个过程被复制到一个4×4的向量中,在这个向量中,我假定结果向量中的第三个元素对于你的目的是没有意义的。

像这样构build你的matrix(H是你的单应matrix)

 [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是满意的,因为同质元素总是最后一个。 这就是为什么“同质排”,如果你将不得不碰到一条线。 第三行的1是让vector的z分量通过unmleted。

以上所有内容都是在行主要符号(如openCV)中完成的,以防止混淆。 你可以看看汤米的答案,看看如何转换到专栏看起来(你基本上只是转置它)。 但是请注意,目前汤米和我不同意如何构buildmatrix。

从我阅读的文档中, CATransform3D m11等同于CGAffineTransform m11m12等同于b等等。

根据您的评论,我知道matrixOpenCV返回到3×3(回想起来,这是你所期望的大小)。 所以你应该用等价于单位matrix的元素填充其他元素。 按照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; } 

或者使用cvGetReal1D如果你保持C ++的。

Interesting Posts