如何计算两次透视变换后的结果?
Posted
技术标签:
【中文标题】如何计算两次透视变换后的结果?【英文标题】:How to compute the result after two perspective transformations? 【发布时间】:2021-08-10 19:50:42 【问题描述】:我正在使用 OpenCV 进行图像拼接项目。现在我有了img1和img2之间的单应性H1,以及img2和img3之间的单应性H2。现在我需要计算 img1 和 img3 之间的单应性,简单地乘以 H1*H2 是行不通的。
有什么想法可以计算img1和img3之间的新单应性吗?
【问题讨论】:
同形异义词是定向的。假设 pX 是图像 X 中的一个像素,HX 是从 imageX 到 imageX-1 的单应性,那么例如 p1=H1*p2 和 p2=H2*p3;那么 p1 = H1*H2*p3;您可以通过反转单应矩阵来反转方向。你能举例说明他的图像和单应性在你的情况下是什么样子的吗? 我有两个单应性:第一个是` ([[1.0e+00, 0.0e+00, 1.8e+03], [0.0e+00, 1.0e+00, 5.0e +01], [0.0e+00, 0.0e+00, 1.0e+00]])` 另一个是([[ 9.49534471e-01, -5.81765975e-03, 6.67917766e+01], [-1.13810490e-02, 9.81450515e-01, -6.72362563e-01], [-1.47974585e-04, 9.92770511e-06, 1.00000000e+00]])
如果我只是简单地将它们相乘,这不是我需要的结果。我不确定您所说的“通过反转单应矩阵来反转方向”是什么意思?
你的 H1 和 H2 方向是哪个方向,你是从 image1 向 H1 馈送点还是从 image2 向 H1 馈送图像?
好的,知道了。 H1是从img2到img1,H2是从img3到img2。现在我需要从 img3 到 img1 的新单应性。
【参考方案1】:
对我来说,计算 H1 * H2
效果很好并给出了正确的结果。
在这里,H1 = H2_1
因为它从 image2 扭曲到 image1。
H2 = H3_2
因为它从 image3 扭曲到 image2。
H1 * H2 = H3_1
因为它从 image3 扭曲到 image 1。
int main()
try
cv::Mat H2_1 = (cv::Mat_<double>(3, 3) << 1.0e+00, 0.0e+00, 1.8e+03, 0.0e+00, 1.0e+00, 5.0e+01, 0.0e+00, 0.0e+00, 1.0e+00);
cv::Mat H3_2 = (cv::Mat_<double>(3, 3) << 0.949534471, -0.00581765975, 66.7917766, -0.0113810490, 0.981450515, -0.672362563, -0.000147974585, 0.00000992770511, 1.0);
cv::Mat H3_1 = H2_1 * H3_2;
cv::Point2f p3(500, 500);
std::vector<cv::Point2f> src3;
src3.push_back( p3 );
src3.push_back(p3);
std::vector<cv::Point2f> dst2;
cv::perspectiveTransform(src3, dst2, H3_2);
std::cout << "p1: " << p3 << std::endl;
std::cout << "p2: " << dst2[0] << std::endl;
std::vector<cv::Point2f> dst1;
cv::perspectiveTransform(dst2, dst1, H2_1);
std::cout << "p1 from p2: " << dst1[0] << std::endl;
dst1.clear();
cv::perspectiveTransform(src3, dst1, H3_1);
std::cout << "p1 from p3: " << dst1[0] << std::endl;
catch (std::exception& e)
std::cout << e.what() << std::endl;
std::cin.get();
结果:
【讨论】:
谢谢。 'perspectiveTransform()' 是否与 'warpPerspective()' 相同,因为在这种情况下,我需要使用 python 使用它们的匹配点缝合图像。 warpPerspective 使用相同类型的变换来根据像素位置变换像素值。 perspectiveTransform 仅转换像素位置列表。因此,如果您将 warpPerspective 与 H3_1 一起使用,您可以将 image3 扭曲到 image1。如果你使用带有 H3_1 的 perspectiveTransform,你可以得到一个从 image3 到 image1 的坐标列表。 谢谢。在我的任务中。我使用 warpimg1 = cv2.warpPerspective(img2, H2_1,(600, 240)) 将 image2 与 image1 对齐,它可以工作。但是对于 warpimg2 = cv2.warpPerspective(img3, H2_1*H3_2,(600, 240)),当我将第三张图像与 1 张图像对齐时,它不起作用。我试过你的代码,它很好,但是为什么在这种情况下它是错误的。我错过了什么吗? 这仅在 H2_1 从 image1 到 image2(而不是从 image2 到 image1)扭曲时才有意义,所以您的方向可能是相反的,这意味着您可能必须改为执行 H2*H1的 H1*H2 以结合两种转换。 谢谢我突然意识到我应该使用np.matmul()而不是np.multiply()。哈哈以上是关于如何计算两次透视变换后的结果?的主要内容,如果未能解决你的问题,请参考以下文章