Как рассчитать FOV?

Исходный Контекст

Я разрабатываю местоположение приложения дополненной реальности на основе, и мне нужно получить поле зрения [FOV] (я просто обновляю значение при изменении ориентации, поэтому я ищу метод, который может получить это значение, когда я его вызываю)

цель состоит в том, чтобы сделать "градусную линейку" актуальной для реальности, как показано ниже: Degree Ruler - AR App

Я уже использую AVCaptureSession для отображения потока камеры ; и путь в сочетании с CAShapeLayer нарисовать правитель. Это работает довольно хорошо, но теперь я должен использовать поле зрения значение для размещения моего элемента в нужном месте (выберите нужное пространство между 160° и 170°, например!).

На самом деле, я жестко кодирую эти значения с помощью этих источников:https://stackoverflow.com/a/3594424/3198096 (особая благодарность @hotpaw2!) Но я не уверен, что они полностью точны, и это не касается iPhone 5 и т. д. Я не смог получить ценности из официальных источников (Яблоко!), но есть ссылка, показывающая значения для всех iDevice, которые мне нужны (4, 4S, 5, 5S) : AnandTech / некоторые мысли об улучшениях камеры iphone 5s.

Примечание: после личного теста и некоторых других исследований в Интернете, я уверен, что эти значения неточны! Также это заставляет меня использовать внешнюю библиотеку, чтобы проверить, какую модель iPhone я использую для ручной инициализации моего FOV... И я должен проверить свои значения для всех поддерживаемых устройство.

я бы предпочел "решение код" !

после прочтения этого поста: iPhone: информация о цвете видео в реальном времени, фокусное расстояние, диафрагма?, Я пытаюсь получить exif data из AVCaptureStillImageOutput как предложено. После того, что я смог прочитать фокусное расстояние из данных 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.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 кажется неправильным!

Via 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-это то, что я думаю, что мне нужно использовать, если у вас есть какие-либо предложения о том, как правитель может соответствовать реальности; я бы принял ответ !
  • Zoom отключен в контроллере дополненной реальности, поэтому мое поле зрения фиксируется, когда камера инициализирован и не может измениться, пока пользователь не повернет телефон!

также извините за мои английские ошибки, я француз...

5 ответов


в iOS 7 и выше вы можете сделать что-то в этом роде:

float FOV = camera.activeFormat.videoFieldOfView;

здесь camera ваш AVCaptureDevice. В зависимости от того, какой пресет вы выберете для видеосессии, это может измениться даже на одном устройстве. Это горизонтальное поле зрения (в градусах), поэтому вам нужно будет рассчитать вертикальное поле зрения из размеров дисплея.

здесь справочные материалы Apple.


из уравнения FOV вам нужны фокусное расстояние и размеры датчика. Данные Exif имеют фокусное расстояние, но не размеры датчика. Я нашел только одного поставщика камеры (Canon), который предоставляет размеры датчиков в метаданных-и это в их файлах CRW raw. Таким образом, вам придется иметь таблицу поиска размеров датчика на основе камеры или смартфона. В следующей ссылке Википедии перечислены размеры датчиков для многочисленных камер и некоторых новых iPhone. Список находится в конце Wiki статья. http://en.wikipedia.org/wiki/Image_sensor_format

другим источником для этого типа информации могут быть различные блоги фотографии. Надеюсь, это поможет.

Если используется цифровой зум, умножьте фокусное расстояние на значение Зума. Данные Exif содержат коэффициент масштабирования.

фотографии блоги и веб-сайты, такие как http://www.kenrockwell.com имейте много информации о размерах датчика камеры.

A коррекция: на самом деле есть теги Exif для разрешения фокальной плоскости X и разрешения фокальной плоскости Y (в пикселях) и единиц разрешения фокальной плоскости, из этих тегов и размеров изображения вы можете вычислить размер датчика. Но не все камеры предоставляют эти теги Exif. Например, iPhone 4 не предоставляет эти теги.


чтобы ответить на ваш вопрос:

мой метод и моя формула выглядят правильно...?

возможно, но они также выглядят слишком сложными.

...и если да, то какие значения я передаю в функцию?

Я не знаю, но если цель состоит в том, чтобы вычислить 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, если вы хотите, чтобы это работало!


Apple также выпустила список со всеми деталями спецификации камеры, включая FOV (поле зрения).

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

значения соответствуют значениям, которые могут быть получены с помощью:

float FOV = camera.activeFormat.videoFieldOfView;


диаметр поля зрения-это диаметр круга света, который вы можете видеть, когда смотрите в микроскоп.

Если около десяти круглых ячеек в ряд может поместиться поперек диаметра поля зрения, и если вы знаете диаметр в миллиметрах, то вы можете разделить общий диаметр на количество ячеек, которые подходят, чтобы найти размер каждой ячейки.

общий диаметр, деленный на количество ячеек, которые будут соответствовать, равен размеру (диаметру) каждой ячейки

пример

Если диаметр поля зрения 1,5 мм и десять ячеек поместились бы, если бы они были расположены в линию, то каждая ячейка:

1,5 мм/10 = 0.15 мм

0.15 миллиметров

помните, что каждый раз, когда вы меняете увеличение, вы меняете диаметр круга света, который вы можете видеть. Таким образом, каждое увеличение будет иметь свой собственный диаметр.

Если вы положите линейку под микроскоп, тем больше вы увеличиваете, чем меньше линий на линейке, тем меньше их видно.