9

我正在使用 opencv 为 iPhone 开发一个应用程序。我必须使用方法solvePnPRansac:

http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html

对于这种方法,我需要提供一个相机矩阵:
__ __
| fx 0 cx |
| 0 年 |
|_0 0 1 _|

其中 cx 和 cy 代表图像的中心像素位置, fx 和 fy 代表焦距,但这就是所有文档所说的。我不确定为这些焦距提供什么。iPhone 5 的焦距为 4.1 毫米,但我认为这个值不能按原样使用。

我查了另一个网站:

http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

它显示了 opencv 如何创建相机矩阵。这里指出焦距是以像素为单位测量的。

我查了另一个网站:

http://www.velocityreviews.com/forums/t500283-focal-length-in-pixels.html

(大约一半)它说焦距可以使用以下公式从毫米单位转换为像素:fx = fy = focusMM * pixelDensity / 25.4;

我发现的另一个链接指出 fx = focusMM * width / (sensorSizeMM); fy = focusMM * 长度 / (sensorSizeMM);

我不确定这些方程以及如何正确创建这个矩阵。

任何有关如何创建准确的相机矩阵(尤其是 iPhone 5)的帮助、建议或链接将不胜感激,

艾萨克

ps 我认为 (fx/fy) 或 (fy/fx) 可能等于相机的纵横比,但这可能是完全错误的。

更新:

像素坐标到 3D 线(opencv)

使用此链接,我可以弄清楚他们希望如何格式化 fx 和 fy,因为他们使用它来缩放相对于它们与中心的距离的角度。因此,fx 和 fy 可能以像素/(单位长度)为单位,但我仍然不确定这个单位长度需要是多少,只要 x 和 y 相互缩放,它可以是任意的吗?

4

5 回答 5

10

您可以获得以像素为单位的焦距的初始(粗略)估计,以毫米为单位的焦距除以相机传感器(CCD、CMOS 等)的像素宽度。

您可以从相机手册中获得前者,或者从以全分辨率拍摄的图像的 EXIF 标题中读取它。找出后者有点复杂:如果您知道传感器的制造商和型号,您可以在互联网上查看传感器的规格表,或者您可以将其敏感区域的总宽度除以传感器上的像素数边。

在没有其他信息的情况下,通常可以安全地假设像素是正方形的(即 fx == fy),并且传感器与镜头的焦轴正交(即相机矩阵的第一行和第二列中的项是零)。此外,如果没有精心设计的校准装置和精心执行的校准程序,主点 (cx, cy) 的像素坐标通常很难准确估计(这是因为它们本质上与平行于图像的相机平移相混淆飞机)。因此最好将它们设置为等于图像的几何几何中心,除非您知道图像已被不对称裁剪。

因此,您最简单的相机模型只有一个未知参数,焦距 f = fx = fy。

忠告:在您的应用程序中通常更方便地携带水平(或垂直)视场角,而不是焦距(以像素为单位)。这是因为 FOV 对于图像缩放是不变的。

于 2013-02-05T13:29:21.167 回答
6

您在这里处理的“焦距”只是从世界中的物体到相机像素的比例因子,用于针孔相机模型(维基百科链接)。这就是为什么它的单位是像素/单位长度。对于给定的f ,在距离(垂直于相机)z处大小为L的对象将是f*L/z像素。

因此,您可以通过将已知大小的物体放置在相机已知距离处并测量其在图像中的大小来估计焦距。您也可以假设中心点是图像的中心。您绝对不应该忽略镜头失真(solvePnPRansac中的dist_coef参数)。

在实践中,获取相机矩阵和畸变系数的最佳方法是使用相机校准工具。您可以从此链接下载和使用 MRPT camera_calib 软件,这里还有视频教程。如果您使用 matlab,请使用Camera Calibration Toolbox

于 2013-02-08T10:05:46.420 回答
4

在这里,您有一张表格,其中包含 iPhone 4 和 5 的相机规格。计算公式为:

double f = 4.1;
double resX = (double)(sourceImage.cols);
double resY = (double)(sourceImage.rows);
double sensorSizeX = 4.89;
double sensorSizeY = 3.67;
double fx = f * resX / sensorSizeX;
double fy = f * resY / sensorSizeY;
double cx = resX/2.;
double cy = resY/2.;
于 2014-08-05T23:18:22.510 回答
1

试试这个:

func getCamMatrix()->(Float, Float, Float, Float)
{

    let format:AVCaptureDeviceFormat? = deviceInput?.device.activeFormat
    let fDesc:CMFormatDescriptionRef = format!.formatDescription

    let dim:CGSize = CMVideoFormatDescriptionGetPresentationDimensions(fDesc, true, true)

    // dim = dimensioni immagine finale
    let cx:Float = Float(dim.width) / 2.0;
    let cy:Float = Float(dim.height) / 2.0;

    let HFOV : Float = format!.videoFieldOfView
    let VFOV : Float = ((HFOV)/cx)*cy

    let fx:Float = abs(Float(dim.width) / (2 * tan(HFOV / 180 * Float(M_PI) / 2)));
    let fy:Float = abs(Float(dim.height) / (2 * tan(VFOV / 180 * Float(M_PI) / 2)));

    return (fx, fy, cx, cy)
}
于 2015-11-20T10:49:30.123 回答
1

老线程,现在的问题。

正如 Milo 和 Isaac 在 Milo 的回答之后提到的那样,似乎没有可用于 iPhone 5 的“通用”参数。

值得一提的是,这里是使用 MRPT 校准工具运行的结果,使用一部不错的旧 iPhone 5:

[CAMERA_PARAMS]
resolution=[3264 2448]
cx=1668.87585
cy=1226.19712
fx=3288.47697
fy=3078.59787
dist=[-7.416752e-02 1.562157e+00 1.236471e-03 1.237955e-03 -5.378571e+00]

Average err. of reprojection: 1.06726 pixels (OpenCV error=1.06726)

请注意,这dist意味着这里的失真。

我正在用这些参数对一个玩具项目进行实验——有点好。如果您确实在自己的项目中使用它们,请记住,它们可能不足以开始使用。最好的办法是使用您自己的数据遵循 Milo 的建议。MRPT 工具非常易于使用,并带有它们提供的棋盘格。希望这确实有助于入门!

于 2017-06-30T02:02:20.447 回答