最近懵逼了,我还连小孔成像的畸变矫正公式还没弄清楚,很有必要把张正友论文读一遍《Flexible camera calibration by viewing a plane from unknown orientations》,很多文章梦棱两可,建议大家还是首先读了论文了解情况。

开局一张框图

论文截图

由上述论文可见, 畸变公式左侧 x^ 和 y^ 是畸变矫正前的像素坐标,右侧的 x ,y 是理想情况下无畸变时的像素坐标:

这个是K1,K2的情况。如果是K1,K2,K3的情况:
径向畸变

xdistortedx_{distorted}xdistorted​是畸变的像素。xxx是理想的像素。

OpenCV 针对不同的使用场景提供了几个不同用法的畸变校正函数

OpenCV 针对不同的使用场景提供了几个不同用法的畸变校正函数。
主要有以下几种:

initUndistortRectifyMap() remap()组合
undistort()
undistortPoints()

1.1 initUndistortRectifyMap() remap()组合

通过映射的方式逐个找出理想点在有畸变原图的位置。initUndistortRectifyMap()用于产生映射表,remap()用于执行映射。

适用场景:
当要进行多次畸变校正时,使用initUndistortRectifyMap() remap()组合比较有效率,只需要执行一次initUndistortRectifyMap(),后面畸变校正只需要执行remap()即可

1.2 undistort()

本质是initUndistortRectifyMap() remap()组合,写在了一个函数里。方便只校正一次。

适用场景:
当只需要执行一次畸变校正时,用undistort()比用组合形式更方便一些。

1.3 undistortPoints()

适用场景:
当只需要找出有畸变原图中的少数几个点经过畸变校正后的理想位置时,使用undistortPoints()可达到目的。

计算公式

3.1 initUndistortRectifyMap()

https://docs.opencv.org/master/d9/d0c/group__calib3d.html#ga7dfb72c9cf9780a347fbe3d1c47e5d5a

作用: 用于生成remap()需要用到的map。
函数签名:

计算公式如下

(u, v)是理想点坐标,求出畸变后移到哪里去了,属于正向求解:

参数说明:

newCameraMatrix :
如果是单目,newCameraMatrix可以直接取cameraMatrix,或者是经过getOptimalNewCameraMatrix改变视野后的内参矩阵。
如果是双目,可能要做共面行对准,就用stereoRectify计算后的P。

m1type参数 :
是指定map1的类型,可以是CV_32FC1 、 CV_32FC2 或者 CV_16SC2,如果map1是双通道的,相当于x,y的映射关系都在map1里了。

用法示例:

cv::Mat image_undistort;
cv::Size imageSize = image.size();
cv::Mat map1, map2;
initUndistortRectifyMap(cameraMatrix, distCoeff, cv::Mat(), cameraMatrix, imageSize, CV_32FC1, map1, map2);
remap(image, image_undistort, map1, map2, cv::INTER_LINEAR);

remap函数签名

映射函数,注意插值方法和边界处理。

3.2 undistort()

https://docs.opencv.org/master/d9/d0c/group__calib3d.html#ga55c716492470bfe86b0ee9bf3a1f0f7e

作用: 是initUndistortRectifyMap()和remap()组合, initUndistortRectifyMap()参数的R是单位阵,remap()的插值方法是双线性插值。


用法示例:
cv::Mat image_undistort2;
undistort(image, image_undistort2, cameraMatrix, distCoeff);

3.3 undistortPoints()

https://docs.opencv.org/master/d9/d0c/group__calib3d.html#ga55c716492470bfe86b0ee9bf3a1f0f7e

作用: 根据有畸变的观察点计算出其理想点的位置。

函数签名:

计算公式:

其中undistort过程是根据畸变公式反向迭代计算。
参数说明:

R是指定另外的旋转,一般是双目的共面行对准时需要用到。单目可不设置,或者使用单位矩阵。

P是指定新的相机内参矩阵或者投影矩阵。
用法注意事项

如果P没有指定,那么结果dst就是物理坐标(x, y),而不是像素坐标(u’, v’).

如果设置了P,就按照新的内参矩阵计算(u’, v’),这时是像素坐标
用法示例:

    // create ptscv::Size imageSize = image.size();std::vector<cv::Point2f> pts, upts;int x, y;int N = 21;for (y = 0; y < N; y++) {for (x = 0; x < N; x++) {pts.push_back(cv::Point2f((float)x*imageSize.width / (N - 1), (float)y*imageSize.height / (N - 1)));}            }undistortPoints(pts, upts, cameraMatrix, distCoeff);    // output is x,y with z = 1// undistortPoints(pts, upts, cameraMatrix, distCoeff, cv::Mat(), cameraMatrix);   // output is u' v' 

传统的张正友不适合鱼眼

如果按照小孔成像,配合K1,K2的系数,可能难以匹配鱼眼的情况。

比较“camera calibration toolbox” 和“fisheye camera calibration”的结果

图像来源:https://www.cnblogs.com/yongjieShi/p/11327414.html

理论上需要修改,一般的鱼眼镜头基于等距投影模型(r=焦距×入射角),需要考虑入射角,优化再sensor上的r值。

以入射角为输入量,(张正友是以位置x为输入量)

输出的是投影点到图像中心的距离rho
rho(theta)=k1∗theta+k2∗theta∗∗2+k3∗theta∗∗3+k4∗theta∗∗4,rho(theta)=k1∗theta+k2∗theta∗∗2+k3∗theta∗∗3+k4∗theta∗∗4, rho(theta)=k1∗theta+k2∗theta∗∗2+k3∗theta∗∗3+k4∗theta∗∗4,

根据rho计算u v值

u' = rho * X / sqrt( X ** 2 + Y ** 2)
v' = rho * Y / sqrt( X ** 2 + Y ** 2)
u = u' + cx + width/2 - 0.5
v = v'  + cy + height/2 - 0.5

两种方案:
方案1:

我们选用了小孔模型进行了映射表。其实我们可以采用别的投影模型进行映射,例如我们可以采用等距投影映射:

参考:https://blog.csdn.net/Gavinv/article/details/78386465

方案2:

我们选用了小孔模型,或者其他模型进行了映射表。

【鱼眼镜头8】张正友畸变公式;鱼眼的畸变公式需要使用入射角相关推荐

  1. 深入理解张正友相机标定法:数学理论详细推导

    最近在项目中需要在激光雷达(Lidar)和相机(Camera)之间进行标定,即需要标定出相机内参和外参,使用的标定方法是张正友标定法,这里给出其数学理论推导过程. 论文原文:<A Flexibl ...

  2. 张正友相机标定(全流程,含畸变,matlab源代码解析)

    张正友标定的具体原理很多文章已经介绍,这里主要结合源代码对其中的基本原理及本人遇到的问题进行介绍.(仅介绍基本原理供本人复习,同时方便他人,如有问题,请及时指正勿喷) 1. 标定基本思路介绍 相机标定 ...

  3. 相机标定(二)-畸变校正,张正友标定法

    >>>文章索引<<< 相机标定(一)-原理及内参.外参 相机标定(二)-畸变校正,张正友标定法 相机标定(三)-相机成像模型 1 一些基本的方程推导 1.1 预定义 ...

  4. 张正友畸变矫正C++代码

    1,在自己的项目下创建文件夹sample->left 2,创建两个txt文件,caliberation_result.txt,filename.txt 3,将拍的标定图名称写到filename. ...

  5. 【一文弄懂】张正友标定法-完整学习笔记-从原理到实战

    张正友标定法-完整学习笔记-从原理到实战 文章目录 张正友标定法-完整学习笔记-从原理到实战 (零)前言: 1 为什么需要标定? 2 相机标定的已知条件和待求解是什么? 标定前的已知条件: 待求信息: ...

  6. 针孔相机标定-基于张正友标定法

    针孔相机标定 前段时间曾经做过一段时间的摄像头标定,这里对以前做的事情做一个总结.首先,介绍一下针孔相机的标定吧,主要还是代码解析和一些细节说明,为了让自己更好的理解相机标定.当时做摄像头标定是为了实 ...

  7. 三维重建学习(3):张正友相机标定推导

    前言 前面的几篇博客中介绍了有关相机标定的基础知识(三维重建学习(1):基础知识:旋转矩阵与旋转向量.三维重建学习(2):相机标定基础).这次介绍一个十分经典的单目相机标定方法--张正友标定,并给出数 ...

  8. 张正友标定Opencv实现、标定流程以及图像坐标转为世界坐标

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/xiaomifanhxx/article/details/79560693 使用相机以前,首先要进行相 ...

  9. 张正友相机标定程序实现

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/hongbin_xu/article/details/78988450 前言 在前面的博客中( 三维重 ...

  10. 相机标定(六)—— 张正友标定法

    相机标定 一.相机标定的目的 1. 相机的成像过程 2. 相机标定的目的 3. 畸变与畸变矫正 二.张正友标定法简介 三.标定相机内外参 1. 求解内参和外参的积 2. 求解内参矩阵 3. 求解外参矩 ...

最新文章

  1. 自己动手写一个Struts2
  2. 【论文阅读和实现】On Spectral Clustering: Analysis and an algorithm【Python实现】
  3. linux虚拟实验室关闭了,centos8禁用selinux临时关闭/永久关闭
  4. 计算机网络·数据链路层.三个基本问题
  5. C#面向对象(一):明确几个简单的概念作为开胃菜
  6. 中值滤波讲解-Matlab
  7. jenkins中通过git发版操作记录
  8. 不修改数组找出重复的数字
  9. Quartz实线定期运行程序(Java)
  10. 鸿蒙轻内核M核源码分析:中断Hwi
  11. 《2017微信春节数据报告》出炉 初一到初五微信红包收发总量达到460亿个
  12. 国务院印发《政务信息资源共享管理暂行办法》
  13. RemObjects SDK 简介
  14. 90%企业都适用,搭建性能监控体系照抄就行
  15. 2021-07-06
  16. 网络信息安全之信息系统安全保障
  17. Allegro添加中文字体的简单有效方法
  18. 助力白纸一般的你面试——宏任务微任务
  19. android上传单个或多个文件
  20. 字符串的扩展距离问题(动态规划)

热门文章

  1. Landsat8数据初识和概述
  2. Python类中的__init__,__del__和__call__方法
  3. 罗盘时钟制作代码_抖音超火的姓氏罗盘壁纸,安卓和苹果都能做
  4. ElasticSearch解决中文搜索只能搜索单个字符的问题
  5. 实习踩坑之路:Mybatis写的sql语句有<符号的问题导致项目启动失败以及count(*)怎么对应到某个实体类的字段
  6. adb ps shell 查看进程_Appium学废系列(三) adb调试桥命令
  7. 我们公司使用了 6 年的分布式锁,很是牛逼啊!
  8. 如何画c语言箭头鼠标,简单的鼠标绘图程序
  9. python类方法为装饰器_类方法的python装饰器
  10. 跨服务器、跨数据库、多表联合查询