web-dev-qa-db-ja.com

FOVを計算する方法は?

初期コンテキスト

拡張現実アプリケーションのロケーションベースを開発していて、視野[FOV]を取得する必要があります(方向が変わったときに値を更新するだけなので、呼び出すときにこの値を取得できるメソッドを探しています)

目標は、次のような現実に関連する「度定規」を作成することです。 Degree Ruler - AR App

私はすでにAVCaptureSessionを使用してカメラストリームを表示しています;ルーラーを描画するためのCAShapeLayerと結合されたパス。これはかなりうまく機能していますが、今度は視野値を使用して、要素を適切な場所に配置する必要があります(たとえば、160°から170°の間の適切なスペースを選択してください! )。

実際、私はこれらの値をこれらのソースでハードコーディングしています: https://stackoverflow.com/a/3594424/3198096 (@ hotpaw2に感謝します!)しかし、それらが完全に正確であるかどうかはわかりません。はiPhone5などを処理していません。公式ソース(Apple!)から値を取得できませんでしたが、必要だと思うすべてのiDevice(4、4S、5、5S)の値を示すリンクがあります: AnandTech | iphone 5sカメラの改善についてのいくつかの考え

:個人的なテストやその他のオンライン調査の後、これらの値は不正確であると確信しています。また、これにより、外部ライブラリを使用して、FOVを手動で初期化するために使用しているiPhoneのモデルを確認する必要があります...サポートされているすべてのデバイスの値を確認する必要があります。

「コードソリューション」がいいです!

この投稿を読んだ後: iPhone:リアルタイムのビデオの色情報、焦点距離、絞り? 、提案されているようにAVCaptureStillImageOutputからexif dataを取得しようとしています。その後、exifデータから焦点距離を読み取って、式を使用して水平および垂直の視野を計算できます。 (または、ここに示すようにFOVを直接取得することもできます: http://www.brianklug.org/2011/11/a-quick-analysis-of-exif-data-from-apples-iphone-4s-camera -samples / -note:一定数の更新後、exifから直接視野を取得できないようです! )


実際のポイント

ソースhttp://iphonedevsdk.com/forum/iphone-sdk-development/112225-camera-app-working-well -on-3gs-but-not-on-4s.html および 変更されたEXIFデータが正しく保存されない

これが私が使用しているコードです:

AVCaptureDevice* camera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (camera != nil)
{
    captureSession = [[AVCaptureSession alloc] init];

    AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:camera error:nil];

    [captureSession addInput:newVideoInput];

    captureLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
    captureLayer.frame = overlayCamera.bounds;
    [captureLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    previewLayerConnection=captureLayer.connection;
    [self setCameraOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
    [overlayCamera.layer addSublayer:captureLayer];
    [captureSession startRunning];

    AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
    [stillImageOutput setOutputSettings:outputSettings];
    [captureSession addOutput:stillImageOutput];

    AVCaptureConnection *videoConnection = nil;
    for (AVCaptureConnection *connection in stillImageOutput.connections)
    {
        for (AVCaptureInputPort *port in [connection inputPorts])
        {
            if ([[port mediaType] isEqual:AVMediaTypeVideo] )
            {
                videoConnection = connection;
                break;
            }
        }
        if (videoConnection) { break; }
    }

    [stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection
                                                         completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error)
     {
         NSData *imageNSData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

         CGImageSourceRef imgSource = CGImageSourceCreateWithData((__bridge_retained CFDataRef)imageNSData, NULL);

         NSDictionary *metadata = (__bridge NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imgSource, 0, NULL);

         NSMutableDictionary *metadataAsMutable = [metadata mutableCopy];

         NSMutableDictionary *EXIFDictionary = [[metadataAsMutable objectForKey:(NSString *)kCGImagePropertyExifDictionary]mutableCopy];

         if(!EXIFDictionary)
             EXIFDictionary = [[NSMutableDictionary dictionary] init];

         [metadataAsMutable setObject:EXIFDictionary forKey:(NSString *)kCGImagePropertyExifDictionary];

         NSLog(@"%@",EXIFDictionary);
     }];
}

出力は次のとおりです。

{
    ApertureValue = "2.52606882168926";
    BrightnessValue = "0.5019629837352776";
    ColorSpace = 1;
    ComponentsConfiguration =     (
        1,
        2,
        3,
        0
    );
    ExifVersion =     (
        2,
        2,
        1
    );
    ExposureMode = 0;
    ExposureProgram = 2;
    ExposureTime = "0.008333333333333333";
    FNumber = "2.4";
    Flash = 16;
    FlashPixVersion =     (
        1,
        0
    );
    FocalLenIn35mmFilm = 40;
    FocalLength = "4.28";
    ISOSpeedRatings =     (
        50
    );
    LensMake = Apple;
    LensModel = "iPhone 4S back camera 4.28mm f/2.4";
    LensSpecification =     (
        "4.28",
        "4.28",
        "2.4",
        "2.4"
    );
    MeteringMode = 5;
    PixelXDimension = 1920;
    PixelYDimension = 1080;
    SceneCaptureType = 0;
    SceneType = 1;
    SensingMethod = 2;
    ShutterSpeedValue = "6.906947890818858";
    SubjectDistance = "69.999";
    UserComment = "[S.D.] kCGImagePropertyExifUserComment";
    WhiteBalance = 0;
}

FOVを計算するために必要なものはすべて揃っていると思います。しかし、それらは正しい値ですか?さまざまな焦点距離値を与えるさまざまなウェブサイトをたくさん読んだ後、私は少し混乱しています!また、私のPixelDimensionsは間違っているようです!

経由 http://en.wikipedia.org/wiki/Angle_of_view これは私が使用する予定の式です:

FOV = (IN_DEGREES(   2*atan( (d) / (2  * f) )   ));
// d = sensor dimensions (mm)
// f = focal length (mm)

私の質問

私のメソッドと数式は正しく見えますか?はいの場合、どの値を関数に渡しますか?


精度

  • 支配者が現実とどのように一致するかについて何か提案があれば、FOVは私が使用する必要があると思うものです。私は答えを受け入れます!
  • 拡張現実ビューコントローラーではズームが無効になっているため、カメラの初期化時に視野が固定され、ユーザーが電話を回転させるまで視野を変更できません。

英語の間違いも申し訳ありませんが、私はフランス語です...

27
Humbertda

IOS 7以降では、次のように実行できます。

float FOV = camera.activeFormat.videoFieldOfView;

ここで、cameraはあなたのAVCaptureDeviceです。ビデオセッション用に選択したプリセットによっては、同じデバイスでも変更される可能性があります。これは水平方向の視野(度単位)であるため、表示サイズから垂直方向の視野を計算する必要があります。

これが Appleの参考資料 です。

26
Wildaker

FOVの式から、焦点距離とセンサーの寸法が必要です。 Exifデータには焦点距離がありますが、センサーの寸法はありません。メタデータでセンサーの寸法を提供しているカメラベンダー(Canon)は1つだけで、それはCRWrawファイルにあります。そのため、カメラまたはスマートフォンに基づいてセンサーの寸法をテーブルで検索する必要があります。次のウィキペディアのリンクには、多数のカメラと一部の新しいiPhoneのセンサーの寸法が記載されています。このリストは、Wiki記事の終わり近くにあります。 http://en.wikipedia.org/wiki/Image_sensor_format

この種の情報のもう1つの情報源は、さまざまな写真ブログです。お役に立てれば。

デジタルズームを使用する場合は、焦点距離にズーム値を掛けます。 Exifデータにはズーム率が含まれています。

http://www.kenrockwell.com などの写真ブログやWebサイトには、カメラセンサーの寸法に関する多くの情報があります。

修正:実際には、焦点面X解像度と焦点面Y解像度(ピクセル単位)および焦点面解像度単位のExifタグがあります。これらのタグと画像の寸法から、センサーサイズを計算できます。ただし、すべてのカメラがこれらのExifタグを提供しているわけではありません。たとえば、iPhone4はこれらのタグを提供していません。

1
Jim Merkel

Appleはまた、FOV(Field of View)を含むすべてのカメラ仕様の詳細を含むリストをリリースしました。

https://developer.Apple.com/library/ios/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Cameras/Cameras.html

値は、以下を使用して取得できる値と一致します。

float FOV = camera.activeFormat.videoFieldOfView;

1
Kevin Goedecke

あなたの質問に答えるには:

私の方法と式は正しく見えますか...?

たぶん、しかしそれらはあまりにも複雑に見えます。

...はいの場合、どの値を関数に渡しますか?

わかりませんが、目標がHFOVとVFOVを計算することである場合、これは、Swiftでアクセスできる唯一の視野角である水平視野角をプログラムで見つけるコード例です。現在、iPhone 6、16:9のアスペクト比に基づいて垂直視野角を計算します。

    let devices = AVCaptureDevice.devices()
    var captureDevice : AVCaptureDevice?
    for device in devices {
        if (device.hasMediaType(AVMediaTypeVideo)) {
            if(device.position == AVCaptureDevicePosition.Back) {
                captureDevice = device as? AVCaptureDevice
            }
        }
    }
    if let retrievedDevice = captureDevice {
        var HFOV : Float = retrievedDevice.activeFormat.videoFieldOfView
        var VFOV : Float = ((HFOV)/16.0)*9.0
    }

また、これを機能させたい場合は、AVFoundationをインポートすることを忘れないでください!

1
James Mart

視野の直径は、顕微鏡を見たときに見える光の円の直径です。

連続した約10個の丸いセルが視野の直径全体に収まる可能性があり、直径がミリメートルでわかっている場合は、合計直径を収まるセルの数で割って、各セルのサイズを見つけることができます。

適合するセルの数で割った総直径は、各セルのサイズ(直径)に等しくなります

視野の直径が1.5mmで、10個のセルを一列に並べると収まる場合、各セルは次のようになります。

1.5mm/10 = 0.15mm

0.15ミリメートル

倍率を変更するたびに、表示される光の円の直径が変更されることを忘れないでください。したがって、各倍率には独自の直径があります。

定規を顕微鏡下に置くと、ズームインすればするほど、定規に表示される線の数が少なくなります。

0
user3435307