【发布时间】: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.html 和 Modified 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