打开CV和三维坐标中的立体校准
Stereo Calibration in Open CV and 3D Coordinates
我是OpenCV
的初学者,目前正在进行一个项目,需要将像素精确映射到厘米/毫米/任何现实世界中的单位。
我在OpenCV
中进行了立体声校准,然后进行了立体声校正。因此,我得到了内在参数和外在参数。
在执行立体校准时,我没有在哪里输入棋盘图案的确切正方形大小(25毫米乘25毫米(。我只输入了水平和垂直内角的数量以及板的数量。那么,当我重新投影到3D时,这会有效果吗?如果是,如何在StereoCalibrate函数中包含正方形大小。
其次,从相机矩阵中得到的fx
和fy
的值都是513.86,而从EXIF数据中得到的值是3.7mm。那么,两者之间的确切关系是什么?
第三,使用reprojectImageTo3D
,得到了三维世界坐标。现在,这些坐标的确切单位是多少(厘米/毫米/英寸/等(?
基本上,我想获得从像素到现实世界单位的精确映射,经过大量的阅读和搜索,我一直无法做到这一点。请帮助我解决这个问题。
- 函数
StereoCalibrate
的第一个参数是您需要自己创建的校准图案的实际尺寸。例如,如果你有一个3毫米正方形的6x5棋盘网格,你需要创建一个矩阵,其中包含棋盘e.x.[(0,0,0)(0,3,0)(0,6,0)...]
上参考系统中表示的每个角的位置,依此类推 - 焦距以像素尺寸表示。您只需检查像素的实际尺寸(通常以微米为单位(,然后将
fx
和fy
乘以它 - 单位取决于您创建校准模式的方式(第一个问题(。在我制作的例子中,棋盘有3毫米的正方形,所以网格中角的位置以毫米表示。这是你的结果的单位
我同意前两个问题的其他答案。但为了进一步澄清和详细说明,
1(
查看下面代码块中的参数"squareSize"。
这就是你给出正方形大小的地方。这样做的目的是,它计算棋盘上每个角落的位置,并将其推送到一个点向量中,称为objectPoints。这是可能的,因为棋盘有规则的图案。
矢量objectPoints然后成为StereoCalibrate函数的第一个参数。
此外,请记住,无论您为squareSize指定什么单位,您的校准结果(当然除了fx和fy(都将使用相同的单位。
for( j = 0; j < boardSize.height; j++ ){
for( k = 0; k < boardSize.width; k++ ){
objectPoints.push_back(Point3f(j*squareSize, k*squareSize, 0));
}
}
2(
你得到的fx和fy将以像素为单位。为了获得以毫米为单位的焦距,需要将其乘以比例因子。
fx、fy和实际焦距(单位:mm(之间的关系由相机传感器的大小决定。您应该能够在相机规格中找到此参数。
我上面提到的比例因子是相机传感器每毫米的像素数。
3(
你得到的三维世界坐标正是你提到的坐标。从系统中的某个点引用。它们是对象点的x、y和z坐标。坐标没有单位!
到目前为止,我可以回答两个第一个问题:
1: cv::stereoCalibrate中的第一个参数是目标点的矢量,您可以使用以下函数填充它:
void CalcBoardCornerPositions(cv::Size boardSize, double squareSize, std::vector<cv::Point3f>& corners) {
corners.clear();
for( int i = 0; i < boardSize.height; ++i )
for( int j = 0; j < boardSize.width; ++j )
corners.push_back(cv::Point3f(float( j*squareSize ), float( i*squareSize ), 0));
}
然后使用它:
std::vector<std::vector<cv::Point3f> > objectPoints(1);
CalcBoardCornerPositions(boardSize, squareSize, objectPoints[0]);
cv::stereoCalibrate(objectPoints, imagePointsA, imagePointsB, _cameraMatrixA, /// etc
2:相机矩阵fx和fy实际上分别是焦距乘以x和y方向上的像素密度。这意味着
fx=f*cx
fy=f*cy
其中cx=imageSize.width/sensorSize.width,cy=imageSize.height/sensorSize e.height。在现代相机中通常cx==cy。您可以在相机手册中找到相机传感器的尺寸。
- 如何将三维尺寸不固定的三维阵列展平为一维阵列
- 如何使用qt缩放三维网格
- 三维数组中的C/C++DWORD到BYTE和BYTE到DWORD的转换
- 使用vtkImageReslice重新切片三维原始图像
- 特征:创建一个具有函数的三维阵列
- 扩充矩阵的行缩减-三维样条曲线计算
- 使用pcl transformcloud将三维点平移并旋转到原点
- 用C++从三维矢量中删除元素
- 如何访问CGAL三维三角测量中的面
- 如何在Openscenegraph中从二维鼠标点击的屏幕坐标点计算三维点(世界坐标)
- std::将三维数组复制到三维向量中
- 显示结构的三维数组
- 如何将X 2维数组连接到一个三维阵列中
- 使用unique_ptr来管理三维数组
- 如何访问三维矩阵元素
- 无法访问三维数组中的特定位置
- 如何将 HDC 位图快速复制到三维阵列?
- 内存相关崩溃:Cocos2d游戏中的三维数组
- 如何使用opencv和c++实现三维sift算法
- 打开CV和三维坐标中的立体校准