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

复制代码
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();

 }



}

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

相关推荐
星火开发设计7 分钟前
C++ queue 全面解析与实战指南
java·开发语言·数据结构·c++·学习·知识·队列
橘颂TA13 分钟前
【剑斩OFFER】算法的暴力美学——力扣 394 题:字符串解码
数据结构·c++·结构与算法
new_zhou26 分钟前
vs2019+qt工程中生成dump文件及调试
开发语言·qt·visual studio·dump调试
txinyu的博客1 小时前
结合游戏场景理解,互斥锁,读写锁,自旋锁,CAS / 原子变量,分段锁
开发语言·c++·游戏
hugerat1 小时前
在AI的帮助下,用C++构造微型http server
linux·c++·人工智能·http·嵌入式·嵌入式linux
-森屿安年-1 小时前
unordered_map 和 unordered_set 的实现
数据结构·c++·散列表
九久。1 小时前
手动实现std:iterator/std:string/std::vector/std::list/std::map/std:set
c++·stl
小羊羊Python1 小时前
Sound Maze - 基于 SFML+C++14 的音效迷宫开源游戏 | MIT 协议
c++·游戏·开源
hqwest2 小时前
码上通QT实战16--监控页面08-连接后状态处理
qt·串口·信号与槽·serialport·通信过程·打开串口·com1
txinyu的博客2 小时前
HTTP服务实现用户级窗口限流
开发语言·c++·分布式·网络协议·http