利用opencv中带的相机标定camera_calibration.cpp文件,整理后进行相机矫正。
在opencv中的目录:/opencv-3.3.0/samples/cpp/tutorial_code/calib3d/camera_calibration
在里面还有需要的in_VID5.xml、VID5.xml根据自己需要进行修改。
另外需要事先拍好的图片或视频或直接用摄像头进行标定。
一、认识函数
1、bool cv::findChessboardCorners( // 如果找到角点则返回true
cv::InputArray image, // 输入的棋盘格图像(8UC1或8UC3)
cv::Size patternSize, // 棋盘格内部角点的行、列数
cv::OutputArray corners, // 输出的棋盘格角点
int flags = cv::CALIB_CB_ADAPTIVE_THRESH
| cv::CALIB_CB_NORMALIZE_IMAGE
);
2、void cv::cornerSubPix(
cv::InputArray image, // 输入图像
cv::InputOutputArray corners, // 角点(既作为输入也作为输出)
cv::Size winSize, // 区域大小为 NXN; N=(winSize*2+1)
cv::Size zeroZone, // 类似于winSize,但是总具有较小的范围,Size(-1,-1)表示忽略
cv::TermCriteria criteria // 停止优化的标准
);
3、 void cv::drawChessboardCorners(
cv::InputOutputArray image, // 棋盘格图像(8UC3)即是输入也是输出
cv::Size patternSize, // 棋盘格内部角点的行、列数
cv::InputArray corners, // findChessboardCorners()输出的角点
bool patternWasFound // findChessboardCorners()的返回值
);
4、bitwise_not(Mat, Mat);//图像反转
5、void cv::undistort ( InputArray src,
OutputArray dst,
InputArray cameraMatrix,
InputArray distCoeffs,
InputArray newCameraMatrix = noArray()
)
6、void cv::initUndistortRectifyMap(
InputArray _cameraMatrix,
InputArray _distCoeffs,
InputArray _matR,
InputArray _newCameraMatrix,
Size size, int m1type,
OutputArray _map1,
OutputArray _map2 )
7、void cv::remap ( InputArray src,
OutputArray dst,
InputArray map1,
InputArray map2,
int interpolation,
int borderMode = BORDER_CONSTANT,
const Scalar & borderValue = Scalar()
)
二、代码,有注释
1.cameracalibrate.hpp
#ifndef CAMERACALIBRATE_HPP
#define CAMERACALIBRATE_HPP
#include <iostream>
#include <time.h>
#include <sstream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 };
class cameraCalibrate;
class cameraCalibrate
{
public:
/**
* @brief 构造函数,初始化参数inputDetect,flag
* @param
* @author
* @data
*/
cameraCalibrate();
/**
* @brief 向输出文件写入数据
* @param
* @author
* @data
*/
void write(FileStorage &fs) const;
/**
* @brief 从输入文件读取节点数据
* @param
* @author
* @data
*/
void read(const FileNode &node);
/**
* @brief 切换到下一张图片
* @param
* @author
* @data
*/
Mat nextImage();
/**
* @brief 从图片数据文件中读取图片列表
* @param
* @author
* @data
*/
static bool readImageList(const string& filename, vector<string>& list);
/**
* @brief 检查从数据文件读取的参数是否合法,通过inputCheck访问
* @param
* @author
* @data
*/
void chectInput();
public:
enum Pattern { NOT_EXISTING, CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID }; //检测模式
//无检测,棋盘,圆形网格,非对称圆形网格
enum InputType {INVALID, CAMERA, VIDEO_FILE, IMAGE_LIST}; //输入类型:无类型,相机,视频,图像
int cameraID; // 使用摄像头为摄像头标号
vector<string> imageList; // 使用图像为图像名字列表
int atImageList; // 当前第几张图像
VideoCapture inputCapture; // 使用摄像头,打开的摄像头
InputType inputType; // 输入类型,包括INVALID, CAMERA, VIDEO_FILE, IMAGE_LIST
bool inputCheck; // 检测输入数据是否合法
int flag; // 执行动作标志
Pattern calibrationPattern; // 检测模式,包括NOT_EXISTING, CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID
// 由patternToUse转化
string patternToUse; // 将要使用的模式,从输入文件中读取转化为Pattern
Size boardSize; // 棋盘格子个数 横排个数width,纵排个数height
float squareSize; // 格子大小 边长单位 mm
int nrFrames; // 图片张数
float aspectRatio; // 宽高比
int delay; // video延时获取帧
bool bwritePoints; // 非0在输出文件中写入特征点
bool bwriteExtrinsics; // 非0在输出文件中写入相机外部参数
bool calibZeroTangentDist; // 非0假设切向畸变为0
bool calibFixPrincipalPoint;// 非0在全局优化中主角点不变
bool flipVertical; // 非0在水平轴上翻转输入图像
string outputFileName; // 输出文件名称
bool showUndistorsed; // 非0显示采集图像
string input; // 图像输入文件名称,可以是摄像头标号
public:
/**
* @brief 运行校准并保存
* @param
* @author
* @data
*/
bool runCalibrationAndSave(/*cameraCalibrate& s, */Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,
vector<vector<Point2f> > imagePoints );
/**
* @brief 计算重投影误差
* @param
* @author
* @data
*/
double computeReprojectionErrors( const vector<vector<Point3f> >& objectPoints,
const vector<vector<Point2f> >& imagePoints,
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
const Mat& cameraMatrix , const Mat& distCoeffs,