Comment calculer FOV?
Contexte Initial
je développe une application de réalité augmentée basée sur l'emplacement et j'ai besoin d'obtenir le champ de vision [FOV] (je viens de mettre à jour la valeur quand l'orientation change, donc je suis à la recherche d'une méthode qui peut obtenir cette valeur quand je l'appelle)
le but est de faire une" règle de degré " pertinente à la réalité comme le suivant:
j'utilise déjà AVCaptureSession
pour afficher caméra stream; et un chemin couplé à un CAShapeLayer
pour dessiner la règle. Cela fonctionne assez bien, mais maintenant je dois utiliser champ de vision valeur pour placer mon élément à la bonne place (choisissez le bon espace entre 160° et 170° par exemple!).
en fait, je suis hardcoding ces valeurs avec ces sources : https://stackoverflow.com/a/3594424/3198096 (remerciements spéciaux à @hotpaw2!) Mais je suis pas sûr qu'ils soient pleinement précis et ce n'est pas gérer iPhone 5, etc J'ai été incapable d'obtenir les valeurs à partir de sources officielles (Apple!), mais il ya un lien montrant des valeurs pour tous iDevice je pense que j'ai besoin (4, 4S, 5, 5S) : AnandTech | quelques réflexions sur l'iphone 5s améliorations de la caméra .
Note : après un test personnel et d'autres recherches en ligne, je suis presque sûr que ces valeurs sont inexactes! Aussi cela m'oblige à utiliser une bibliothèque externe pour Vérifiez quel modèle d'iPhone j'utilise pour initialiser manuellement mon FOV... Et je dois vérifier mes valeurs pour tous les appareils pris en charge.
je préférerais un " solution de code " !
après avoir lu ce billet: iPhone: informations de couleur vidéo en temps réel, focal length, aperture? , j'essaie d'obtenir exif data
de AVCaptureStillImageOutput comme suggéré. Après ce que je pourrais être capable de lire le Distance focale à partir des données exif, puis calculer le champ de vision horizontal et vertical à l'aide de la formule! (Ou peut-être obtenir directement la FOV comme indiqué ici : http://www.brianklug.org/2011/11/a-quick-analysis-of-exif-data-from-apples-iphone-4s-camera-samples / --
note : après un certain nombre de mise à jour, il semble que nous ne pouvons pas obtenir directement le champ de vision d'exif!)
réel Point
Sources de : http://iphonedevsdk.com/forum/iphone-sdk-development/112225-camera-app-working-well-on-3gs-but-not-on-4s.html et Modifié les données EXIF ne pas enregistrer correctement
voici le code que j'utilise:
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);
}];
}
Voici la sortie:
{
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;
}
je pense que j'ai tout ce dont j'ai besoin pour calculer FOV. Mais sont-ils les valeurs de droite? Parce qu'après avoir lu beaucoup de différents sites Web donnant des valeurs différentes focal length , je suis un peu confus! Aussi mes Pixels dimensionnels semblent être faux!
Via http://en.wikipedia.org/wiki/Angle_of_view c'est la formule que j'avais prévu d'utiliser:
FOV = (IN_DEGREES( 2*atan( (d) / (2 * f) ) ));
// d = sensor dimensions (mm)
// f = focal length (mm)
Ma Question
Faire ma méthode et ma formule de regarder à droite, et si oui, quelles valeurs dois-je passer à la fonction?
précisions
- FOV est ce que je pense que j'ai besoin de l'utiliser, si vous avez des suggestions, de la façon dont le souverain peut correspondre à la réalité; j'accepte la réponse !
- Zoom est désactivé dans le contrôleur de la réalité augmentée, donc mon champ de vision est fixe lorsque la caméra est initialisée, et ne peut pas changer jusqu'à ce que l'utilisateur tourne le téléphone!
aussi désolé pour mes erreurs en anglais, je suis français...
5 réponses
Dans iOS 7 et ci-dessus, vous pouvez faire quelque chose le long de ces lignes:
float FOV = camera.activeFormat.videoFieldOfView;
où camera
est votre AVCaptureDevice
. En fonction du preset que vous choisissez pour la session vidéo, cela peut changer même sur le même appareil . C'est le champ de vision horizontal (en degrés), vous aurez donc besoin de calculer le champ de vision vertical à partir des dimensions de l'écran.
Voici d'Apple matériel de référence .
de L'équation FOV, vous avez besoin de la distance focale et des dimensions du capteur. Les données Exif ont la distance focale mais pas les dimensions du capteur. Je n'ai trouvé qu'un seul vendeur de caméras (Canon) qui fournit les dimensions des capteurs dans les métadonnées -- et c'est dans leurs fichiers CRW raw. Vous aurez donc besoin d'une table de recherche des dimensions des capteurs basée sur l'appareil photo ou le smartphone. Le lien Wikipédia suivant liste les dimensions des capteurs pour de nombreux appareils photo et de nouveaux iPhones. La liste est proche de la fin du Article Wiki. http://en.wikipedia.org/wiki/Image_sensor_format
une autre source pour ce type d'information pourrait être divers blogs de photographie. Espérons que cette aide.
si un zoom numérique est utilisé, multiplier la distance focale par la valeur de zoom. Les données Exif contiennent le facteur de zoom.
blogs de photographie et des sites web tels que http://www.kenrockwell.com ont beaucoup d'informations sur dimensions du capteur de caméra.
une correction: en fait, il existe des balises Exif pour la résolution du plan Focal X et la résolution du plan Focal Y (en pixels) et des unités de résolution du plan Focal, à partir de ces balises et des dimensions de l'image, vous pouvez calculer la taille du capteur. Mais toutes les caméras ne fournissent pas ces étiquettes Exif. Par exemple iPhone 4 ne fournit pas ces étiquettes.
pour répondre à votre question:
ma méthode et ma formule ont l'air bien...?
Peut-être, mais ils ont aussi l'air trop complexe.
...et si oui, quelles valeurs puis-je transmettre à la fonction?
Je ne sais pas, mais si le but est de calculer HFOV et VFOV, voici un exemple de code qui trouve programmatically L'Angle Horizontal de visualisation, qui est le seul angle d'observation auquel on peut accéder dans Swift actuellement, et calcule ensuite L'Angle D'observation Vertical basé sur le rapport d'aspect de l'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
}
n'oubliez pas d'importer AVFoundation si vous voulez que cela fonctionne!
Apple a également publié une liste avec tous les détails des spécifications des caméras, y compris FOV (champ de vision).
les valeurs correspondent aux valeurs qui peuvent être récupérées en utilisant:
float FOV = camera.activeFormat.videoFieldOfView;
Le diamètre du champ de vue est le diamètre du cercle de lumière, vous pouvez voir quand on se regarde dans un microscope.
Si dix tour des cellules dans une ligne pourrait être sur le diamètre du champ de vision et si vous connaissez le diamètre en millimètres, alors vous pouvez diviser le diamètre total par le nombre de cellules qui correspondent à trouver la taille de chaque cellule.
Diamètre total divisé par le nombre de cellules qui correspondraient est égal à la taille (diamètre) de chaque cellule
exemple
si le diamètre du champ de vision est de 1,5 mm et que dix cellules peuvent être placées si elles sont disposées en ligne, alors chaque cellule est:
1,5 mm / 10 = 0,15 mm
0,15 millimètres
rappelez-vous que chaque fois que vous changez le grossissement, vous changez le diamètre du cercle de lumière que vous pouvez voir. Donc chaque grossissement aura son propre diamètre.
Si vous mettez un souverain sous un microscope, plus vous zoomez, moins le nombre de lignes de la règle que vous pouvez voir.