ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

单目视觉标定

2021-06-13 20:34:28  阅读:765  来源: 互联网

标签:标定 成像 相机 畸变 单目 归一化 视觉 坐标系


内容

一.单目视觉成像原理

1.理想情况下相机成像模型

在理想情况下,相机成像模型可以看作是⼩孔成像模型,如下图所示,
在这里插入图片描述
为了便于计算,我们将成像平面进行翻转(它们在数学上是等价的,并且相机硬件会自动帮我们处理),我们假设成像平面翻转到了相机光心的正前方,翻转后的相机模型如下,其主要包含四个坐标系。
在这里插入图片描述
此外,还有一个归一化平面如下图所示,其实际是图像坐标系的等比缩放,也就是当f=1的情况,主要是便于公式推导,它与图像坐标系是等比缩放关系,只需要乘以f即可完成相互转换:
在这里插入图片描述

1.1 世界坐标系 -> 相机坐标系

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 相机坐标系 -> 图像坐标系

图像坐标系:以光心在成像平面上的投影点O(成像平面的中点)为原点建立的坐标系,单位一般是mm。
在这里插入图片描述
在这里插入图片描述
总结:
在这里插入图片描述

1.3 图像坐标系 -> 像素坐标系

像素坐标系:以成像平面左上角建立的坐标系,单位是像素。
图像坐标系和像素坐标系处在同一平面,但是有两点不同:
①坐标原点不同:图像坐标系在成像平面的中心;像素坐标系在成像平面的左上角;
②单位不同:图像坐标系,单位是mm,属于物理单位;像素坐标系,单位是pixel(1 pixel = dx 或 dy mm)。
它们之间的转换关系如下,包含平移与缩放两个变换:
在这里插入图片描述
总结:
在这里插入图片描述

1.4 总结:世界坐标系 -> 像素坐标系

在这里插入图片描述
在这里插入图片描述
将之前所有的变换合并:
在这里插入图片描述
将它们相乘后进行化简:
在这里插入图片描述

二.考虑畸变情况下相机成像模型

1.径向畸变

原因:在相机制造过程中,很难保证镜头的厚度完全均匀,由于制造工艺的原因,通常这种情况为中间厚、边缘薄,因而光线在远离透镜中心的地方,会发生更大程序的扭曲,这种现象在鱼眼相机(桶形畸变)中尤为明显。
径向畸变主要有两种类型:枕型畸变和桶型畸变,示意图如下:
在这里插入图片描述
它们可以由k1、k2构成的下列数学公式描述:
在这里插入图片描述
在这里插入图片描述
通常只用k1、k2来矫正相机,对于畸变较小的图像中心区域,主要是k1在起作用,对于畸变较大的图像边缘区域,主要是k2在起作用,而对于鱼眼相机这类广角相机才会用到k3,同时,并不是选用的系数越多从而整个矫正结果越精确,而应该考虑相机的实际情况。

2.切向畸变

原因:在相机制造过程中,成像平面与透镜平面不平行,产生透视变换,如下图所示:
在这里插入图片描述
切向畸变可由以下公式描述,其与距离图像中心的距离半径有关:
在这里插入图片描述
式中,p1、p2表示切向畸变矫正系数,其他参数含义与径向畸变中的公式相同。

3.合并考虑畸变

原因:两种畸变是同时发生在成像过程中的,发生的原因也是相互独立的,而且也都是关于距离的表达式,似乎也找不到更好的方式来综合考虑这两种误差,实践证明,这种合并考虑畸变的情况效果还不错。
将径向畸变和切向畸变合并,只需将两个畸变矫正直接加起来即可,公式如下:
在这里插入图片描述
式中,k1、k2、k3为径向畸变系数;p1、p2为切向畸变系数。
不过在此之前,需要特别注意一点,相机畸变现象发生的位置:
①世界坐标系 -> 相机坐标系:刚体变换,不存在畸变现象;
②相机坐标系 -> 图像坐标系:也就是成像过程,理想情况下是相似三角形,但实际由于相机智造、装配的原因,成像过程存在畸变现象;
③图像坐标系 -> 像素坐标系:坐标原点、单位不同,仅仅平移与缩放,不存在畸变现象。

三.成像过程总结

将成像过程的公式进行总结整理,假设:
在这里插入图片描述
(1)像素坐标系 -> 归一化坐标系
这个变换仅仅是平移与缩放,不存在畸变,因而只需要一个逆变换,归一化坐标P=(x,y)T,公式如下:
在这里插入图片描述
(2)归一化坐标系(带畸变的)-> 归一化坐标系(畸变矫正后)
在前一成像过程即相机坐标系到归一化平面透射中,相机发生了畸变,因而需要将实际的归一化坐标P=(x,y)T纠正到理想的无畸变归一化坐标P=(x’,y’)T,公式如下:
在这里插入图片描述
(3)归一化坐标系(理想)-> 相机坐标系
理想的无畸变归一化坐标P=(x’,y’)到相机坐标系,它们是相似三角形关系,公式如下:
在这里插入图片描述
(注:这里3×4矩阵的逆是伪逆。)
(4)相机坐标系 -> 世界坐标系
由相机坐标系到世界坐标系,仅仅是之前刚体变换的反变换,公式如下:
在这里插入图片描述
所以只需要将上述的四个公式合并起来即可得到像素坐标系P=(u,v)转换到世界坐标系P=(XW,YW,,ZW)的转换公式。

四.单目相机标定过程

①准备标定图片(不同位置、角度、姿态下拍摄,以10~20张为宜)。
在这里插入图片描述
②使用Matlab自带的标定工具进行相机标定。(我的Matlab版本是R2019a)过程如下:
在这里插入图片描述
在这里插入图片描述
加载你拍的所有标定图片
在这里插入图片描述
输入你拍摄标定板的每个格子的尺寸大小,
在这里插入图片描述
软件会自动剔除不符合要求的图片,
在这里插入图片描述
在这里插入图片描述
点击Calibrate,
在这里插入图片描述
标定结果如下图,
在这里插入图片描述
为了使结果更精确,可以删除误差较大的图片,(我这里忘了删了。。。)
导出标定参数,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在命令行分别输入
cameraParams.IntrinsicMatrix
获得相机内参矩阵
cameraParams.RadialDistortion
获得相机径向畸变系数
在这里插入图片描述
在这里插入图片描述

③校正结果
畸变校正前:
在这里插入图片描述
点击Show Undistorted,畸变校正后:
在这里插入图片描述

五.用Opencv查看标定结果

这部分参考的别的博主,他用标定结果校正了电脑自带的摄像头,我还没写出来校正海康威视工业相机的代码。。。
我运行了他的程序(VS2019+Opencv4.4),亲测有效,下面贴出:
在这里插入图片描述
在这里插入图片描述

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    VideoCapture inputVideo(0);
    if (!inputVideo.isOpened())
    {
        cout << "Could not open the input video: " << endl;
        return -1;
    }
    Mat frame;
    Mat frameCalibration;

    inputVideo >> frame;
    Mat cameraMatrix = Mat::eye(3, 3, CV_64F);
    cameraMatrix.at<double>(0, 0) = 4.450537506243416e+02;
    cameraMatrix.at<double>(0, 1) = 0.192095145445498;
    cameraMatrix.at<double>(0, 2) = 3.271489590204837e+02;
    cameraMatrix.at<double>(1, 1) = 4.473690628394497e+02;
    cameraMatrix.at<double>(1, 2) = 2.442734958206504e+02;

    Mat distCoeffs = Mat::zeros(5, 1, CV_64F);
    distCoeffs.at<double>(0, 0) = -0.320311439187776;
    distCoeffs.at<double>(1, 0) = 0.117708464407889;
    distCoeffs.at<double>(2, 0) = -0.00548954846049678;
    distCoeffs.at<double>(3, 0) = 0.00141925006352090;
    distCoeffs.at<double>(4, 0) = 0;

    Mat view, rview, map1, map2;
    Size imageSize;
    imageSize = frame.size();
    initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),
        getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
        imageSize, CV_16SC2, map1, map2);


    while (1) 
    {
        inputVideo >> frame;              
        if (frame.empty()) break;         
        remap(frame, frameCalibration, map1, map2, INTER_LINEAR);
        imshow("Origianl", frame);
        imshow("Calibration", frameCalibration);
        char key = waitKey(1);
        if (key == 27 || key == 'q' || key == 'Q')break;
    }
    return 0;
}

参考博客,感谢这些大佬:
https://blog.csdn.net/hitzijiyingcai/article/details/82715921
https://blog.csdn.net/weixin_43843780/article/details/89294131
https://blog.csdn.net/u010607947/article/details/80510907
https://blog.csdn.net/Kano365/article/details/90721424

标签:标定,成像,相机,畸变,单目,归一化,视觉,坐标系
来源: https://blog.csdn.net/qq_45445740/article/details/117855768

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有