SLAM从入门到放弃:SLAM十四讲第五章习题(3-6)

以下均为简单笔记,如有错误,请多多指教。

  1. 搜索特殊相机(鱼眼或全景相机)的标定方法。它们与普通的针孔模型有何不同?
    解: 目前比较常用的鱼眼或全景相机的标定工具有opencv,OcamCalib(https://github.com/urbste/ImprovedOcamCalib),SWARD等等非常多的工具。通常而言其标定思路与常规相机并没有太大区别,首先采集一系列棋盘格的影像,然后使用手动或者自动提取出所有的棋盘角点,并在其基础上进行畸变参数的求解。但是区别在于,鱼眼或全景通常会采用更加复杂的畸变模型,最常用的就是一个多线性畸变公式,如下式所示(OpenCV中的示例):
    θ d = θ ( 1 + k 1 θ 2 + k 2 θ 4 + k 3 θ 6 + k 4 θ 8 ) \theta_d=\theta(1+k_1\theta^2+k_2\theta^4+k_3\theta^6+k_4\theta^8) θd=θ(1+k1θ2+k2θ4+k3θ6+k4θ8)
    其主要原因是此类相机通常并不符合针孔模型,其成像过程可以用下图展示,可以发现其成像过程是一个球面折射过程。
    SLAM从入门到放弃:SLAM十四讲第五章习题(3-6)_第1张图片

  2. 调研全局快门相机和卷帘快门相机的异同。它们在SLAM中有何优缺点?
    答: 参考资料:https://www.oxinst.com/learning/view/article/rolling-and-global-shutter。
    下图展示了全局相机和卷帘快门相机成像方式的区别,全局相机是一次成像,所有的像素同时停止曝光;而卷帘相机是逐行成像,不同的像素停止曝光的时间不同。
    SLAM从入门到放弃:SLAM十四讲第五章习题(3-6)_第2张图片
    因此当出现高速运动后,卷帘相机会出现明显的“果冻效应”,如左图所示。右图展示的全局相机的拍摄结果,可以发现虽然仍然出现了模糊问题,但是并没有出现果冻问题。
    SLAM从入门到放弃:SLAM十四讲第五章习题(3-6)_第3张图片
    至于他们在SLAM中的优缺点,我感觉目前的大趋势是使用全局快门相机,因为其明显更精确,但是其缺点可能是相对而言比较贵吧~

  3. RGB-D相机是如何标定的?以Kinect为例,需要标定那些参数?(参照 https://github.com/code-iai/iai_kinect2)
    答: 本人对Kinect不是很熟悉,所以一下答案都是参考iai_kinect2得到,其标定过程与普通相机似乎差异也不是特别大,只是需要同时标定RGB相机和红外相机,需要标定的参数有RGB的内参数,红外相机的内参数,RGB相机和红外相机之间的变化关系,红外相机的深度信息校正。
    因此其标定过程通常如下:首先采集一系列RGB影像,然后标定内参数;然后采集一系列红外影像,标定内参数;接下来同时采集RGB影像和红外影像,标定两个相机之间的外参数,并同时对红外相机的深度信息进行校正。
    值得注意的是,iai_kinect2标定要求采集数据时标定板和相机都处于静止静止状态,从而避免运动对标定结果的影响,因此相机和标定板都最好放在一个固定架上。另外则是相机最好能够从多个角度、多个深度采集数据数据。

  4. 除了示例程序演示的遍历图像方式,你还能举出哪些遍历图像的方法?
    答:OpenCV中常用的遍历图像的方法主要有三中,包括基于at,ptr和迭代器的方法,本人的实验结果是是ptr的效果最佳。

#include 
#include 

#include 

int main()
{
	// Mat
	cv::Mat image = cv::Mat::zeros(1000, 1000, CV_8UC3);

	// By at
	clock_t atBegin = clock();
	for (int y = 0; y < image.rows; y++)
	{
		for (int x = 0; x < image.cols; x++)
		{
			image.at(x, y) = cv::Vec3b(100, 100, 100);
		}
	}
	clock_t atFinish = clock();
	std::cout << "Time: " << (atFinish - atBegin)*1.0 / CLOCKS_PER_SEC << std::endl;

	// By ptr
	clock_t ptrBegin = clock();
	for (int y = 0; y < image.rows; y++)
	{
		for (int x = 0; x < image.cols; x++)
		{
			image.ptr(y)[x]= cv::Vec3b(100, 100, 100);
		}
	}
	clock_t ptrFinish = clock();
	std::cout << "Time: " << (ptrFinish - ptrBegin)*1.0 / CLOCKS_PER_SEC << std::endl;

	// By Iterator
	clock_t iteratorBegin = clock();
	cv::Mat_::iterator begin = image.begin();
	cv::Mat_::iterator end = image.end();
	for (; begin != end; begin++)
	{
		(*begin) = cv::Vec3b(100, 100, 100);
	}
	clock_t iteratorFinish = clock();
	std::cout << "Time: " << (iteratorFinish - iteratorBegin)*1.0 / CLOCKS_PER_SEC << std::endl;

	return 0;
}

你可能感兴趣的:(SLAM从入门到放弃:SLAM十四讲第五章习题(3-6))