24

DroidIncredibleスマートフォンのカメラの視野の大きさを調べようとしています。開発中のアプリケーションのこの値を知る必要があります。プログラムでそれを見つけて計算する方法を誰かが知っていますか?

4

3 に答える 3

63

Camera.Parameters getHorizo​​ntalViewAngle()およびgetVerticalViewAngle()関数は、ベースビュー角度を提供します。これらはズームされていない状態のカメラ自体にのみ適用され、これらの関数によって返される値は、画角自体が変化しても変化しないため、「ベース」と言います。

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

「有効な」視野角が変化する原因は2つあります。ズームと、カメラのアスペクト比と一致しないプレビューアスペクト比の使用です。

基本的な数学

視野(Θ)の三角法はかなり単純です。

tan(Θ/ 2)= x / 2z

x = 2ztan(Θ/ 2)

xは、距離zで表示可能な直線距離です。つまり、距離z = 1メートルで定規を持ち上げた場合、その定規のxメートルを見ることができます。

たとえば私のカメラでは、水平方向の視野は52.68°ですが、垂直方向の視野は40.74°です。これらをラジアンに変換し、100mの任意のz値を使用して数式にプラグインすると、99.0m(水平)と74.2m(垂直)のx値が得られます。これは4:3のアスペクト比です。

ズーム

この計算をズームレベルに適用するのは少し難しいだけです。ここで、xは一定のままであり、既知の比率で変化するのはzです。Θを決定する必要があります。

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

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

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

ここで、zは基本ズームレベル(100)、z'は現在のズームレベル(CameraParameters.getZoomRatiosから)、Θは基本水平/垂直視野、Θ'は有効視野です。度->ラジアン変換を追加すると、これはかなり冗長になります。

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の比率でも利用できる場合があります。これは、実際に水平方向の視野を拡大することで実現されるようです。これは文書化されていないため、信頼性が低いように見えますが、それがどのように機能するかを想定することで、視野を計算できます。

計算はズーム計算に似ています。ただし、この場合、zは一定のままであり、変化するのはxです。アスペクト比の変化に応じて水平画角を変化させながら垂直画角を変更しないと仮定することで、新しい有効水平画角を計算することができます。

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);

上で述べたように、これは文書化されていないように見えるため、すべてのデバイスに適用されると推測されます。それはハックと見なされるべきです。正しい解決策は、関数getCurrentHorizo​​ntalViewAngleとgetCurrentVerticalViewAngleの新しいセットを分割することです。

于 2012-08-25T02:52:54.397 に答える
16

そのためのAPI呼び出しがない限り(私はAndroidプログラマーではないので、わかりません)、既知の距離から定規の写真を撮って、写真に表示されている定規の量を確認します。次に、三角法を使用して次のよう角度を見つけます。

ここに画像の説明を入力してください

これで、図から2つの距離lとdが得られました。いくつかの簡単なゴニオメトリーで、次のことができます。

tan(α/ 2)=(l / 2)/ d、

したがって、

α=2* atan(l / 2d)

したがって、この式を使用すると、カメラの水平視野を計算できます。もちろん、垂直視野の測定は、オブジェクトを垂直位置で表示する必要があることを除いて、まったく同じ方法で行われます。

次に、プログラムの定数としてハードコーディングできます。(もちろん、名前付き定数なので、簡単に変更できます:-p)

于 2010-07-16T03:47:01.407 に答える
9

私もDroidIncredibleを持っています。Android 2.2は、あなたが探している機能を導入しました。私のコードでは、次のようになっています。

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

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

ただし、これらにはカメラを開いておく必要があります。これらの値を取得するために毎回カメラを開く必要がない「ベストプラクティス」の方法があるかどうかを知りたいと思います。

@David Zaslavsky-どうやって?ズームレベル間の数学的関係は何ですか?どこにも見つかりません(この質問で尋ねました:Androidカメラのズーム数は数学的に何を表していますか?

于 2010-09-10T03:57:24.997 に答える