matlab进行棋盘格标定,得到参数后用opencv进行矫正

第一步,拍摄多张棋盘格标定图

第二步,打开matlab工具箱进行内参自动标定计算,参考如下的链接:

https://blog.csdn.net/leonardohaig/article/details/81254179

https://blog.csdn.net/qq_41880787/article/details/124966057?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167279765616800188541526%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=167279765616800188541526&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-124966057-null-null.blog_rank_default&utm_term=matlab%20%E7%9B%B8%E6%9C%BA%E6%A0%87%E5%AE%9A%E5%90%8E%20opencv%E7%9F%AB%E6%AD%A3&spm=1018.2226.3001.4450 需要注意的是,matlab导出的cameraParams.IntrinsicMatrix内参矩阵是和opencv的是转置关系。

畸变系数的排布是【k1,k2,p1,p2,k3].

第三步,将matlab计算的cameraParams参数导出成xml文件,那么上述需要注意的问题就直接在导出的时候解决。

function writeXML(cameraParams,file)
%writeXML(cameraParams,file)
%功能:将相机校正的参数保存为xml文件
%输入:
%cameraParams:相机校正数据结构
%file:xml文件名
%说明在xml文件是由一层层的节点组成的。
%首先创建父节点 fatherNode,
%然后创建子节点 childNode=docNode.createElement(childNodeName),
%再将子节点添加到父节点 fatherNode.appendChild(childNode)
docNode = com.mathworks.xml.XMLUtils.createDocument('opencv_storage'); %创建xml文件对象
docRootNode = docNode.getDocumentElement; %获取根节点
IntrinsicMatrix = ((cameraParams.IntrinsicMatrix)'); %*相机内参矩阵,千万记住要转置*
RadialDistortion = cameraParams.RadialDistortion; %相机径向畸变参数向量1*3
TangentialDistortion =cameraParams.TangentialDistortion; %相机切向畸变向量1*2
%Distortion = [RadialDistortion(1:2),TangentialDistortion,RadialDistortion(3)]; %当RadialDistortion为3维时,构成opencv中的畸变系数向量[k1,k2,p1,p2,k3]
Distortion = [RadialDistortion(1:2),TangentialDistortion,0]; %当RadialDistortion为2维时,构成opencv中的畸变系数向量[k1,k2,p1,p2,k3]

camera_matrix = docNode.createElement('camera-matrix'); %创建mat节点
camera_matrix.setAttribute('type_id','opencv-matrix'); %设置mat节点属性
rows = docNode.createElement('rows'); %创建行节点
rows.appendChild(docNode.createTextNode(sprintf('%d',3))); %创建文本节点,并作为行的子节点
camera_matrix.appendChild(rows); %将行节点作为mat子节点

cols = docNode.createElement('cols');
cols.appendChild(docNode.createTextNode(sprintf('%d',3)));
camera_matrix.appendChild(cols);

dt = docNode.createElement('dt');
dt.appendChild(docNode.createTextNode('d'));
camera_matrix.appendChild(dt);

data = docNode.createElement('data');
for i=1:3
    for j=1:3
        data.appendChild(docNode.createTextNode(sprintf('%.16f ',IntrinsicMatrix(i,j))));
    end
    data.appendChild(docNode.createTextNode(newline));
end
camera_matrix.appendChild(data);
docRootNode.appendChild(camera_matrix);

distortion = docNode.createElement('distortion');
distortion.setAttribute('type_id','opencv-matrix');
rows = docNode.createElement('rows');
rows.appendChild(docNode.createTextNode(sprintf('%d',5)));
distortion.appendChild(rows);

cols = docNode.createElement('cols');
cols.appendChild(docNode.createTextNode(sprintf('%d',1)));
distortion.appendChild(cols);

dt = docNode.createElement('dt');
dt.appendChild(docNode.createTextNode('d'));
distortion.appendChild(dt);
data = docNode.createElement('data');
for i=1:5
      data.appendChild(docNode.createTextNode(sprintf('%.16f ',Distortion(i))));
end
distortion.appendChild(data);

docRootNode.appendChild(distortion);

xmlFileName = file;
xmlwrite(xmlFileName,docNode);
end

然后在matlab命令行运行

writeXML(cameraParams2,'cameraParams.xml');

 因为的导出的参数叫cameraParams2。

第四步,建立opencv的c++程序,输入图像进行矫正

#include <windows.h>
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/utils/logger.hpp>
#include <thread>
#include <stdio.h>
#include <string.h>
#include <include/opencv2/stitching.hpp>
#include<opencv2/calib3d.hpp>

using namespace std;
using namespace cv;
int main(int argc, char* argv[])                                                                                            
{
    opencvreadjiaozheng();
    //cailida();
	//stitcher();
    //align();
	return 0;
}

void  opencvreadjiaozheng()
{
    Mat src = imread("C:\\Users\\lixiaowei\\Desktop\\标定图\\1.3\\Image_w5472_h3648_fn332.jpg");
    Mat distortion = src.clone();
    Mat camera_matrix = Mat(3, 3, CV_32FC1);
    Mat distortion_coefficients;


    //导入相机内参和畸变系数矩阵
    FileStorage file_storage("C:\\Users\\lixiaowei\\Desktop\\标定图\\cameraParams.xml", FileStorage::READ);
    file_storage["camera-matrix"] >> camera_matrix;
    file_storage["distortion"] >> distortion_coefficients;
    file_storage.release();
    //矫正
    undistort(src, distortion, camera_matrix, distortion_coefficients);

    namedWindow("img", WINDOW_NORMAL);
    imshow("img", src);
    namedWindow("undistort", WINDOW_NORMAL);
    imshow("undistort", distortion);
    //imwrite("undistort.jpg", distortion);

    waitKey(0);
}

注意xml文件和图像文件的路径,根据自己的来修改,

简单总结一下,然后矫正也有两种方法:

目前opencv在标定完后得到相机内参及畸变系数,要么通过cv::undistort()直接得到去畸变的图像,要么通过v::getOptimalNewCameraMatrix()得到新的矩阵,再通过cv::initUndistortRectifyMap()得到x轴与y轴映射,最后通过cv::remap()将原图映射到新图。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值