opencv棋盘格RT矩阵
时间: 2025-01-06 07:38:02 浏览: 6
### 使用OpenCV进行棋盘格相机标定并计算RT矩阵
在计算机视觉领域,相机标定是一个重要的过程,用于确定相机内部参数和外部参数。其中,旋转和平移矩阵(即RT矩阵)是描述相机姿态的关键部分。
#### 获取角点坐标
为了实现精确的相机标定,在图像中标记已知几何形状(如棋盘格)上的特征点至关重要。通过检测这些模式中的角点位置来获得世界坐标系下的三维点及其对应的二维投影点[^2]。
```cpp
std::vector<std::vector<cv::Point3f>> objectPoints;
std::vector<std::vector<cv::Point2f>> imagePoints;
// Prepare object points (0,0,0), (1,0,0), ..., depending on the number of internal corners per a chessboard row/column.
for(int i = 0; i<imageCount ;i++)
{
std::vector<cv::Point3f> objp;
for( int j = 0; j < boardSize.height; ++j )
for( int k = 0; k < boardSize.width; ++k )
objp.push_back(cv::Point3f(j*distanceBetweenSquares,k*distanceBetweenSquares,0));
objectPoints.push_back(objp);
}
bool found;
cv::Mat frame;
for(int i=0;i<imageCount;++i){
frame = cv::imread(imagePaths[i]);
found=cv::findChessboardCorners(frame,chessBoardDimensions,imagePoints[i],cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE );
}
```
#### 执行相机标定
利用上述收集到的对象空间点与图像平面内的对应关系执行实际的校准操作:
```cpp
double rms = calibrateCamera(objectPoints,
imagePoints,
imageSize,
cameraMatrix,
distCoeffs,
rvecs,
tvecs,
flags,
criteria);
cout << "Re-projection error reported by calibrateCamera: "<<rms<<endl;
```
此函数返回重投影误差以及估计出来的摄像机内参`cameraMatrix`、失真系数`distCoeffs`还有每张图片对应的旋转向量形式表示的姿态信息(`rvecs`)和平移向量(`tvecs`)。注意这里的R(t)就是所说的外参矩阵。
对于每一个视图而言,可以将得到的结果转换成标准的旋转矩阵形式以便后续处理:
```cpp
void Rodrigues(const Mat& src, Mat& dst)
{
CV_Assert(src.total() == 3 && src.channels() == 1); // Input should be either 3x1 or 1x3 vector
double theta = norm(src,L2);
if(theta != 0.)
{
Vec3d w = src/theta;
Mat W = (Mat_<double>(3,3) <<
0,-w[2],w[1],
w[2],0,-w[0],
-w[1],w[0],0);
expm(W * theta,dst);
}
else
dst.setTo(Mat::eye(3,3,CV_64F));
}
// Convert rotation vectors to rotation matrices using Rodrigues formula
std::vector<cv::Mat> Rots(rvecs.size());
for(size_t i=0;i<Rots.size();++i)
Rodrigues(rvecs[i],Rots[i]);
// Combine with translation vectors into single transformation matrix [R|T]
std::vector<cv::Mat> ExtrinsicTransformations(Rots.size(),cv::Mat::zeros(3,4,CV_64FC1));
for(size_t i=0;i<ExtrinsicTransformations.size();++i)
{
hconcat(Rots[i],tvecs[i].reshape(1,3).t(),ExtrinsicTransformations[i]);
}
```
这段代码展示了如何把从`calibrateCamera()`获取的数据进一步加工成为完整的变换矩阵\[R|T\],这正是所需的RT矩阵。
阅读全文