GoPro相机的视野范围

7
我使用了Matlab的照相机校准工具箱来校准我的GoPro Hero 4 Black,并使用OpenCV的calibrationMatrixValues()计算其视场和焦距。然而,这些值与GoPro的规格不同。我得到的FOV是95.4/63.4,而不是118.2/69.5,焦距为2.8mm而不是17.2mm。显然有些问题。
我认为校准本身是正确的,因为图像去畸变似乎运作良好。
请问有人能给我提示我哪里出了错吗?我在下面发布我的代码。
谢谢。

代码

cameraMatrix = new Mat(3, 3, 6);
for (int i = 0; i < cameraMatrix.height(); i ++)
    for (int j = 0; j < cameraMatrix.width(); j ++) {
    cameraMatrix.put(i, j, 0);
}
cameraMatrix.put(0, 0, 582.18394);
cameraMatrix.put(0, 2, 663.50655);
cameraMatrix.put(1, 1, 582.52915);
cameraMatrix.put(1, 2, 378.74541);
cameraMatrix.put(2, 2, 1.);

org.opencv.core.Size size = new org.opencv.core.Size(1280, 720);
//output parameters
double [] fovx = new double[1];
double [] fovy = new double[1];
double [] focLen = new double[1];
double [] aspectRatio = new double[1];
Point ppov = new Point(0, 0);
org.opencv.calib3d.Calib3d.calibrationMatrixValues(cameraMatrix, size,
        6.17, 4.55, fovx, fovy, focLen, ppov, aspectRatio);


System.out.println("FoVx: " + fovx[0]);
System.out.println("FoVy: " + fovy[0]);
System.out.println("Focal length: " + focLen[0]);
System.out.println("Principal point of view; x: " + ppov.x + ", y: " + ppov.y);
System.out.println("Aspect ratio: " + aspectRatio[0]);

结果

FoVx: 95.41677635378488
FoVy: 63.43170132212425
Focal length: 2.8063085232812504
Principal point of view; x: 3.198308916796875, y: 2.3934605770833333
Aspect ratio: 1.0005929569269807

GoPro 规格

https://gopro.com/help/articles/Question_Answer/HERO4-Field-of-View-FOV-Information

编辑

Matlab 校准结果

Focal Length:          fc = [ 582.18394   582.52915 ] ± [ 0.77471   0.78080 ]
Principal point:       cc = [ 663.50655   378.74541 ] ± [ 1.40781   1.13965 ]
Skew:             alpha_c = [ -0.00028 ] ± [ 0.00056  ]   => angle of pixel axes = 90.01599 ± 0.03208 degrees
Distortion:            kc = [ -0.25722   0.09022   -0.00060   0.00009  -0.01662 ] ± [ 0.00228   0.00276   0.00020   0.00018  0.00098 ]
Pixel error:          err = [ 0.30001   0.28188 ]

用于校准的其中一张图像: 13.jpg

经过去畸变处理后的图像: _rect13.jpg

1个回答

6
您在OpenCV中输入了6.17毫米和4.55毫米的传感器尺寸,对应于长宽比1.36,而您的分辨率(1270x720)为1.76(近似16:9格式)。在进行MATLAB校准之前,您是否裁剪了图像?
这个Gopro页面得知像素大小约为1.55微米(这真是太小了!)。如果像素是正方形的(商业相机应该是这样的),那么您的输入就不一致了。计算出的传感器尺寸应该是:

[传感器宽度,传感器高度] = [1280, 720]*1.55*10^-3 = [1.97, 1.12]毫米

即使考虑最大视频分辨率3840 x 2160,我们得到[5.95, 3.35]mm,仍然与您的输入不同。
请查看有关等效焦距的解释,了解为什么相机的实际焦距不是17.2而是17.2*5.95/36约等于2.8毫米。在这种情况下,使用此处的公式计算视场角。您将确实发现93.5°/61.7°(接近您的输出,但仍与规格书中写的不同,因为可能存在由于广角引起的光学畸变)。
然而,我不明白的是,当输入的传感器尺寸错误时,返回的焦距值如何正确。您能否提供更多信息和/或发送一张图片? 问题更新后的编辑 对于这些相机,在工作分辨率1280x720下,图像被降采样但未被裁剪,因此上述关于传感器尺寸的说法不适用。要考虑的传感器尺寸确实是使用的那个(6.17 x 4.55),正如您在第一条评论中所解释的那样。
视场角受到校准矩阵输入(fx、fy、cx、cy)和分辨率的限制。您可以通过键入以下内容来检查它: 2*DEGRES(ATAN(1280/(2*582.18394)))(=95.416776...°)
这个FOV值比预期的要小,但从无畸变图像的外观来看,您的MATLAB畸变模型是正确的,校准也是正确的。由于广角引起的桶形畸变似乎被您应用的重映射方法很好地修正了。
然而,MATLAB工具箱使用的是针孔模型,该模型是线性的,不能考虑到类似镜头畸变之类的固有参数。我是从此页面推断出来的:https://fr.mathworks.com/help/vision/ug/camera-calibration.html。因此,我认为除非您找到一个更准确适配Gopro相机(也许是广角镜头模型),否则MATLAB校准将返回与“线性”无畸变图像对应的内部相机矩阵,而FOV确实会更小(在桶形畸变的情况下)。您将需要应用与校准相关的畸变系数以检索实际FOV值。我们可以看到,在校正后的图像中,FOV的边缘部分被拒绝超出边界。如果您完全扭曲了图像,则会发现一些无畸变的像素坐标超出[-1280/2 ; +1280/2](水平方向和垂直方向相同)。然后,将opencv.core.Size(1280, 720)替换为获得的最极端范围,您将希望恢复Gopro网站的值。总之,我认为如果您在图像中心进行测量,您可以依靠获得的焦距值,否则会有太多畸变而不适用。

非常感谢您的回答。我在这里找到了传感器的尺寸http://vfxcamdb.com/category/camera/gopro/。然而,如果我改变传感器的尺寸,calibrationMatrixValues(...)返回的视场并不会改变。我认为这个计算所需的所有数据都来自相机的校准矩阵。然而,变化的是焦距,当我将传感器的尺寸改变为1.97和1.12时,焦距等于约0.9mm。 - Milan Zelenka
我在上面的帖子中添加了一些更多的数据。 - Milan Zelenka
我没有找到有关传感器尺寸的信息,但当您拥有Gopro信息时确实应该依赖它们。那么我的错误是:我猜在像素之间有一些间距,并且在较低分辨率下的降采样实际上增加了像素间距。现在对于焦距的结果对我来说是有意义的。关于FOV差异,您是否尝试过使用适用于鱼眼镜头校准的畸变模型? - Matt-Mac-Muffin
好的。只是为了确保,您放置棋盘的材料是坚固的吗?我们可以做些什么来帮助我们理解,就是手动测量视野。只需将棋盘补丁放在距离相机已知的距离处(不要太靠近,以便焦点正常,并且在与相机轴(光轴)正交的平面上。它必须面向相机。最好使用比棋盘大的东西,这样板子就可以占据整个图像。然后,使用基本几何学计算您所看到的角度,或者将板子的图片尺寸和距离发送给我,我会为您计算。 - Matt-Mac-Muffin
1
哦,对了,这个材料是坚硬而平整的。 - Milan Zelenka
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接