从相机标定数据(.yml文件)读取相机参数并对单目相机的畸变图像进行校正

    单目相机,尤其是一些具有较大视场角的鱼眼相机,所拍摄的图片通常具有较大的桶形畸变。

    为了获得正确的图像,即“真实世界的直线在图片中也呈现为直线”,需要对相机拍摄的图片进行校正。

    校正需要相机的内参,而通过标定相机可以获得这些参数(标定的方法见我之前的博客)。一般情况下,标定之后都需要把获得的相机标定数据保存在一些文件中,通常使用“.yml”文件格式。保存在这种格式文件中的数据非常容易通过C++语言读取放入我们需要的程序当中。

    此处贴上其他作者分享的“读取和写入 opencv yml 相机标定参数”的代码作为参考。该代码非常简明易懂。

    写入数据到yml文件:

#include "opencv2/opencv.hpp"  
using namespace cv;  
int main(int, char** argv)  
{  
    FileStorage fs("test.yml", FileStorage::WRITE);  
    Mat cameraMatrix = (Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);  
    Mat distCoeffs = (Mat_<double>(5, 1) << 0.1, 0.01, -0.001, 0, 0);  
    fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;  
    fs.release();  
    return 0;  
}  

    从yml文件读取数据:

#include "opencv2/opencv.hpp"  
#include<iostream>  
using namespace cv;  
using namespace std;  
int main()  
{  
    FileStorage fs2("C:/Users/Administrator/Desktop/test.yml", FileStorage::READ);  
    Mat cameraMatrix2, distCoeffs2;  
    fs2["cameraMatrix"] >> cameraMatrix2;  
    fs2["distCoeffs"] >> distCoeffs2;  
    cout << cameraMatrix2 << endl;  
    cout << distCoeffs2 << endl;  
}  

    原文链接:https://blog.csdn.net/qq_15505637/article/details/75270615

    在对以上代码进行了一定修改之后,我终于成功地使用自己标定得到的数据实现了鱼眼相机的畸变校正。代码如下:

/******************首先添加一些必要的头文件************************/

#include "opencv2/core.hpp"
#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/calib3d.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include <cctype>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "opencv2/opencv.hpp"  
#include <iostream>
using namespace cv;
using namespace std;

int main()
{
/*************************** 1. 从yml文件读取相机标定数据*******************************/
	Mat cameraMatrix, distCoeffs;   //相机矩阵、畸变系数矩阵
	FileStorage fs2("F:\\SoftwareData\\OpenCV\\Study\\Calibration_sample\\calibration_sample\\x64\\Debug\\camera.yml", FileStorage::READ);   //此条命令可以读取之前获得的标定数据
	fs2["camera_matrix"] >> cameraMatrix;  //将文件中名为“camera_matrix”的变量的值赋给cameraMatrix
	fs2["distortion_coefficients"] >> distCoeffs;  //作用类似上一句

/*************************** 2. 读取需要校正的图片***************************************/
	Mat view; //声明准备装入待处理图像的Mat类变量
	Mat temp; //声明用于暂存的图像变量temp
		view = imread("F:\\SoftwareData\\OpenCV\\Study\\rectify_test\\rectify_test.bmp",1);  //读入待处理图像到view变量
		temp = view.clone();  //克隆原图像view至暂存图像变量temp


/*注意:两种方法生成的校正图片稍有区别。方法一生成的是没有黑色边缘的图。方法二生成的是有黑色边缘的图。*/


/************************** 3.1 查表法校正********************************/
/*	Mat map1, map2; //声明用于匹配的映射表map1,map2
	Size imageSize;  //声明图像尺寸
		imageSize = view.size();  //图像尺寸赋值

		initUndistortRectifyMap(cameraMatrix, distCoeffs, Mat(),  // 构建校正表格。initUndistortRectifyMap()这个函数很重要,它可以构建校正图像的查表,形成查表后,配合另一个remap()函数使用,可以提高校正图像的速度。
			getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0),
			imageSize, CV_16SC2, map1, map2);
		remap(temp, view, map1, map2, INTER_LINEAR);  //对view变量进行查表,查表为从map1->map2的映射关系,使用线性插值,输出图像为view图像变量。
*/
/************************** 3.2 使用校正函数校正********************************/
		
		undistort(temp, view, cameraMatrix, distCoeffs);  //校正图像,并存放在view当中

/****************************保存校正好的图片*****************************/
		imwrite("F:\\SoftwareData\\OpenCV\\Study\\rectify_test\\rectifed_image.bmp",view);

//**************************显示已经校正的图像************
		//	imshow("Image View", view);   //显示已经校正过的图像。

	return 0;
}

猜你喜欢

转载自blog.csdn.net/yibeiyese/article/details/80694133
今日推荐