【问题标题】:How to calculate FOV?如何计算FOV?
【发布时间】:2014-03-03 08:59:46
【问题描述】:

初始上下文

我正在开发一个基于位置的增强现实应用程序,我需要获取视野 [FOV](我只是在方向改变时更新值,所以我正在寻找一种可以在调用时获取该值的方法它)

我们的目标是制作一个与现实相关的“度数尺”,如下所示:

我已经在使用AVCaptureSession 来显示摄像头流;和一条路径加上CAShapeLayer 来绘制标尺。这工作得很好,但现在我必须使用 Field of view 值将我的元素放置在正确的位置(例如,选择 160° 和 170° 之间的正确空间!)。

实际上,我正在使用以下来源对这些值进行硬编码:https://stackoverflow.com/a/3594424/3198096(特别感谢@hotpaw2!)但我不确定它们是否完全精确,并且这不适用于 iPhone 5 等。我无法获得值来自官方来源(Apple!),但有一个链接显示我认为我需要的所有 iDevice 的值(4、4S、5、5S):AnandTech | Some thoughts about the iphone 5s camera improvements

注意:经过个人测试和其他一些在线研究,我很确定这些值是不准确的!这也迫使我使用外部库来检查我使用哪种型号的 iPhone 来手动初始化我的 FOV...而且我必须检查所有支持设备的值。

###我更喜欢“代码解决方案” !###

阅读这篇文章后:iPhone: Real-time video color info, focal length, aperture?,我正在尝试像建议的那样从 AVCaptureStillImageOutput 获取exif data。之后我可以从exif数据中读取焦距,然后通过公式计算水平和垂直视野! (或者也许直接获得像这里显示的FOV:http://www.brianklug.org/2011/11/a-quick-analysis-of-exif-data-from-apples-iphone-4s-camera-samples/-- 注意:经过一定次数的更新,exif似乎无法直接获取视野!)


实际点

来源http://iphonedevsdk.com/forum/iphone-sdk-development/112225-camera-app-working-well-on-3gs-but-not-on-4s.htmlModified EXIF data doesn't save properly

这是我正在使用的代码:

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 是我认为我需要使用的,如果您对尺子如何匹配现实有任何建议;我会接受答案!
  • 在增强现实视图控制器中禁用了缩放,因此在初始化相机时我的视野是固定的,并且在用户旋转手机之前无法改变!

【问题讨论】:

  • 也许尝试获得更多声誉,以便您可以投资更高的赏金。也许这将有助于获得更多关注
  • ExifTool 根据 Exif 数据计算 FOV 和其他一些东西。也许您可以查看 ExifTool 的输出并对其进行逆向工程。
  • @Pavan :我想这就是我要做的! JimMerkel 这是个好主意,我不知道 Phil Harvey 的 ExifTool,谢谢!如果你有评论,我会给你赏金!
  • 像素尺寸可能是正确的:相机硬件处于视频模式,可能默认以 1080p 录制。 FOV应该可以从 EXIF 数据中计算出来,假设“35mm”帧尺寸为 36×24mm,但显然 iPhone 4S 传感器是 4.54×3.42mm,所以这个数字不太准确(假设没有水平裁剪)。

标签: ios iphone camera avcapturesession fieldofview


【解决方案1】:

在 iOS 7 及更高版本中,您可以执行以下操作:

float FOV = camera.activeFormat.videoFieldOfView;

其中camera 是您的AVCaptureDevice。根据您为视频会话选择的预设,这可能即使在同一设备上也会发生变化。它是水平视野(以度为单位),因此您需要根据显示尺寸计算垂直视野。

这里是Apple's reference material

【讨论】:

  • 完美!每个人都必须知道这个答案。你让我很开心,谢谢(希望你能赢得赏金!)
  • 这是两个视野中较宽的一个,即横向工作时的水平视野。
【解决方案2】:

回答你的问题:

我的方法和公式看起来是否正确...?

也许吧,但它们看起来也太复杂了。

...如果是,我将哪些值传递给函数?

我不知道,但如果目标是计算 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!

【讨论】:

    【解决方案3】:

    Apple 还发布了包含所有相机规格详细信息的列表,包括 FOV(视野)。

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

    这些值与可以使用以下方法检索的值相匹配:

    float FOV = camera.activeFormat.videoFieldOfView;

    【讨论】:

      【解决方案4】:

      根据 FOV 方程,您需要焦距和传感器尺寸。 Exif 数据具有焦距,但没有传感器尺寸。我发现只有一家相机供应商(佳能)在元数据中提供传感器尺寸——即在他们的 CRW 原始文件中。因此,您必须根据相机或智能手机查找传感器尺寸的表格。以下 Wikipedia 链接列出了众多相机和一些较新 iPhone 的传感器尺寸。该列表在 Wiki 文章的末尾附近。 http://en.wikipedia.org/wiki/Image_sensor_format

      此类信息的另一个来源可能是各种摄影博客。 希望这会有所帮助。

      如果使用数码变焦,请将焦距乘以变焦值。 Exif 数据包含缩放因子。

      摄影博客和网站(如http://www.kenrockwell.com)提供大量有关相机传感器尺寸的信息。

      修正:实际上有 Exif 标签用于焦平面 X 分辨率和焦平面 Y 分辨率(以像素为单位)和焦平面分辨率单位,根据这些标签和图像尺寸,您可以计算传感器尺寸。但并非所有相机都提供这些 Exif 标签。例如 iPhone 4 不提供这些标签。

      【讨论】:

      • 好的,所以我猜想将我的硬编码数组与所有 iPhone 视野保持一致会更简单!谢谢你的回答!
      【解决方案5】:

      视场直径是您在显微镜下看到的光环的直径。

      如果一行中大约十个圆形单元格可以穿过视野的直径,并且如果您知道直径(以毫米为单位),那么您可以将总直径除以适合的单元格数,以找到每个单元格的大小细胞。

      总直径除以适合的单元数等于每个单元的大小(直径)

      例子

      如果视场的直径是 1.5mm,如果排列成一条线就可以容纳十个单元格,那么每个单元格是:

      1.5mm/10 = 0.15mm

      0.15 毫米

      请记住,每次更改放大倍率时,都会更改您可以看到的光圈的直径。所以每个放大倍率都有自己的直径。

      如果你把尺子放在显微镜下,你放大的越多,你能看到的尺子上的线数就越少。

      【讨论】:

      • (缩放已禁用,我在问题中添加了信息,谢谢!)所以放大倍率不会改变,缩放不适合应用程序,所以我认为最好禁用它!实际上这是我的想法,但以像素为单位:如果我有 FOV 和屏幕尺寸,我可以知道两度之间有多少像素。 (就像你建议的 1.5mm/10 一样)。我也可以以毫米为单位,然后将其转换为像素,但我的问题仍然悬而未决:你如何在 iOS 中获得相机 FOV? (毫米或度数)感谢您的回答!
      猜你喜欢
      • 2014-02-15
      • 1970-01-01
      • 1970-01-01
      • 2018-02-16
      • 2015-01-23
      • 2019-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多