問題を解決できたと思います。他の人に役立つかもしれない場合、私がそれをどのように行ったかを説明しましょう。このアプローチが間違っていると思われる場合は、フィードバックやその他の手がかりをいただければ幸いです。
仮想ビルボードに物理的な寸法をメートル単位で割り当てることにしました。 この議論は、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を計算する方法は次のとおりです。
これらの値をどこでも見つけるのは非常に困難です。なぜプログラムでアクセスできないのか疑問に思います (少なくとも私の調査では、そうではないことがわかりました)。ハードコーディングされた値を準備し、アプリが実行されているデバイスのモデルを確認して、上記のすべての計算を行うときにどの値を選択するかを決定する必要があるようです:-/.