OpenCV:鱼眼相机去畸变=图像去畸变+点去畸变
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV:鱼眼相机去畸变=图像去畸变+点去畸变相关的知识,希望对你有一定的参考价值。
参考技术A 官网: https://docs.opencv.org/3.4/db/d58/group__calib3d__fisheye.html(5)undistortPoints是点去畸变函数
去畸变点的坐标为(725,514)和去畸变图像中一致.
VS2019+OpenCV4.5 鱼眼相机图像畸变矫正
-
一、鱼眼相机概述
鱼眼镜头是定焦镜头中的一种视野范围很大的镜头,它视角范围通常大于等于180度。鱼眼相机虽然能获得较大的视角范围,但是其拍摄的图像存在较大的畸变,为了后续任务的需要,往往需要对原始图像进行预处理,即进行图像的畸变矫正,获得没有畸变的图像。
如下图所示,鱼眼相机在获得大视角范围的同时,产生的畸变也很大,真实场景中的直线经成像变成了曲线。
日常生活中接触到的大多数相机都可以近似用针孔相机模型来近似,在针孔相机模型中,光线沿直线传播,在成像平面所成的像与真实物体具有相似性。像与物之间经过了透视变换,透视变换保证直线仍然成像为直线,但是不保证平行性,即平行的直线在图像上不再平行,而相交于无穷远处。
针孔相机成像的特点带来了相应的缺陷,光线只能沿直线传播,这就使得镜头难以捕捉位于图像边缘的物体。如下图所示,越靠近边缘的物体经过直线传播后,在成像平面上的位置就会越远,而相机的底片尺寸有限,因此靠近边缘的物体无法成像。
为了获得更大的视角范围,人们希望光线不经过直线传播,而是像光线从空气射入水中那样发生折射。如下图所示便是鱼眼相机的成像原理,光线的折射角小于入射角,并且入射角越大,折射角减小的程度也越大。这样就相当于把光线集中到了一个锥形空间内,在图像中表现为所有的画面都集中到一个圆圈之中,类似于鱼的眼睛,因此该相机得名“鱼眼相机”。
-
二、鱼眼相机成像模型
鱼眼相机采用最多的是等距投影模型,投影函数为,其中r为像高,f为焦距,θ为入射角。成像时,由于镜头畸变,实际的投影函数不会严格符合投影模型。考虑到畸变,实际的投影函数由下式给出(这里假设f=1):
其中,k0约等于1,k1,k2,k3,k4称为畸变系数。
如图所示,坐标系Oc-XcYcZc是相机坐标系,坐标系O-XY是物理图像坐标系。假设按照针孔相机的成像模型,世界坐标系中的一点经过直线投影到物理图像坐标系中的点。其中,光线的入射角为。按照鱼眼相机的成像模型,出射角应该小于入射角,因此实际投影点应该为。不妨假设f=1,则点坐标以及入射角如下:
由于畸变的存在,实际像点为P’,像点到图像中心的距离被压缩为,结合鱼眼相机的投影函数得:
由于,且的一次项系数约为1,因此OpenCV中使用的鱼眼相机模型为:
由相似三角形原理:
因此畸变后的点坐标p’为:
最后利用相机内参将物理图像坐标系转换为像素坐标系,得到p’点的像素坐标:
-
三、基于OpenCV的鱼眼相机图像矫正
1.相机标定
由鱼眼成像模型的知识可以知道,要矫正鱼眼相机图像需要获得相机内参及畸变系数。这两个参数可以通过相机标定获得。本文采用张正友标定法,拍摄了20张棋盘格图像,用于求解相机内参以及畸变系数。
2.图像矫正
获得相机的内参及畸变系数之后,使用OpenCV的鱼眼图像矫正函数fisheye::undistortImage()进行畸变矫正。
void Undistort::UndistortImg(const double k, bool is_save, const string& path)
{
//新的相机内参矩阵
Mat new_intrinsic_mat;
K.copyTo(new_intrinsic_mat);
//调节视场大小,乘的系数越小视场越大
new_intrinsic_mat.at<double>(0, 0) *= k;
new_intrinsic_mat.at<double>(1, 1) *= k;
cout << endl << "开始校正图像" << endl;
for (int i = 0; i < test_images.size(); i++)
{
//调节校正图中心,建议置于校正图中心
new_intrinsic_mat.at<double>(0, 2) = 0.5 * test_images[i].cols;
new_intrinsic_mat.at<double>(1, 2) = 0.5 * test_images[i].rows;
Mat undistort_img;
fisheye::undistortImage(test_images[i], undistort_img, K, distortion_coeffs, new_intrinsic_mat);
//保存图像
if (is_save)
{
string filename = path + "/out" + format("%d", i + 1) + ".jpg";
imwrite(filename, undistort_img);
}
}
if (is_save)
cout << endl << "校正结果已保存至:" << path << endl;
cout << endl << "校正结束" << endl;
}
fisheye::undistortImage()的第一个参数是待矫正的图像,第二个参数是矫正后的图像,第三个参数是相机内参,第四个参数是畸变系数,第五个参数是矫正后的相机内参,可以改变这个参数来调整矫正后图像的中心位置和视场大小。
3.矫正结果
原图1
结果图1
原图2
结果图2
原图3
结果图3
四、本文代码
(23条消息) fisheye_cali.zip-图像处理文档类资源-CSDN文库
五、参考文献
以上是关于OpenCV:鱼眼相机去畸变=图像去畸变+点去畸变的主要内容,如果未能解决你的问题,请参考以下文章
相机标定中的一些知识点(小孔模型、鱼眼模型、畸变、泰勒展开)
Python OpenCV 单目相机标定坐标转换相关代码(包括鱼眼相机)