0

拡張現実のiPhone アプリを開発しています。

基本的にすべきことは、カメラで見たときに地理的な場所に割り当てられた写真を表示することです。そのような各画像は、その地理的位置と見出し (その平面と北方向軸の間の角度として理解される) を持つビルボードとして理解される場合があります。

目標は、これらの看板を多かれ少なかれ物理的なオブジェクトのように表示することです。近くにいる場合は大きく、遠くにある場合は小さくする必要があります。真正面に立たなくても、適切な視点で表示する必要があります。

私はその目標を多かれ少なかれ達成したと思います。iPhone から写真までの最初の方向を測定することで、カメラから見た写真の回転角度を決定できます (適切な視点で見るため)。

ただし、電話からの距離に基づいてスケーリングする場合は、アプローチを台無しにしたと思います。最大視界距離は、たとえば 200 m であると仮定しました。次に、電話から 100 m 離れたビルボードが元のサイズの 50% で表示されます。それでおしまい。最大距離に基づく線形スケーリング。

このアプローチで見逃したのは、ビルボード (物理的なオブジェクトとして理解される) のサイズです。画面に表示される方法は、ピクセル単位のサイズのみに依存します。これは、ディスプレイの解像度が、それらをどのように知覚するかを決定する要因であることを意味します。したがって、画面サイズが同じで解像度が異なる 2 台の電話を入手した場合、同じ写真でも両方でサイズが異なると思います。私は正しいですか?

最後に、私の質問は、AR ビューで見栄えを良くするために画像をスケーリングする方法です。

いくつかのカメラ パラメータを考慮する必要があると思います。10x10 cm のオブジェクトがカメラのすぐ前にある場合、画面全体を覆うことがあります。しかし、数メートル離すと、些細なことになります。では、スケーリングにどのようにアプローチするのでしょうか? 仮想ビルボードに物理的な寸法を割り当てることにした場合、カメラからの距離に基づいてそれらをスケーリングする方法は?

各写真に物理的な寸法をメートル単位で割り当て (ピクセル単位のサイズに関係なく)、寸法とカメラに依存する倍率に基づいて表示する必要があるのは正しいですか?

それについて私を助けてもらえますか?どんな手がかりも役に立ちます。ありがとうございました!

4

1 に答える 1

2

問題を解決できたと思います。他の人に役立つかもしれない場合、私がそれをどのように行ったかを説明しましょう。このアプローチが間違っていると思われる場合は、フィードバックやその他の手がかりをいただければ幸いです。

仮想ビルボードに物理的な寸法をメートル単位で割り当てることにしました。 この議論は、iPhone 4 カメラのパラメータ (焦点距離と CCD センサーの寸法) を見つけるのに役立ちました。さらに、これらの値は、AR アプリの適切な FOV を計算するのにも役立ちました (カメラの画角の計算を参照)。

この Web サイトは、CCD センサーで生成された物理オブジェクトの画像のサイズをミリメートル単位で計算するのに役立ちました。したがって、ビルボードの幅と高さがメートル単位であり、カメラからの距離とカメラの焦点距離がわかっている場合、センサーでサイズを計算できます。

(焦点距離 * オブジェクトの寸法) / レンズからオブジェクトまでの距離 = イメージ サイズ (センサー上)

double CalculatePhysicalObjectImageDimensionOnCCD(double cameraFocalLength_mm, double physicalObjectDimension_m, double distanceFromPhysicalObject_m)
{
    double physicalObjectDimension_mm = physicalObjectDimension_m * 1000;
    double distanceFromPhysicalObject_mm = distanceFromPhysicalObject_m * 1000;
    return (cameraFocalLength_mm * physicalObjectDimension_mm) / distanceFromPhysicalObject_mm;
}

私はその件についてほとんど知識がないので、私が取ったアプローチが正しいかどうかはわかりませんが、CCD センサーの寸法と比較して iPhone の画面がどれだけ大きいかを計算することにしました。したがって、単純な数学的操作によって、センサーと画面のサイズの比率を取得します。センサーと画面の幅と高さの比率が異なるように見えるため、私は一種の不自然な方法で比率を計算しました。

double GetCCDToScreenSizeRatio(double sensorWidth, double sensorHeight, double screenWidth, double screenHeight)
{
    return sqrt(screenWidth * screenHeight) / sqrt(sensorWidth * sensorHeight);
}

次に、取得した比率を乗数として扱うことができます。まず、センサー上の仮想ビルボードの寸法を計算し、比率を掛けます。このようにして、ビルボードの実際のサイズをピクセル単位で取得します。それでおしまい。したがって、ビルボードの幅とそこからの距離を指定するだけで以下の関数を呼び出すと、画面に表示されるビルボードの幅がピクセル単位で返されます。両方の寸法を取得するために、ビルボードの高さも同じです。

const double CCD_DIM_LONGER_IPHONE4 = 4.592; //mm
const double CCD_DIM_SHORTER_IPHONE4 = 3.450; //mm
const double FOCAL_LENGTH_IPHONE4 = 4.28; //mm

double CalculatePhysicalObjectImageDimensionOnScreen_iPhone4(double physicalObjectDimension_m, double distanceFromPhysicalObject_m)
{
    double screenWidth = [UIScreen mainScreen].bounds.size.width;
    double screenHeight = [UIScreen mainScreen].bounds.size.height;

    return CalculatePhysicalObjectImageDimensionOnScreen(FOCAL_LENGTH_IPHONE4, physicalObjectDimension_m, distanceFromPhysicalObject_m, CCD_DIM_LONGER_IPHONE4, CCD_DIM_SHORTER_IPHONE4, screenWidth, screenHeight);
}

double CalculatePhysicalObjectImageDimensionOnScreen(double cameraFocalLength_mm, double physicalObjectDimension_m, double distanceFromPhysicalObject_m, double ccdSensorWidth, double ccdSensorHeight, double screenWidth, double screenHeight)
{
    double ccdToScreenSizeRatio = GetCCDToScreenSizeRatio(ccdSensorWidth, ccdSensorHeight, screenWidth, screenHeight);
    double dimensionOnCcd = CalculatePhysicalObjectImageDimensionOnCCD(cameraFocalLength_mm, physicalObjectDimension_m, distanceFromPhysicalObject_m);

    return dimensionOnCcd * ccdToScreenSizeRatio;
}

私の以前のばかげた線形スケーリングのアプローチと比較して、それは完璧に機能しているようです。ちなみに、AR ビューに仮想オブジェクトを登録するときは、カメラの FOV を知ることが非常に重要であることに気付きました。CCDセンサーの寸法と焦点距離に基づいてFOVを計算する方法は次のとおりです

これらの値をどこでも見つけるのは非常に困難です。なぜプログラムでアクセスできないのか疑問に思います (少なくとも私の調査では、そうではないことがわかりました)。ハードコーディングされた値を準備し、アプリが実行されているデバイスのモデルを確認して、上記のすべての計算を行うときにどの値を選択するかを決定する必要があるようです:-/.

于 2012-08-11T21:12:36.683 に答える