OpenCV_Camera Calibration and Rectification under QT creator( 相机标定及矫正 | QT creator环境 )

24 篇文章 0 订阅

流程:

//1.找多副棋盘格图像角点,存入2D图像点及3D坐标点
//2.进行相机标定 获取标定参数:相机矩阵 畸变矩阵 旋转向量和平移向量
//3.映射相应矩阵 获取x y映射函数   (像高hi/物高h0=焦距f/物距d0)
//4.应用映射函数,输出未畸变图像

main 函数:

 

#include <QCoreApplication>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp> //引用cv::KeyPoint 特征检测器通用接口
# include <opencv2/calib3d/calib3d.hpp>
//#include <opencv2/legacy/legacy.hpp>   //引用cv::cornerSubPix()
#include  "CameraCalibrator.h"
#include  <iostream>
#include <iomanip>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //2.使用CameraCalibritor类对图像进行矫正
       //cv::Mat image = cv::imread("../../aTestImage/chessboards/chessboard01.jpg", 0);

        //cv::namedWindow("Image");

       cv::Mat image;
        std::vector<std::string> filelist  ;  //????初始化
        for (int i = 1; i <= 20; i++)//将指定文件夹中20张图片添加到filelist中
        {
           std::stringstream str;
           str << "../TestPic/chessboards/chessboard" << std::setw(2) << std::setfill('0') << i << ".jpg";
           std::cout << str.str() << std::endl;
           filelist.push_back(str.str());
           image = cv::imread(str.str(), 0);

        //cv::imshow("Image", image);
        //cv::waitKey(100);
        }

        CameraCalibrator calibr;
        cv::Size boardSize(6, 4);
        calibr.addChessboardPoints(filelist, boardSize);:imread( filelist[0]);
        cv::Size cvsize =cv::Size(320,240);
         //指定标定文件夹  标定尺寸
        //image =cv: calibr.calibrate(cvsize);  //进行标定image.size()

        image =cv::imread( filelist[11]);
        cv::Mat result = calibr.remap(image);  //进行矫正

        cv::namedWindow("image");  //显示src
        cv::imshow("image", image);
        cv::namedWindow("result");  //显示结果
        cv::imshow("result", result);

        cv::waitKey(0);

    return a.exec();
}


CameraCalibrator.h 头文件:

 

 

#pragma once
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp> //引用cv::KeyPoint 特征检测器通用接口
#include <opencv2/imgproc/imgproc.hpp>
# include <opencv2/calib3d/calib3d.hpp>
//#include <opencv2/legacy/legacy.hpp>   //引用cv::cornerSubPix()
class CameraCalibrator
{
public:
    CameraCalibrator() ;

	 ~CameraCalibrator();
	//提取 文件中各个图像 指定数目 棋盘格角点
	int addChessboardPoints(const std::vector<std::string>&filelist, cv::Size &boardSize);
	//添加角点到2D图像点和3D场景点坐标系中
	void addPoints(const std::vector<cv::Point2f> &imageCorners, const std::vector<cv::Point3f> &objectCorners);
	//进行标定,并返回投影误差(相机矩阵,畸变矩阵,旋转向量,平移向量)
    double  calibrate(cv::Size &imageSize);
	//标定后去除图像中的畸变
	cv::Mat remap(const cv::Mat &image);
private:
    std::vector< std::vector<cv::Point3f> >objectPoints;  //存储世界坐标点
    std::vector< std::vector<cv::Point2f> >imagePoints;  //存储像素坐标点
	cv::Mat  cameraMatrix;  //输出相机矩阵
	cv::Mat  distCoeffs;    //输出畸变矩阵
	int flag;  //标定方式
	cv::Mat map1, map2;  //去图像畸变的x y 映射函数
	bool mustInitUndistort;  //是否初始化失真
	
};


CameraCalibrator.cpp:

 

 

 

 

#include "CameraCalibrator.h"
//#include <opencv2/core/core.hpp>
//#include <opencv2/highgui/highgui.hpp>
//#include <opencv2/features2d/features2d.hpp> //引用cv::KeyPoint 特征检测器通用接口
//# include <opencv2/calib3d/calib3d.hpp>
//#include <opencv2/legacy/legacy.hpp>   //引用cv::cornerSubPix()

CameraCalibrator::CameraCalibrator()
{
    flag=0;
    mustInitUndistort=true;
}


CameraCalibrator::~CameraCalibrator()
{
}

int CameraCalibrator::addChessboardPoints(const std::vector<std::string>& filelist, cv::Size & boardSize)
{
	std::vector< cv::Point2f> imageCorners;  //对应图像上(i, j)棋盘格角点
	std::vector< cv::Point3f> objectCorners;  //对应世界坐标系(X,Y,Z)棋盘格角点
	//获取3D场景中的点
	for (int i = 0; i < boardSize.height; i++)
	{
		for (int j = 0; j < boardSize.width; j++)
		{
			objectCorners.push_back(cv::Point3f(i, j, 0.0f));
		}
	}

	//获取2D图像中的点
	cv::Mat  image;
	int successes = 0;
	for (int i = 0; i < filelist.size(); i++)
	{
	      image = cv::imread(filelist[i], 0);
        bool found = cv::findChessboardCorners(image, boardSize, imageCorners); //获取棋盘格角点  ?? under VS "block type is valid"
       // cv::cornerSubPix(image, imageCorners, cv::Size(5, 5), cv::Size(-1, -1),  //获取亚像素精度
         //    cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 30, 0.1)); //终止条件为迭代30次或达到精度0.1
		
        if (imageCorners.size() == boardSize.area())
        {
            addPoints(imageCorners, objectCorners);
            successes++;
        }
	}  
	return successes;  //block type is valid
}

void CameraCalibrator::addPoints(const std::vector<cv::Point2f>& imageCorners, const std::vector<cv::Point3f>& objectCorners)
{
	imagePoints.push_back(imageCorners);
	objectPoints.push_back(objectCorners);
}

double CameraCalibrator::calibrate(cv::Size &imageSize)
{
	mustInitUndistort = true;  //必须重新去畸变
	std::vector<cv::Mat> rvecs, tvecs;  //输出旋转向量和平移向量
	return  calibrateCamera(objectPoints,imagePoints,imageSize,cameraMatrix,distCoeffs,rvecs,tvecs,flag);
}

cv::Mat CameraCalibrator::remap(const cv::Mat & image)
{
	cv::Mat undistorted; //未畸变图像
    if (mustInitUndistort)
    {
        //初始化未畸变矫正映射图像(相机矩阵,畸变矩阵,可选矫正矩阵,生成的未畸变相机矩阵,生成的未畸变相机矩阵的尺寸,输出的映射图像类型,X坐标映射函数,Y坐标映射函数)
        cv::initUndistortRectifyMap(cameraMatrix, distCoeffs, cv::Mat(), cv::Mat(),cv::Size(320,240), CV_32FC1, map1, map2);
        mustInitUndistort = false;
    }
    cv::remap(image, undistorted, map1, map2,cv::INTER_LINEAR);  //应用映射函数,输出未畸变图像  | 差值类型
	return undistorted;
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惊鸿一博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值