相机标定小工具(单目+双目)技术分享

复制代码
void stereo_Calibrate::calibrateStereo()
{

    int current = 1;
    QDir dirL(imgsrcDirPathl+"/left");
    QDir dirR(imgsrcDirPathl+"/right");
    QStringList imagelistL;
    QStringList imagelistR;
    imagelistL<<"*.jpg"<<"*.bmp"<<"*.png";
    imagelistR<<"*.jpg"<<"*.bmp"<<"*.png";
    dirL.setNameFilters(imagelistL);
    dirR.setNameFilters(imagelistR);
    int imagecuont =dirL.count();
    framenumber=dirL.count();
    std::string dirpathL =imgsrcDirPathl.toStdString();
    std::string dirpathR =imgsrcDirPathl.toStdString();
    int success_n=0;
        for(int i=0;i<imagecuont;i++)
        {

        std::string imagenameL =dirpathL+"/left/"+dirL[i].toStdString();
        imageL = cv::imread(imagenameL);
        cv::cvtColor(imageL,grayimageL,cv::ColorConversionCodes::COLOR_BGR2GRAY);

        std::string imagenameR =dirpathR+"/right/"+dirR[i].toStdString();
        imageR = cv::imread(imagenameR);

        cv::cvtColor(imageR, grayimageR, cv::ColorConversionCodes::COLOR_BGR2GRAY);

        bool foundL, foundR;

        foundL = cv::findChessboardCorners(imageL,boardsize,cornerL);
        foundR = cv::findChessboardCorners(imageR, boardsize, cornerR);

        if (foundL == true && foundR == true)
        {
        cv::cornerSubPix(grayimageL,cornerL,cv::Size(11,11),cv::Size(-1,-1),cv::TermCriteria(cv::TermCriteria::MAX_ITER|cv::TermCriteria::EPS, 30, 1e-6));
        cv::cornerSubPix(grayimageR, cornerR, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS, 30, 1e-6));
        cv::drawChessboardCorners(imageL,boardsize,cornerL,foundL);
        cv::drawChessboardCorners(imageR, boardsize, cornerR, foundR);
        cv::Mat Tg;
        cv::hconcat(imageL,imageR,Tg);
        cv::imshow("F", Tg);
        cv::moveWindow("F", 500, 100);
        cv::waitKey();

        imagepointL.push_back(cornerL);
        imagepointR.push_back(cornerR);
        success_n++;
        std::cout << "The image  " << current << "  is good" <<  std::endl;

        }
        else
        {
            std::cout << "The image is bad please try again" <<  std::endl;
        }
        current++;
    }
//===========================================================================================================================================单目标定矩阵写入

        cv::Size square_size = cv::Size(cellSize_width, cellSize_height);
        std::vector<std::vector<cv::Point3f>> object_pointsL; /* 保存标定板上角点的三维坐标 */
        std::vector<cv::Mat> tvecsMatL;  /* 每幅图像的旋转向量 */
        std::vector<cv::Mat> rvecsMatL;  /* 每幅图像的平移向量 */
        std::vector<cv::Point3f> realPointL;

        std::vector<std::vector<cv::Point3f>> object_pointsR; /* 保存标定板上角点的三维坐标 */
        std::vector<cv::Mat> tvecsMatR;  /* 每幅图像的旋转向量 */
        std::vector<cv::Mat> rvecsMatR;  /* 每幅图像的平移向量 */
        std::vector<cv::Point3f> realPointR;

 if(success_n!=0)
{
    for(int i=0;i<success_n;i++)
   {
        for (int i = 0; i < boardhight; i++)
        {
            for (int j = 0; j < boardwidth; j++)
            {
                cv::Point3f tempPointL;
                /* 假设标定板放在世界坐标系中z=0的平面上 */
                tempPointL.x = i * square_size.width;
                tempPointL.y = j * square_size.height;
                tempPointL.z = 0;
                realPointL.push_back(tempPointL);
            }

        }

        object_pointsL.push_back(realPointL);
        realPointL.clear();
    }
    for(int i=0;i<success_n;i++)
   {
        for (int i = 0; i < boardhight; i++)
        {
            for (int j = 0; j < boardwidth; j++)
            {
                cv::Point3f tempPointR;
                /* 假设标定板放在世界坐标系中z=0的平面上 */
                tempPointR.x = i * square_size.width;
                tempPointR.y = j * square_size.height;
                tempPointR.z = 0;
                realPointR.push_back(tempPointR);
            }

        }

        object_pointsR.push_back(realPointR);
        realPointR.clear();
    }
    cv::calibrateCamera(object_pointsL, imagepointL, imageL.size(), L_cameraMatrix, L_distCoeffs, rvecsMatL, tvecsMatL,
                           cv::CALIB_FIX_K3, cv::TermCriteria(cv::TermCriteria::EPS+cv::TermCriteria::COUNT, ITER,accuracy));//---------------------------


    cv::calibrateCamera(object_pointsR, imagepointR, imageR.size(), R_cameraMatrix, R_distCoeffs, rvecsMatR, tvecsMatR,
                           cv::CALIB_FIX_K3, cv::TermCriteria(cv::TermCriteria::EPS+cv::TermCriteria::COUNT, ITER,accuracy));//-----


//======================================================================================================================================单目标定矩阵写入
    QMessageBox mesbox;
    mesbox.setText("start stereoCalibrate!");
    mesbox.exec();
    worldpoint();
    double err = cv::stereoCalibrate(objpoint, imagepointL, imagepointR, L_cameraMatrix, L_distCoeffs, R_cameraMatrix, R_distCoeffs, imagesize, R, T, E, F,
        cv::CALIB_USE_INTRINSIC_GUESS, cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 30, 1e-6));

    qDebug()<< "The err = " << err ;

    cv::stereoRectify(L_cameraMatrix,L_distCoeffs, R_cameraMatrix,R_distCoeffs,imagesize,R,T,R1,R2,P1,P2,Q, cv::CALIB_ZERO_DISPARITY, -1, imagesize, &validROIL, &validROIR);

    cv::initUndistortRectifyMap(L_cameraMatrix,L_distCoeffs,R1,P1,imagesize, CV_32FC1,maplx,maply);
    cv::initUndistortRectifyMap(R_cameraMatrix,R_distCoeffs,R2,P2,imagesize,CV_32FC1,maprx,mapry);
    outputparam();
 }
 else
 {
     QMessageBox mesbox;
     mesbox.setText("calibrate faile!");
     mesbox.exec();

 }



}

以上就是软件的主要代码,相信大家都可以做出来了。加油!

相关推荐
爱吃涮毛肚的肥肥(暂时吃不了版)2 小时前
仿腾讯会议——音频服务器部分
c++·qt·面试·职场和发展·音视频·腾讯会议
DpHard2 小时前
自用Vscode 配置c++ debug环境
c++·ide·vscode
旭唐3 小时前
Qt Widgets模块功能详细说明,基本控件:QCheckBox(三)
qt·qbuttongroup·qt widgets·qcheckbox·qradionbutton
hy____1233 小时前
C++多态的详细讲解
开发语言·c++
superior tigre3 小时前
C++学习:六个月从基础到就业——C++20:范围(Ranges)进阶
c++·学习·c++20
小葡萄20253 小时前
黑马程序员C++2024版笔记 第0章 C++入门
开发语言·c++·笔记
不二一4 小时前
linux c++头文件生成源文件 使用python脚本 配置vim快捷键
linux·c++·python
Lazy Dave4 小时前
C++开源库argh使用教程
c++·开源·argh
奇树谦5 小时前
VTK|显示三维图像的二维切片
c++·vtk·qt5·三维显示
老歌老听老掉牙5 小时前
Open CASCADE学习|几何体切片处理:OpenMP与OSD_Parallel并行方案深度解析
c++·学习·open cascade·切片处理