确定智能手机相机的视angular

我正在尝试确定Droid Incredible智能手机相机的视野的大小。 我需要知道我正在开发的应用程序的这个值。 有谁知道我可以找出/计算它编程?

  • Android getOrientation倾斜手机时,方位angular会受到污染
  • 将方向存储到一个数组 - 并进行比较
  • 如何将分数格式化的string转换为Java中的Decimal或Float?
  • MathML和Java
  • 除非有一些API调用(我不是Android程序员,我不知道),我只是从已知的距离拍摄一个统治者的照片,看看有多less统治者显示在图片中,然后使用三angular来find这样的angular度:

    在这里输入图像说明

    现在你有了图中的两个距离l和d。 用一些简单的测angular仪就可以得到:

    tan(α/ 2)=(1/2)/ d,

    于是

    α= 2 * atan(1 / 2d)

    所以用这个公式,你可以计算你的相机的水平视野。 当然,测量垂直fov的方式完全一样,只不过需要在垂直位置查看对象。

    然后你可以在你的程序中把它作为一个常量进行硬编码。 (一个命名的常量,当然,所以它很容易改变:-p)

    Camera.Parameters getHorizo​​ntalViewAngle()和getVerticalViewAngle()函数为您提供基本视angular。 我说“基地”,因为这些只适用于相机本身在一个unzoomed状态,并且这些函数返回的值不会改变即使视angular本身。

     Camera.Parameters p = camera.getParameters(); double thetaV = Math.toRadians(p.getVerticalViewAngle()); double thetaH = Math.toRadians(p.getHorizontalViewAngle()); 

    有两件事导致您的“有效”视angular改变:缩放,并使用与相机纵横比不匹配的预览纵横比。

    基础math

    视野的三angular(Θ)相当简单:

    tan(Θ/ 2)= x / 2z

    x = 2z tan(Θ/ 2)

    x是在距离z处可见的线性距离; 也就是说,如果你在距离z = 1米的地方举起一把尺子,你就能看到那个尺子的x米。

    比如在我的相机上,水平视场angular为52.68°,垂直视场angular为40.74°。 将它们转换为弧度并将它们插入公式中,任意z值为100m,得到x值为99.0m(水平)和74.2m(垂直)。 这是一个4:3的长宽比。

    放大

    将这个math应用于缩放级别只是稍微困难一些。 现在,x保持不变,z是以已知比例变化的; 我们必须确定Θ。

    tan(Θ/ 2)= x /(2z)

    tan(Θ'/ 2)= x /(2z')

    Θ'= 2 atan((z / z')tan(Θ/ 2))

    其中z是基本缩放级别(100),z'是当前缩放级别(来自CameraParameters.getZoomRatios),Θ是基本水平/垂直视野,而Θ'是有效视野。 添加degree->弧度转换使得这个过于冗长。

     private static double zoomAngle(double degrees, int zoom) { double theta = Math.toRadians(degrees); return 2d * Math.atan(100d * Math.tan(theta / 2d) / zoom); } Camera.Parameters p = camera.getParameters(); int zoom = p.getZoomRatios().get(p.getZoom()).intValue(); double thetaH = zoomAngle(p.getHorizontalViewAngle(), zoom); double thetaV = zoomAngle(p.getVerticalViewAngle(), zoom); 

    长宽比

    虽然典型的相机是4:3的宽高比,但预览也可以以5:3和16:9的比率提供,这似乎是通过实际扩展水平视场来实现的。 这似乎是无证的,因此不可靠,但通过假设它是如何工作的,我们可以计算视场。

    math与缩放计算相似; 然而,在这种情况下,z保持不变,这是变化的x。 通过假设垂直视angular保持不变而水平视angular随高宽比变化而变化,则可以计算新的有效水平视angular。

    tan(Θ/ 2)= v /(2z)

    tan(Θ'/ 2)= h /(2z)

    2z = v / tan(Θ/ 2)

    Θ'= 2 atan((h / v)tan(Θ/ 2))

    这里的h / v是宽高比,Θ是基本的垂直视场,而Θ'是有效的水平视场。

     Camera.Parameters p = camera.getParameters(); int zoom = p.getZoomRatios().get(p.getZoom()).intValue(); Camera.Size sz = p.getPreviewSize(); double aspect = (double) sz.width / (double) sz.height; double thetaV = Math.toRadians(p.getVerticalViewAngle()); double thetaH = 2d * Math.atan(aspect * Math.tan(thetaV / 2)); thetaV = 2d * Math.atan(100d * Math.tan(thetaV / 2d) / zoom); thetaH = 2d * Math.atan(100d * Math.tan(thetaH / 2d) / zoom); 

    正如我上面所说,由于这似乎是无证的,这只是一个猜测,它将适用于所有设备; 它应该被认为是一个黑客。 正确的解决scheme将分离出一组新的函数getCurrentHorizo​​ntalViewAngle和getCurrentVerticalViewAngle。

    我也有一个令人难以置信的Droid。 Android 2.2引入了你正在寻找的function。 在我的代码中,我有:

     public double getHVA() { return camera.getParameters().getHorizontalViewAngle(); } public double getVVA() { return camera.getParameters().getVerticalViewAngle(); } 

    但是,这些要求您打开相机。 我有兴趣知道是否有一个“最佳实践”的方式,不必每次打开摄像头获得这些价值观。

    @David Zaslavsky – 怎么样? 什么是缩放级别之间的math关系? 我无法在任何地方find它(我在这个问题中问: Android摄像头缩放数字在math上代表什么? )