为iPhone 5 solvepnp创建opencv相机矩阵

时间:2013-02-04 05:35:33

标签: iphone opencv computer-vision augmented-reality camera-calibration

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

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

对于这种方法,我需要提供一个相机矩阵:
 __ __
| fx 0 cx |
| 0 fy cy |
| _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 = focalMM * pixelDensity / 25.4;

另一个链接我发现fx = focalMM * width /(sensorSizeMM); fy = focalMM * length /(sensorSizeMM);

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

非常感谢有关如何创建精确相机矩阵(尤其是iPhone 5)的任何帮助,建议或链接,

艾萨克

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

更新:

Pixel coordinates to 3D line (opencv)

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

5 个答案:

答案 0 :(得分:10)

你可以得到像素的初始(粗略)估计焦距,以mm为单位将焦距除以相机传感器(CCD,CMOS等)的像素宽度。

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

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

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

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

答案 1 :(得分:6)

你在这里处理的“焦距”只是从世界上的物体到相机像素的比例因子,用于针孔相机模型(Wikipedia link)。这就是它的单位是像素/单位长度的原因。对于给定的 f ,距离(垂直于相机) z 的尺寸 L 的对象将 f * L / z 像素。

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

实际上,获取相机矩阵和失真系数的最佳方法是使用相机校准工具。您可以从this link下载并使用MRPT camera_calib软件,还有一个视频教程here。如果您使用matlab,请转到Camera Calibration Toolbox

答案 2 :(得分: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.;

答案 3 :(得分: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)
}

答案 4 :(得分: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工具非常易于使用,它们提供了棋盘格。希望这确实有助于入门!