在 emgu CV 中进行相机校准后如何访问旋转和平移矢量?
How do I access the rotation and translation vectors after camera calibration in emgu CV?
相机标定的目标是找到内部和外部参数:
- 内在的是描述相机本身的那些(焦点
长度、失真等)我得到了这些值,没问题。
- 外部参数基本上是相机的位置。当我尝试访问那些时,我得到一个
AccessViolationException
.
执行此类校准的一种方法是
- 拍摄具有已知角的校准目标的图像
- 找到图像中的那些角
- 从3D点和2D点的对应关系中,找出一个变换成另一个的矩阵
- 该矩阵由内部参数和外部参数组成。
对 calibration function 的调用如下所示:
Mat[] rotationVectors = new Mat[1];
Mat[] translationVectors = new Mat[1];
double error = CvInvoke.CalibrateCamera(realCorners,
detectedCorners,
calibrationImages[0].Image.Size,
cameraMatrix,
distortionCoefficients,
0,
new MCvTermCriteria(30, 0.1),
out rotationVectors,
out translationVectors);
Console.WriteLine(rotationVectors[0].Size); // AccessViolationException
- 我这里只用了一张图片,但是当我用更多的图片时也有同样的问题(30) 无论如何,不同的校准图像会对
translation
-/rotationVector
产生不同的结果,这让我怀疑只使用 1 张图像是个问题。
- 点的检测有效并将它们绘制到原始图像中给出了合理的结果。
cameraMatrix
和 distortionCoefficients
都可以访问并包含值。 (我试着只 post 代码的相关部分)
- 我使用 emgu 版本 3.0.0.2157
为什么我在 rotationVectors
和 translationVectors
上得到 AccessViolationException
?
我下了断点,发现内部Data
属性是null
。查看 VS 调试器的屏幕截图:
这就是为什么我无法访问它的原因。但是为什么是null
呢?
这是因为 EmguCV 中的错误。您正在呼叫
public static double CalibrateCamera(
MCvPoint3D32f[][] objectPoints,
PointF[][] imagePoints,
Size imageSize,
IInputOutputArray cameraMatrix,
IInputOutputArray distortionCoeffs,
CvEnum.CalibType calibrationType,
MCvTermCriteria termCriteria,
out Mat[] rotationVectors,
out Mat[] translationVectors)
在此方法中调用了
public static double CalibrateCamera(
IInputArray objectPoints,
IInputArray imagePoints,
Size imageSize,
IInputOutputArray cameraMatrix,
IInputOutputArray distortionCoeffs,
IOutputArray rotationVectors,
IOutputArray translationVectors,
CvEnum.CalibType flags,
MCvTermCriteria termCriteria)
IOutputArray rotationVectors
应复制到 Mat[] rotationVectors
。在 translationVectors 的情况下也是如此。问题出在 this 循环中。
有
for (int i = 0; i < imageCount; i++)
{
rotationVectors[i] = new Mat();
using (Mat matR = rotationVectors[i]) // <- bug
matR.CopyTo(rotationVectors[i]);
translationVectors[i] = new Mat();
using (Mat matT = translationVectors[i]) // <- bug
matT.CopyTo(translationVectors[i]);
}
而且应该有
for (int i = 0; i < imageCount; i++)
{
rotationVectors[i] = new Mat();
using (Mat matR = rVecs[i])
matR.CopyTo(rotationVectors[i]);
translationVectors[i] = new Mat();
using (Mat matT = tVecs[i])
matT.CopyTo(translationVectors[i]);
}
最后要获得旋转和平移值,您可以使用 DataPointer
复制数据
var rotation = new Matrix<float>(rotationVectors[0].Rows, rotationVectors[0].Cols, rotationVectors[0].DataPointer);
相机标定的目标是找到内部和外部参数:
- 内在的是描述相机本身的那些(焦点 长度、失真等)我得到了这些值,没问题。
- 外部参数基本上是相机的位置。当我尝试访问那些时,我得到一个
AccessViolationException
.
执行此类校准的一种方法是
- 拍摄具有已知角的校准目标的图像
- 找到图像中的那些角
- 从3D点和2D点的对应关系中,找出一个变换成另一个的矩阵
- 该矩阵由内部参数和外部参数组成。
对 calibration function 的调用如下所示:
Mat[] rotationVectors = new Mat[1];
Mat[] translationVectors = new Mat[1];
double error = CvInvoke.CalibrateCamera(realCorners,
detectedCorners,
calibrationImages[0].Image.Size,
cameraMatrix,
distortionCoefficients,
0,
new MCvTermCriteria(30, 0.1),
out rotationVectors,
out translationVectors);
Console.WriteLine(rotationVectors[0].Size); // AccessViolationException
- 我这里只用了一张图片,但是当我用更多的图片时也有同样的问题(30) 无论如何,不同的校准图像会对
translation
-/rotationVector
产生不同的结果,这让我怀疑只使用 1 张图像是个问题。 - 点的检测有效并将它们绘制到原始图像中给出了合理的结果。
cameraMatrix
和distortionCoefficients
都可以访问并包含值。 (我试着只 post 代码的相关部分)- 我使用 emgu 版本 3.0.0.2157
为什么我在 rotationVectors
和 translationVectors
上得到 AccessViolationException
?
我下了断点,发现内部Data
属性是null
。查看 VS 调试器的屏幕截图:
这就是为什么我无法访问它的原因。但是为什么是null
呢?
这是因为 EmguCV 中的错误。您正在呼叫
public static double CalibrateCamera(
MCvPoint3D32f[][] objectPoints,
PointF[][] imagePoints,
Size imageSize,
IInputOutputArray cameraMatrix,
IInputOutputArray distortionCoeffs,
CvEnum.CalibType calibrationType,
MCvTermCriteria termCriteria,
out Mat[] rotationVectors,
out Mat[] translationVectors)
在此方法中调用了
public static double CalibrateCamera(
IInputArray objectPoints,
IInputArray imagePoints,
Size imageSize,
IInputOutputArray cameraMatrix,
IInputOutputArray distortionCoeffs,
IOutputArray rotationVectors,
IOutputArray translationVectors,
CvEnum.CalibType flags,
MCvTermCriteria termCriteria)
IOutputArray rotationVectors
应复制到 Mat[] rotationVectors
。在 translationVectors 的情况下也是如此。问题出在 this 循环中。
有
for (int i = 0; i < imageCount; i++)
{
rotationVectors[i] = new Mat();
using (Mat matR = rotationVectors[i]) // <- bug
matR.CopyTo(rotationVectors[i]);
translationVectors[i] = new Mat();
using (Mat matT = translationVectors[i]) // <- bug
matT.CopyTo(translationVectors[i]);
}
而且应该有
for (int i = 0; i < imageCount; i++)
{
rotationVectors[i] = new Mat();
using (Mat matR = rVecs[i])
matR.CopyTo(rotationVectors[i]);
translationVectors[i] = new Mat();
using (Mat matT = tVecs[i])
matT.CopyTo(translationVectors[i]);
}
最后要获得旋转和平移值,您可以使用 DataPointer
var rotation = new Matrix<float>(rotationVectors[0].Rows, rotationVectors[0].Cols, rotationVectors[0].DataPointer);