相机标定C++\opencv4.5.1代码

后续还会更改

#include <io.h>
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void getFilesName(string& fileDirectory, string& fileType, vector<string>& filesName)
{
	string buffer = fileDirectory + "/*" + fileType;	// 拼接文件搜索路径,形如 "目录/*文件类型"

	intptr_t hFile;
	_finddata_t c_file;  	// 文件信息结构体
	hFile = _findfirst(buffer.c_str(), &c_file);  	// 开始查找第一个匹配的文件

	if (hFile == -1L)
		cout << "No " << fileType << " files in current directory!" << endl;
	else
	{
		string fullFilePath;
		// 循环查找并处理每个匹配的文件
		do
		{
			fullFilePath.clear();
			fullFilePath = fileDirectory + "/" + c_file.name;  // 拼接完整文件路径,形如 "目录/文件名"
			filesName.push_back(fullFilePath);			// 将完整文件路径存储到文件名向量中

		} while (_findnext(hFile, &c_file) == 0);
		_findclose(hFile);  // 关闭文件查找句柄
	}
}

void cameraCalibration(vector<string>& filesName, const Size &cornersNum, const Size &gridSize,
	Mat& cameraMatrix, Mat& distCoeffs, Mat& rvecsMat, Mat& tvecsMat)
{
	 Detect 2D corners 
	cout << "*****角点检测 starts*****" << endl;

	Size image_size;
	vector<Point2f> image_points;              // 2D corners of one image
	vector<vector<Point2f>> image_points_seq;  // 2D corners of all images
	for (int i = 0; i < filesName.size(); ++i)
	{

		cout << "Image " << filesName[i] << " processing..." << endl;
		Mat img = imread(filesName[i]);
		if (i == 0)  // get width and height only when reads the first image
		{
			image_size.width = img.cols;
			image_size.height = img.rows;
			cout <<"图片宽: "<< image_size.width << endl;
			cout <<"图片高: "<< image_size.height << endl;

		}

		// 检测棋盘格角点
		if (!findChessboardCorners(img, cornersNum, image_points))
		{
			cout << "Detect corners of " << filesName[i] << " failed. " << endl;
			waitKey(0);
			return;
		}
		else
		{
			Mat imgGray;
			cvtColor(img, imgGray, COLOR_RGB2GRAY);    // 将图像转换为灰度图

			// subpix processing to get more accurate results     使用亚像素处理以获得更精确的角点位置
			cv::cornerSubPix(imgGray, image_points, cv::Size(5, 8),
				cv::Size(-1, -1),
				cv::TermCriteria(TermCriteria::COUNT | TermCriteria::EPS, 20, 0.01));  //亚像素处理的迭代停止条件  使用迭代次数(COUNT)和迭代误差(EPS)的组合,最多迭代 20 次,或达到迭代误差 0.01 时停止。

			image_points_seq.push_back(image_points);    // 将处理后的角点添加到图像角点序列中
		}
	}

	 2D corners -> 3D corners   将检测到的2D角点映射到3D世界坐标系中,形成对象点序列。
	vector<vector<Point3f>> object_points_seq;
	for (int t = 0; t < filesName.size(); ++t)  //遍历所有图片文件
	{
		vector<Point3f> object_points;
		for (int i = 0; i < cornersNum.height; ++i)  //遍历棋盘格的高度方向上的角点
		{
			for (int j = 0; j < cornersNum.width; ++j)  //遍历棋盘格的宽度方向上的角点
			{
				Point3f realPoint;
				realPoint.x = i * gridSize.width;  //设置该角点在X轴上的坐标,根据棋盘格的行数和格子大小计算得出。
				realPoint.y = j * gridSize.height;
				realPoint.z = 0;  // due to all corners in the same plane   棋盘格的所有角点在同一平面上,因此Z轴坐标都为0
				object_points.push_back(realPoint);   // 将当前计算得到的3D角点坐标添加到object_points向量中。
			}
		}
		object_points_seq.push_back(object_points);
	}
	cout << "*****角点检测 ends*****" << endl;

	 Calibration 
	cout << "*****Calibration started*****" << endl;
	calibrateCamera(object_points_seq, image_points_seq, image_size, cameraMatrix, distCoeffs, rvecsMat, tvecsMat);
	//distCoeffs   畸变系数
	//rvecsMat   包含每张图像的旋转矩阵的向量。每个旋转矩阵对应一个图像
	//tvecsMat   包含每张图像的旋转矩阵的向量。每个旋转矩阵对应一个图像
	cout << "*****Calibration ended*****" << endl;

}

void saveResults(const string &file, const Mat &cameraMatrix, const Mat &distCoeffs, const Mat &rvecsMat, const Mat &tvecsMat) {
	ofstream resultFile(file, ios::out);   //创建一个输出文件流对象 resultFile,以便将相机标定结果写入文件。

	if (!resultFile) {
		cout << "Opening " << file << " failed." << endl;
		return;
	}
	// 内部参数矩阵输出
	cout << "Intrinsic parameters of this camera: " << endl;
	cout << cameraMatrix << endl;
	resultFile << "Intrinsic parameters of this camera: " << endl;
	resultFile << cameraMatrix << endl;

	resultFile << endl;

	//  旋转矩阵输出
	cout << "rvecsMat" << endl;
	cout << rvecsMat << endl;
	resultFile << "rvecsMat" << endl;
	resultFile << rvecsMat << endl;

	resultFile << endl;

	//  平移矩阵输出
	cout << "tvecsMat" << endl;
	cout << tvecsMat << endl;
	resultFile << "tvecsMat" << endl;
	resultFile << tvecsMat << endl;

	resultFile << endl;

	// 畸变系数输出
	cout << "Distortion coefficients of this camera: " << endl;
	cout << distCoeffs << endl;
	resultFile << "Distortion coefficients of this camera: " << endl;
	resultFile << distCoeffs << endl;

	resultFile.close();

	cout << "results saved to " << file << endl;
}

int main() {
	string resultFile;  // 结果文件
	string fileDirectory;  // 待标定图片文件夹
	string fileType;  // 待标定图片类型

	cout << "Please input where to save results: " << endl;  //   E:\\shipsee\\test\\test\\calibration_result.txt
	cin >> resultFile;
	cout << "Please input where are the pictures: " << endl;  //      E:\\shipsee\\test\\test\\images
	cin >> fileDirectory;
	cout << "Please input which type of pictures to processing: " << endl;  //     .jpg
	cin >> fileType;

	// 获取文件名
	vector<string> filesName;
	getFilesName(fileDirectory, fileType, filesName);

	Size cornersNum = Size(5, 8);  // 角点行列数
	Size gridSize = Size2d(23, 23);  // 棋盘格大小

	Mat cameraMatrix = Mat(3, 3, CV_32FC1, Scalar::all(0));  // 相机内参数矩阵
	Mat distCoeffs = Mat(1, 5, CV_32FC1, Scalar::all(0));    // 相机畸变系数

	Mat rvecsMat = Mat(3, 3, CV_32FC1, Scalar::all(0));      // 旋转矩阵
	Mat tvecsMat = Mat(3, 1, CV_32FC1, Scalar::all(0));      // 平移矩阵

	cameraCalibration(filesName, cornersNum, gridSize, cameraMatrix, distCoeffs, rvecsMat, tvecsMat);
	saveResults(resultFile, cameraMatrix, distCoeffs, rvecsMat, tvecsMat);

	system("pause");
	return 0;
}

[点击并拖拽以移动]

​

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值