栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

关于opencv(C++)中decomposeHomographyMat()与filterHomographyDecompByVisibleRefpoints()的使用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于opencv(C++)中decomposeHomographyMat()与filterHomographyDecompByVisibleRefpoints()的使用

前言

  最近遇到问题:需要通过单应矩阵H(homography)分解出相机的R和t。当然,在opencv的C++版本中封装有实现这个功能的函数(然而在其js版本中就去掉了,不知道为什么…)。

  但是,在opencv的官方文档中,函数的接口(输入输出参数)的参数类型全是清一色的Array或者ArrayOfArray。然而,opencv中Array的类型千千万,你如果用错了,他还会给你报错“内存X…… 出现错误”。

  下文将展示我摸索出的可行参数类型。

decomposeHomographyMat函数

  该函数可以通过单应矩阵求出可能的四组R和t,然而想得到真实解,还需要结合filterHomographyDecompByVisibleRefpoints函数。

  详细函数介绍见官方文档(我这里用的opencv3.4.15):

https://docs.opencv.org/3.4.15/d9/d0c/group__calib3d.html#ga7f60bdff78833d1e3fd6d9d0fd538d92

  可以看到,这个说明文档为该函数提供的接口可以说是相当绝望。于是我找到该函数源码,见:

https://github.com/opencv/opencv/blob/master/modules/calib3d/src/homography_decomp.cpp

  通过分析,下面直接放我使用这个函数时的代码:

	vector R, t, n;//旋转矩阵R、平移矩阵t、关键点所在平面的法向量n
	Mat homography_matrix = (Mat_(3, 3) << 1.020205, -0.297803580, 150.1813964, 0.305915176, 0.929503381, -9.5677337, 0.00021775, -0.000026478477, 1);
	Mat K = (Mat_(3, 3) << 20, 0, 320, 0, 20, 240, 0, 0, 1);//K是相机内参,这里我只知道光心,所以剩下的参数随便弄的。
	                                                                //这样做问题不大,只要保证光心对就行,毕竟最后求出来的t也是无尺度的(也就是说对于这个H,相机的t可能是任意倍的t)。
	                                                                //如果你想知道准确的K,opencv中有实现这个的函数。
	
	int solutions = decomposeHomographyMat(homography_matrix, K, R, t, n);//这里的solutions是找到几组解,一般来说是4
filterHomographyDecompByVisibleRefpoints函数

  该函数通过已知的匹配点坐标(2D),从求解出的4组解中筛选出真实解。但是据我实验,该函数好像并不能保证一定能找到真实解,有时候它只能将真实解所在范围缩小到两个解中,不过所幸的是大部分情况都能将真实解筛选出来(也可能是因为我的匹配点的canvas坐标到投影平面的坐标转换不对)。

  详细函数介绍见官方文档(我这里用的opencv3.4.15):

https://docs.opencv.org/3.4.15/d9/d0c/group__calib3d.html#ga32f867159200f7bd55e72dca92d8494c

  这个函数的源码见下面这个文见最后一点部分:

https://github.com/opencv/opencv/blob/master/modules/calib3d/src/homography_decomp.cpp

   同样的,下面给出我是用这个函数的过程:

	vector pointMask;//匹配点对是否有效
	vector  sol;//存放真实解序号
	vectorpattern_xy, screen_xy;//特征点与其对应的匹配点
	
	for (int i = 0; i < 3; i++) {
		pointMask.push_back(1);//我当时找了三对点先试试,全设成有效
	}
	pattern_xy.push_back(Point2f(149-320, 240-32));//因为我原本的坐标(149,32)是使用的canvas的坐标系,也就是原点在左上角,y轴冲下。
	                                               //虽然我不知道相机投影的缩放参数,但至少要根据光心(320,240)把坐标轴变过来。
	pattern_xy.push_back(Point2f(212-320, 240-78));
	pattern_xy.push_back(Point2f(186-320, 240-35));

	screen_xy.push_back(Point2f(284-320, 240-64));
	screen_xy.push_back(Point2f(327-320, 240-122));
	screen_xy.push_back(Point2f(316-320, 240-76));
	
	filterHomographyDecompByVisibleRefpoints(R, n, pattern_xy, screen_xy, sol, pointMask);
完整代码

下面是我的整个完整代码:

#include 

#include 
#include 
#include 
#include 
// #include "extra.h" // use this if in OpenCV2

using namespace std;
using namespace cv;

int main() {
	vector R, t, n;
	vector pointMask;
	vector  sol;
	vectorpattern_xy, screen_xy;
	for (int i = 0; i < 3; i++) {
		pointMask.push_back(1);
	}
	pattern_xy.push_back(Point2f(149-320, 240-32));
		pattern_xy.push_back(Point2f(212-320, 240-78));
		pattern_xy.push_back(Point2f(186-320, 240-35));

		screen_xy.push_back(Point2f(284-320, 240-64));
		screen_xy.push_back(Point2f(327-320, 240-122));
		screen_xy.push_back(Point2f(316-320, 240-76));
		
	Mat homography_matrix = (Mat_(3, 3) << 1.020205, -0.297803580, 150.1813964, 0.305915176, 0.929503381, -9.5677337, 0.00021775, -0.000026478477, 1);
	Mat K = (Mat_(3, 3) << 20, 0, 320, 0, 20, 240, 0, 0, 1);
	int solutions = decomposeHomographyMat(homography_matrix, K, R, t, n);
	filterHomographyDecompByVisibleRefpoints(R, n, pattern_xy, screen_xy, sol, pointMask);
	for (int i = 0; i < solutions; ++i) {
		cout << "======== " << i << " ========" << endl;
		cout << "rotation" << i << " = " << endl;
		cout << R.at(i) << endl;
		cout << "translation" << i << " = " << endl;
		cout << t.at(i) << endl;
		cout << "n" << i << " = " << endl;
		cout << n.at(i) << endl;		
	}
	cout << "the real solution num is : " << sol.size()<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1038667.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号