600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > python二郎成长笔记(三)(matlab标定工具箱详解 旋转矩阵旋转向量 matlab标定数据

python二郎成长笔记(三)(matlab标定工具箱详解 旋转矩阵旋转向量 matlab标定数据

时间:2018-09-10 19:59:35

相关推荐

python二郎成长笔记(三)(matlab标定工具箱详解 旋转矩阵旋转向量 matlab标定数据

这一章由来:二郎之前研究matlab的双目立体视觉,已经得到了需要的信息,可是,二郎想要对代码进行修改使其更适宜自己的应用目的。

修改:标定不用修改……matlab内置的已经很强大了,而且没有必要用python和c++再做一遍,因此考虑的方法为——matlab标定后,参数导入到opencv中使用,这也是应用到python的一个原因。

一、matlab标定工具箱

matlab提供了两种方法:1.用自带的app进行标定(在双目立体视觉的文章中有详细讲解);2.用matlab标定工具箱,像下面这样的东西

与其说它是一个工具箱,更确切地说它就是没有被matlab集成到内部,可以看到的m文件。

用法非常简单,下载在网上找一下,很多,或者找二郎要……吐槽一下,有的博主把这些东西挂到CSDN卖积分……感觉好不地道。

http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/example.html(一篇英文教程,不想看英文的也可以接着文章往下看,二郎给大家做一遍)

1.下载的压缩包解压……到哪都行

这里需要注意……点进来之后,要把这个文件夹添加到执行目录,要不后续无法进行。

2.运行文件

3.选择进入程序

4.将图片目录添加到执行目录,且进入图片目录

5.以此运行,不用设置参数

点完后,去看matlab命令行窗口

上面二郎之前做过所以又记录,其实是需要输入棋盘格的尺寸的,也就是那个30,30

…………然后就一直持续标四个点,直至标完所有,二郎认为大家肯定会出现在标定中小手一抖,标跑偏的现象,没关系,后面能修改,先把四个点都标上再说。

表完之后点计算标定

你会发现我们想要求得值就出来了。然后用分析一下错误,可以看到我们哪张图错误率较大

我们可以用一下重投影,将我们求得内外参数代入公式,算出各点,带回到图像,计算误差(当然,这一步是计算机做的),重投影主要是为了recop.corners计算提高精度。再次确定角点时,以重投影的角点为起始角点,开始寻找角点。

做完上面一些步骤后我们的精度已经得到明显的提高

之后就可以针对单张图来进行操作了,比如再进行一下步骤3,这次不选所有图,而是单独找我们之前标错的图,进行重新的角点标注。在重新计算角点时,可以人为地设置窗口大小,之前默认为5*5,可以适当调大或者缩小。

多次进行角点检测的方法

第二次:Recomp.corners→[9,9]

第三次:Recomp.corners→[8,8]

第四次:Recomp.corners→[7,7]

逐渐缩小角点检测的窗口,避免产生窗口过小,造成的局部误差。

双目标定

当我们左右相机的单目标定完成后,将标定结果进行保存,建议保存名字为

(Calib_Result_left.mat和Calib_Result_right.mat)

运行工具箱里的stereo_gui.m

导入数据(Calib_Result_left.mat和Calib_Result_right.mat),进行双目标定。

二、旋转矩阵和旋转向量

从上面的介绍中可以看到matlab已经集成的标定程序和标定工具箱各有各自的优点,弄哪一个都是可以的。在matlab已经集成的标定程序使用时,我们的2相机相对于1相机的旋转关系为旋转矩阵(9个参数),然而,在opencv和python中,多数程序使用的数据为旋转向量(3个参数)形式,这里涉及了一个转换定理——罗德里格斯(Rodrigues)旋转向量与矩阵的变换

图片截取于:/view/b471efda6037ee06eff9aef8941ea76e58fa4acb.html?from=search

而具体如何实现旋转矩阵和旋转向量的转换呢?

下面列出了程序

python程序——程序不是二郎写的,来自github,方便大家看,因此黏贴过来。

/blzq/tf_rodrigues/commit/338758887a18f0db4e4a38c949be120d7f5169e3#diff-c5ff043af7299aff712f4dc2fb35bba3

#!/usr/bin/python3# -*- encoding: utf-8 -*-import tensorflow as tfdef rodrigues_batch(rvecs):""" Convert a batch of axis-angle rotations in rotation vector form shaped(batch, 3) to a batch of rotation matrices shaped (batch, 3, 3).See/wiki/Rodrigues%27_rotation_formula#Matrix_notation/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle--- second article is wrong?"""batch_size = tf.shape(rvecs)[0]thetas = tf.norm(rvecs, axis=1, keepdims=True)u = rvecs / thetas# Each K is the cross product matrix of unit axis vectors# pyformat: disablezero = tf.zeros([batch_size]) # for broadcastingKs_1 = tf.stack([ zero , -u[:, 2], u[:, 1] ], axis=1) # row 1Ks_2 = tf.stack([ u[:, 2], zero , -u[:, 0] ], axis=1) # row 2Ks_3 = tf.stack([ -u[:, 1], u[:, 0], zero ], axis=1) # row 3# pyformat: enableKs = tf.stack([Ks_1, Ks_2, Ks_3], axis=2) # stack rowsRs = tf.eye(3, batch_shape=[batch_size]) + \tf.sin(thetas)[..., tf.newaxis] * Ks + \(1 - tf.cos(thetas)[..., tf.newaxis]) * tf.matmul(Ks, Ks)print(Rs.shape)return Rs# For testing onlyif __name__ == '__main__':import numpy as npimport cv2rvecs = np.random.randn(4, 3).astype(np.float32)rvecs_tf = tf.constant(rvecs)Rs = rodrigues_batch(rvecs_tf)with tf.Session() as sess:print("TensorFlow: ")print(sess.run(Rs))print("\nOpenCV: ")for rvec in rvecs:mat, _ = cv2.Rodrigues(rvec)print(mat.T)print()

opencv的程序——来自网上,具体出处不明(输入旋转向量则转化为旋转矩阵,输入旋转矩阵,则转化为旋转向量)

#include <stdio.h>#include <cv.h>void main(){int i;double r_vec[3]={-2.100418,-2.167796,0.273330};double R_matrix[9];CvMat pr_vec;CvMat pR_matrix;cvInitMatHeader(&pr_vec,1,3,CV_64FC1,r_vec,CV_AUTOSTEP);cvInitMatHeader(&pR_matrix,3,3,CV_64FC1,R_matrix,CV_AUTOSTEP);cvRodrigues2(&pr_vec, &pR_matrix,0);for(i=0; i<9; i++){printf("%f\n",R_matrix[i]);}}

同样,可以去opencv官网:/3.4.0/d9/d0c/group__calib3d.html#ga61585db663d9da06b68e70cfbf6a1eac

Mat rvec1, tvec1;solvePnP(objectPoints, corners1, cameraMatrix, distCoeffs, rvec1, tvec1);#求旋转矩阵Mat rvec2, tvec2;solvePnP(objectPoints, corners2, cameraMatrix, distCoeffs, rvec2, tvec2);Mat R1, R2;Rodrigues(rvec1, R1);#实现旋转矩阵向旋转向量的转换Rodrigues(rvec2, R2);

三、opencv所需标定结果格式(matlab)

Radial:径向畸变,光学透镜的特性使得成像存在着径向畸变(k1,k2,k3),k3可以有,也可以为0。

Tangen:切向畸变,装配方面的误差,传感器与光学镜头不在同一水平线,可由两个参数P1,P2确定。

这里提一下,畸变参数的排列(K1,K2,P1,P2,K3)(用在opencv中)

Mat cameraMatrixL = (Mat_<double>(3, 3) << 904.0589, 0, 656.6037,0, 869.2423, 308.9319,0, 0, 1);//对应matlab里的左相机标定矩阵Mat distCoeffL = (Mat_<double>(5, 1) << 0.3370, -0.1561, -0.0245, 4.2596e-4, 0.0000);//对应Matlab所得左i相机畸变参数Mat cameraMatrixR = (Mat_<double>(3, 3) << 903.1359, 0, 659.2396,0, 870.4047, 321.2040,0, 0, 1);//对应matlab里的右相机标定矩阵Mat distCoeffR = (Mat_<double>(5, 1) << 0.3338, -0.0631, -0.0105, -0.0022, 0.00000);//对应Matlab所得右相机畸变参数Mat T = (Mat_<double>(3, 1) << -118.9937, 2.5308, -1.8361);//T平移向量//对应Matlab所得T参数Mat rec = (Mat_<double>(3, 1) << XXXXX, XXXXXX,XXXXX);//rec旋转向量,对应matlab om参数,这里需要把旋转矩阵变为旋转向量Mat R;//R 旋转矩阵

下面opencv的代码可以参照博文:/xiao__run/article/details/78900652

python二郎成长笔记(三)(matlab标定工具箱详解 旋转矩阵旋转向量 matlab标定数据传入opencv)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。