opencv中标定函数
calibrateCamera
在 OpenCV 中,calibrateCamera
函数用于进行相机标定,估计相机的内参和外参。相机标定的目的是确定相机在三维空间中的位置和方向,以及其光学特性。
函数原型
double cv::calibrateCamera(
const std::vector<std::vector<cv::Point3f>>& objectPoints,
const std::vector<std::vector<cv::Point2f>>& imagePoints,
cv::Size imageSize,
cv::Mat& cameraMatrix,
cv::Mat& distCoeffs,
std::vector<cv::Mat>& rvecs,
std::vector<cv::Mat>& tvecs,
int flags = 0,
cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, DBL_EPSILON)
);
参数说明
-
objectPoints
:- 三维空间中的点坐标,通常是一个三维标定板的点坐标,使用世界坐标系表示。每个图像的点集为一组。
-
imagePoints
:- 对应于图像中的点坐标,通常是通过特征检测(如角点检测)获得的。
-
imageSize
:- 图像的大小(宽度,高度),通常为
cv::Size(width, height)
。
- 图像的大小(宽度,高度),通常为
-
cameraMatrix
:- 输出参数,表示相机内参矩阵。初始化时可以使用
cv::Mat::eye(3, 3, CV_64F)
。
- 输出参数,表示相机内参矩阵。初始化时可以使用
-
distCoeffs
:- 输出参数,表示相机的畸变系数,通常为一个 5 或 8 元素的向量。
-
rvecs
:- 输出参数,表示每个图像的旋转向量,描述相机在世界坐标系中的方向。
-
tvecs
:- 输出参数,表示每个图像的平移向量,描述相机在世界坐标系中的位置。
-
flags
:- 可选参数,用于指定标定过程中的选项,例如是否使用初始估计。
-
criteria
:- 终止条件,用于控制迭代的停止条件。
返回值
- 返回相机重投影误差,通常用于评估标定的准确性。
示例代码
下面是一个使用 calibrateCamera
的简单示例:
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
int main() {
// 设定标定板的每个角点的三维坐标
std::vector<std::vector<cv::Point3f>> objectPoints; // 3D点
std::vector<std::vector<cv::Point2f>> imagePoints; // 2D点
// 假设我们有 10 张图像,每张图像都检测到角点
for (int i = 0; i < 10; ++i) {
std::vector<cv::Point3f> obj;
for (int j = 0; j < 6; ++j) { // 6x9 的角点
for (int k = 0; k < 9; ++k) {
obj.emplace_back(k * 20.0f, j * 20.0f, 0.0f); // 每个点间隔 20 单位
}
}
objectPoints.push_back(obj);
// 这里假设你已经检测到了相应的 2D 角点
std::vector<cv::Point2f> imgPoints; // 需要通过角点检测得到
imagePoints.push_back(imgPoints);
}
cv::Size imageSize(640, 480);
cv::Mat cameraMatrix = cv::Mat::eye(3, 3, CV_64F);
cv::Mat distCoeffs;
std::vector<cv::Mat> rvecs, tvecs;
// 进行相机标定
double reprojErr = cv::calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);
// 输出标定结果
std::cout << "Camera Matrix: " << cameraMatrix << std::endl;
std::cout << "Distortion Coefficients: " << distCoeffs << std::endl;
std::cout << "Reprojection Error: " << reprojErr << std::endl;
return 0;
}
总结
calibrateCamera
是进行相机标定的关键函数,能够估计相机的内参和外参,帮助纠正图像的畸变。在实际应用中,通常需要多张图像和相应的特征点来获得准确的标定结果。
stereoCalibrate
在 OpenCV 中,stereoCalibrate
函数用于进行立体相机标定。它可以计算两个相机的内参、外参以及相机之间的相对位置和方向,通常用于立体视觉系统中,以便恢复三维场景。
函数原型
double cv::stereoCalibrate(
const std::vector<std::vector<cv::Point3f>>& objectPoints,
const std::vector<std::vector<cv::Point2f>>& imagePoints1,
const std::vector<std::vector<cv::Point2f>>& imagePoints2,
cv::Mat& cameraMatrix1,
cv::Mat& distCoeffs1,
cv::Mat& cameraMatrix2,
cv::Mat& distCoeffs2,
cv::Size imageSize,
cv::Mat& R,
cv::Mat& T,
cv::Mat& E,
cv::Mat& F,
int flags = 0,
cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, DBL_EPSILON)
);
参数说明
-
objectPoints
:- 三维空间中的点坐标,通常是一个标定板的三维点集。
-
imagePoints1
:- 第一个相机中对应的图像点坐标。
-
imagePoints2
:- 第二个相机中对应的图像点坐标。
-
cameraMatrix1
:- 第一个相机的内参矩阵,输出参数。
-
distCoeffs1
:- 第一个相机的畸变系数,输出参数。
-
cameraMatrix2
:- 第二个相机的内参矩阵,输出参数。
-
distCoeffs2
:- 第二个相机的畸变系数,输出参数。
-
imageSize
:- 图像的大小,通常为
cv::Size(width, height)
。
- 图像的大小,通常为
-
R
:- 输出参数,表示旋转矩阵,描述两个相机之间的旋转关系。
-
T
:- 输出参数,表示平移向量,描述两个相机之间的平移关系。
-
E
:- 输出参数,表示基础矩阵的本质矩阵。
-
F
:- 输出参数,表示基础矩阵。
-
flags
:- 可选参数,用于指定标定过程中的选项。
-
criteria
:- 终止条件,用于控制迭代的停止条件。
返回值
- 返回重投影误差,通常用于评估标定的准确性。
示例代码
以下是一个使用 stereoCalibrate
的简单示例:
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
int main() {
// 设定标定板的每个角点的三维坐标
std::vector<std::vector<cv::Point3f>> objectPoints; // 3D点
std::vector<std::vector<cv::Point2f>> imagePoints1; // 第一台相机的2D点
std::vector<std::vector<cv::Point2f>> imagePoints2; // 第二台相机的2D点
// 假设我们有 10 张图像,每张图像都检测到角点
for (int i = 0; i < 10; ++i) {
std::vector<cv::Point3f> obj;
for (int j = 0; j < 6; ++j) { // 6x9 的角点
for (int k = 0; k < 9; ++k) {
obj.emplace_back(k * 20.0f, j * 20.0f, 0.0f); // 每个点间隔 20 单位
}
}
objectPoints.push_back(obj);
// 这里假设你已经检测到了相应的 2D 角点
std::vector<cv::Point2f> imgPoints1; // 第一台相机的检测结果
std::vector<cv::Point2f> imgPoints2; // 第二台相机的检测结果
imagePoints1.push_back(imgPoints1);
imagePoints2.push_back(imgPoints2);
}
cv::Size imageSize(640, 480);
cv::Mat cameraMatrix1 = cv::Mat::eye(3, 3, CV_64F);
cv::Mat distCoeffs1;
cv::Mat cameraMatrix2 = cv::Mat::eye(3, 3, CV_64F);
cv::Mat distCoeffs2;
cv::Mat R, T, E, F;
// 进行立体相机标定
double reprojErr = cv::stereoCalibrate(objectPoints, imagePoints1, imagePoints2,
cameraMatrix1, distCoeffs1,
cameraMatrix2, distCoeffs2,
imageSize, R, T, E, F);
// 输出标定结果
std::cout << "Camera Matrix 1: " << cameraMatrix1 << std::endl;
std::cout << "Camera Matrix 2: " << cameraMatrix2 << std::endl;
std::cout << "Rotation Matrix: " << R << std::endl;
std::cout << "Translation Vector: " << T << std::endl;
std::cout << "Reprojection Error: " << reprojErr << std::endl;
return 0;
}
总结
stereoCalibrate
是进行立体相机标定的关键函数,能够计算两个相机的内参和外参,帮助实现三维场景的重建。为了获得准确的结果,通常需要多张图像和相应的特征点。
stereoRectify
在 OpenCV 中,stereoRectify
函数用于对立体相机进行矫正,使得两个相机的视图可以在同一平面上进行比较和匹配。这个过程通常用于立体视觉应用,以便更容易提取深度信息。
函数原型
void cv::stereoRectify(
const cv::Mat& cameraMatrix1,
const cv::Mat& distCoeffs1,
const cv::Mat& cameraMatrix2,
const cv::Mat& distCoeffs2,
cv::Size imageSize,
const cv::Mat& R,
const cv::Mat& T,
cv::Mat& R1,
cv::Mat& R2,
cv::Mat& P1,
cv::Mat& P2,
cv::Mat& Q,
int flags = 0,
double alpha = -1,
cv::Size newImageSize = cv::Size(),
cv::Rect* validPixROI1 = 0,
cv::Rect* validPixROI2 = 0
);
参数说明
-
cameraMatrix1
:- 第一个相机的内参矩阵。
-
distCoeffs1
:- 第一个相机的畸变系数。
-
cameraMatrix2
:- 第二个相机的内参矩阵。
-
distCoeffs2
:- 第二个相机的畸变系数。
-
imageSize
:- 原始图像的大小,通常为
cv::Size(width, height)
。
- 原始图像的大小,通常为
-
R
:- 旋转矩阵,描述两个相机之间的旋转关系。
-
T
:- 平移向量,描述两个相机之间的平移关系。
-
R1
:- 输出参数,表示第一个相机的旋转矩阵。
-
R2
:- 输出参数,表示第二个相机的旋转矩阵。
-
P1
:- 输出参数,表示第一个相机的投影矩阵。
-
P2
:- 输出参数,表示第二个相机的投影矩阵。
-
Q
:- 输出参数,表示重投影矩阵,通常用于深度图的计算。
-
flags
:- 可选参数,控制矫正的行为。
-
alpha
:- 影响输出图像的大小和内容。
-1
表示输出图像的大小与输入图像相同,0
表示裁剪到有效区域,1
表示包含所有信息。
- 影响输出图像的大小和内容。
-
newImageSize
:- 新的图像大小。如果未指定,则使用
imageSize
。
- 新的图像大小。如果未指定,则使用
-
validPixROI1
:- 可选参数,输出第一个相机的有效区域。
-
validPixROI2
:- 可选参数,输出第二个相机的有效区域。
返回值
- 此函数没有返回值,但会通过输出参数返回矫正结果。
示例代码
以下是一个使用 stereoRectify
的简单示例:
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// 假设已经进行相机标定并获得以下参数
cv::Mat cameraMatrix1 = cv::Mat::eye(3, 3, CV_64F);
cv::Mat distCoeffs1 = cv::Mat::zeros(5, 1, CV_64F);
cv::Mat cameraMatrix2 = cv::Mat::eye(3, 3, CV_64F);
cv::Mat distCoeffs2 = cv::Mat::zeros(5, 1, CV_64F);
cv::Size imageSize(640, 480);
// 假设已经获得相机之间的旋转和位移
cv::Mat R = cv::Mat::eye(3, 3, CV_64F); // 旋转矩阵
cv::Mat T = cv::Mat::zeros(3, 1, CV_64F); // 平移向量
cv::Mat R1, R2, P1, P2, Q;
cv::Rect validPixROI1, validPixROI2;
// 进行立体图像矫正
cv::stereoRectify(cameraMatrix1, distCoeffs1,
cameraMatrix2, distCoeffs2,
imageSize, R, T,
R1, R2, P1, P2, Q,
0, -1, cv::Size(),
&validPixROI1, &validPixROI2);
// 输出结果
std::cout << "R1: " << R1 << std::endl;
std::cout << "R2: " << R2 << std::endl;
std::cout << "P1: " << P1 << std::endl;
std::cout << "P2: " << P2 << std::endl;
std::cout << "Q: " << Q << std::endl;
return 0;
}
总结
stereoRectify
是立体视觉系统中重要的一步,通过矫正两幅图像使其在同一平面上对齐,方便后续的深度计算和匹配。为了获得准确的矫正效果,通常需要在标定阶段获得准确的相机内参和外参。
原文地址:https://blog.csdn.net/qq_22424571/article/details/145216860
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!