确定智能手机摄像头的视角
我正在尝试确定 Droid Incredible 智能手机摄像头的视野大小。我需要知道我正在开发的应用程序的这个值。有谁知道我如何以编程方式找到/计算它?
I'm trying to determine the degree size of the field-of-view of a Droid Incredible smartphone's camera. I need to know this value for an application that I'm developing. Does anyone know how I can find out/calculate it programmatically?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Camera.Parameters getHorizontalViewAngle() 和 getVerticalViewAngle() 函数为您提供基本视角。我说“基础”,因为这些仅适用于处于未缩放状态的相机本身,并且即使视角本身发生变化,这些函数返回的值也不会改变。
有两件事会导致“有效”视角发生变化:缩放以及使用与相机宽高比不匹配的预览宽高比。
基础数学
视场 (θ) 的三角学相当简单:
x 是在距离 z 处可见的线性距离;即,如果您在距离 z=1 米处举起一把尺子,您将能够看到该尺子的 x 米。
例如,在我的相机上,水平视场为 52.68°,而垂直视场为 40.74°。将它们转换为弧度并将其代入公式中,其中 z 值为任意 100m,您将得到 x 值 99.0m(水平)和 74.2m(垂直)。这是 4:3 的长宽比。
缩放 将
这个数学应用到缩放级别只是稍微困难一些。现在,x 保持不变,z 以已知的比率变化;我们必须确定 θ。
其中 z 是底数缩放级别 (100),z' 是当前缩放级别(来自 CameraParameters.getZoomRatios),θ 是基本水平/垂直视场,θ' 是有效视场。添加度数->弧度转换会使这变得相当冗长。
纵横比
虽然典型相机的纵横比为 4:3,但预览也可以采用 5:3 和 16:9 的比例,这似乎是通过实际扩展水平视野来实现的。这似乎没有记录,因此不可靠,但通过假设它是如何工作的,我们可以计算视野。
数学计算与缩放计算类似;然而,在这种情况下,z 保持不变,而 x 发生变化。通过假设垂直视角保持不变,而水平视角随着纵横比的变化而变化,可以计算出新的有效水平视角。
这里 h/v 是纵横比,θ 是基本垂直视场,而 θ' 是有效水平视场。
正如我上面所说,由于这似乎没有记录,因此只是猜测它将适用于所有设备;它应该被视为黑客。正确的解决方案是分离出一组新的函数 getCurrentHorizontalViewAngle 和 getCurrentVerticalViewAngle。
The Camera.Parameters getHorizontalViewAngle() and getVerticalViewAngle() functions provide you with the base view angles. I say "base", because these apply only to the Camera itself in an unzoomed state, and the values returned by these functions do not change even when the view angle itself does.
Two things cause your "effective" view angle to change: zoom, and using a preview aspect ratio that does not match the camera aspect ratio.
Basic Math
The trigonometry of field-of-view (Θ) is fairly simple:
x is the linear distance viewable at distance z; i.e., if you held up a ruler at distance z=1 meter, you would be able to see x meters of that ruler.
For instance on my camera, horizontal field of view is 52.68° while vertical field of view is 40.74°. Convert these to radians and plug them into the formula with an arbitrary z value of 100m, and you get x values of 99.0m(horizontal) and 74.2m(vertical). This is a 4:3 aspect ratio.
Zoom
Applying this math to zoom levels is only slightly harder. Now, x remains constant and it is z that changes in a known ratio; we must determine Θ.
Where z is the base zoom level (100), z' is the current zoom level (from CameraParameters.getZoomRatios), Θ is the base horizontal/vertical field of view, and Θ' is the effective field of view. Adding on degree->radian conversions makes this rather verbose.
Aspect Ratio
While the typical camera is a 4:3 aspect ratio, the preview may also be available in 5:3 and 16:9 ratios and this seems to be accomplished by actually extending the horizontal field of view. This appears to be undocumented, hence unreliable, but by assuming that's how it works we can calculate the field of view.
The math is similar to the zoom calculations; however, in this case z remains constant and it is x that changes. By assuming that the vertical view angle remains unchanged while the horizontal view angle is varied as the aspect ratio changes, it's possible to calculate the new effective horizontal view angle.
Here h/v is the aspect ratio and Θ is the base vertical field of view, while Θ' is the effective horizontal field of view.
As I said above, since this appears to be undocumented, it is simply a guess that it will apply to all devices; it should be considered a hack. The correct solution would be splitting off a new set of functions getCurrentHorizontalViewAngle and getCurrentVerticalViewAngle.
除非有一些 API 调用(我不是 Android 程序员,我不知道),否则我只会从已知距离处拍摄一张尺子的图片,看看图片中显示了多少尺子,然后使用三角法找到角度,例如 this:
现在您已得到与图形的两个距离 l 和 d。通过一些简单的测角,可以得到:
tan(α/2) = (l/2)/d,
因此
α = 2*atan(l/2d)
因此,通过这个公式,您可以计算你的相机。当然,测量垂直视场的方式完全相同,只是您需要在垂直位置查看物体。
然后您可以将其硬编码为程序中的常量。 (当然,这是一个命名常量,因此很容易更改:-p)
Unless there's some API call for that (I'm not an Android programmer, I wouldn't know), I would just snap a picture of a ruler from a known distance away, see how much of the ruler is shown in the picture, then use trigonometry to find the angle like this:
now you have the two distances l and d from the figure. With some simple goniometry, one can obtain:
tan(α/2) = (l/2)/d,
hence
α = 2*atan(l/2d)
So with this formula you can calculate the horizontal field-of-view of your camera. Of course measuring the vertical f.o.v. goes exactly the same way except that you then need to view the object in its vertical position.
Then you can hard-code it as a constant in your program. (A named constant, of course, so it'd be easy to change :-p)
我也有一个 Droid Incredible。 Android 2.2 引入了您正在寻找的功能。在我的代码中,我有:
但是,这些要求您打开相机。我很想知道是否有一种“最佳实践”方法,不必每次都打开相机来获取这些值。
@David Zaslavsky - 怎么办?缩放级别之间的数学关系是什么?我在任何地方都找不到它(我在这个问题中问过: Android 相机变焦数字在数学上代表什么?)
I have a Droid Incredible as well. Android 2.2 introduced the functions you are looking for. In my code, I have:
However, these require that you have the camera open. I'd be interested to know if there is a "best practices" way to not have to open the camera each time to get those values.
@David Zaslavsky - how? What is the mathematical relationship between the zoom levels? I can't find it anywhere (I asked in this question: What do the Android camera zoom numbers mathematically represent?)