双目相机标定C++ OpenCV实现
时间: 2025-04-05 13:15:16 浏览: 36
### 使用 C++ 和 OpenCV 实现双目相机标定
为了实现双目相机标定,可以按照以下方法完成整个流程。此过程涉及角点检测、立体标定以及校正等内容。
#### 1. 开发环境配置
在开始编写代码前,需确保已正确配置开发环境。这包括安装 OpenCV 库和编译工具链,并设置好环境变量以便于调用 OpenCV 功能[^1]。
#### 2. 双目相机标定的主要步骤
以下是基于 OpenCV 的双目相机标定主要步骤:
- **采集标定数据**
需要拍摄多组棋盘格图案的图像(通常建议至少 10 组),这些图像应覆盖不同的角度和位置,以提高标定精度[^3]。
- **角点检测**
利用 `cv::findChessboardCorners` 函数自动识别每幅图像中的棋盘格角点坐标。随后可使用 `cv::drawChessboardCorners` 将检测到的角点可视化,便于验证检测准确性[^2]。
- **单目标定**
对左、右两台相机分别执行单独的标定操作,获得各自的内参矩阵 (`cameraMatrix`) 和畸变系数 (`distCoeffs`)。具体函数为 `cv::calibrateCamera`。
- **双目标定**
调用 `cv::stereoCalibrate` 进行联合标定,输入左右相机各自内参及对应世界坐标系下的三维点与像素平面二维点映射关系,最终求解出旋转矩阵 R 和平移向量 T 描述两者之间的相对位姿。
- **立体校正**
执行 `cv::stereoRectify` 来计算重投影变换矩阵 Q 并生成用于后续处理的标准矩形化地图 (remapping maps),使得经过矫正后的视差图更加精确可靠。
- **保存结果**
把上述过程中产生的各项参数存储下来供后期应用加载使用即可。
下面是完整的代码示例展示如何利用 C++ 结合 OpenCV 完成以上各阶段的任务:
```cpp
#include <opencv2/opencv.hpp>
#include <vector>
int main() {
std::string imageDirectory = "./images/";
int boardSizeWidth = 9;
int boardSizeHeight = 6;
cv::Size imageSize, patternSize(boardSizeWidth, boardSizeHeight);
float squareSize = 1.0f; // 单位长度
bool useIntrinsicGuess = true;
std::vector<std::vector<cv::Point3f>> objectPointsPerView;
std::vector<std::vector<cv::Point2f>> leftImagePointsPerView, rightImagePointsPerView;
// 构造对象空间点集
for(int i=0;i<imageCount;i++){}
std::vector<cv::Point3f> objPts;
for( int y = 0; y < boardSizeHeight; ++y ){
for( int x = 0; x < boardSizeWidth; ++x )
objPts.push_back(cv::Point3f(x*squareSize,y*squareSize,0));
}
objectPointsPerView.push_back(objPts);
}
// 加载图片并查找角点...
double rmsLeft = calibrateCamera(objectPointsPerView,leftImagePointsPerView,imageSize,cameraMatrixL,distCoeffsL,rvecs,tvecs,flags|useIntrinsicGuess);
double rmsRight = calibrateCamera(objectPointsPerView,rightImagePointsPerView,imageSize,cameraMatrixR,distCoeffsR,rvecs,tvecs,flags|useIntrinsicGuess);
flags |= CV_CALIB_FIX_INTRINSIC;
double rmsStereo = stereoCalibrate(objectPointsPerView,
leftImagePointsPerView,
rightImagePointsPerView,
cameraMatrixL,distCoeffsL,
cameraMatrixR,distCoeffsR,
imageSize,R,T,E,F);
stereoRectify(cameraMatrixL,distCoeffsL,cameraMatrixR,distCoeffsR,
imageSize,R,T,Q,CV_CALIB_ZERO_DISPARITY,alpha,newImgSize,R1,P1,R2,P2);
return 0;
}
```
阅读全文
相关推荐


















