张正友标定论文的解读和C++代码编写

Posted qq_38650944

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了张正友标定论文的解读和C++代码编写相关的知识,希望对你有一定的参考价值。

1.概述

张正友标定相机内参是非常经典的标定算法,现在代码已经被集成到MATLAB和opencv里面。不过因为算法涉及到基础的相机坐标系、图像坐标系、公式推导,以及优化算法,故根据张正友论文进行分模块代码编写。

2.代码地址

https://github.com/Shelfcol/Zhangzhengyou_calib_cam_intrinsic

3.简单解析

此C++代码是根据张正友的步骤进行分模块编写的,自认为逻辑还是比较清晰。分别为:

求H、求K、求旋转平移、求畸变稀疏、Ceres优化

bool CamIntrCalib::Calibrate()

    std::cout << "Calibrate with Zhangzhengyou" << std::endl;
    if (ReadPics() && GetKeyPoints())
    
        CalcH();
        // CalcHWithCV();
        // ValidateH();

        CalcK();
        CalcT();
        CalcDistCoeff();
        std::cout << "reproject error before ceres optimizing:" << std::endl;
        CalcRepjErr();
        Optimize();
        std::cout << "reproject error after ceres optimizing:" << std::endl;
        CalcRepjErr();
        return true;
    
    return false;

代码里面也对比实现了调用opencv算法进行标定,主要的函数就是

        cv::calibrateCamera(corner_3d_vec, points_2d_vec_, cv::Size(points_per_col_, points_per_row_),
                            K, dist_coef, rvecs, tvecs, CV_CALIB_FIX_K3 | CV_CALIB_ZERO_TANGENT_DIST);

最终跟opencv算法的结果对比下,内参和冲投影误差的差别都在0.01以内,精度较高

参数

zhang(我们)

opencv

相机内参

fx=589.9421322083375

fy=589.0314402379594

u0=323.830691209651

v0=240.716451101392

fx=589.9534727708858

fy=589.043571094065

u0=323.8345405252027

v0=240.7136136327917

畸变系数

k1=0.08908862963423921

k2=-0.0927595079832754

k1=0.08907964252174579

k2=-0.09266222570771097

重投影误差

0.275026

0.274992

在编写代码的时候也遇到了一个跟平常算法不一样的结构体,卡了很久,就是cv::Size(col,row)是列在前。

具体算法公式的详细推导都写在论文后面了,代码里面也是对应着写的,所以大家可以直接去看github地址里面的论文和代码进行学习。

4.一点学习感受

有人问我opencv都有现成的库,为啥还要自己实现,我认为:

1)对论文的理解会在你真正编写和调试成功之后有质的飞跃,虽然你原本看似成功推导了公式,但是代码实现的时候你也会遇到很多问题,而一个个问题的解决会加深你的理解;

2)对opencv、ceres等库的使用也会更加熟悉;

3)对C++代码能力提升也是很有帮助的;

4)参加工作之后,我才深刻意识到,现实的工作需求是千奇百怪的,绝大多数优秀的开源代码并不是直接照搬就可以解决老板分配给你的任务,里面包含的思想才是真正对你有帮助的。而想对一个算法举一反三,就必须要对其具体思想和实现有深刻理解,而在时间有空的情况下,自己实现一遍理解是更加深刻的;如果没有那么多时间的话,对开源代码进行改进,或者给开源代码加一些其他开源代码的模块,比如给ORBSLAM加动态物去除,G2O改为Ceres之类的,你可以说有的代码已经实现了,但是我觉得你自己再去自己加一下,调试一下,你对整个代码的理解肯定会不一样的。

纸上得来终觉浅,绝知此事要躬行,加油吧,少年。

最后说一句,大家要是觉得对自己有帮助的话,还望不吝star哦。😃😃😃

5.Reference

论文: "A Flexible New Technique for Camera Calibration" (2000).

代码参考:

https://github.com/zhiyuanyou/Calibration-ZhangZhengyou-Method

https://github.com/SHU-FLYMAN/ZhangZhengYou

以上是关于张正友标定论文的解读和C++代码编写的主要内容,如果未能解决你的问题,请参考以下文章

张正友相机标定算法解读

机器视觉1. 张正友平面标定[转]

相机标定的内参、外参、畸变参数

vrep如何进行相机标定

SLAM入门之视觉里程计:相机标定 张正友经典标定法详解

OpenCV实现张正友相机标定源代码