SDK iOS réalité augmentée configuration de l'appareil photo

Le concept de réalité augmentée (RA) a suscité un regain d'intérêt ces dernières années, car l'iPhone et d'autres appareils mobiles ont mis des processeurs, des capteurs et des caméras toujours plus puissants entre les mains de millions de personnes à travers le monde. Pour la première fois depuis que le terme a été inventé dans les années 1990, le consommateur moyen peut désormais regarder à travers l'écran de son smartphone et trouver une couche de réalité dont il n'aurait jamais su l'existence. Cette série premium Mobiletuts + s'aventurera dans le monde de la réalité augmentée et de la réalité mixte. Il montrera, étape par étape, comment fusionner la caméra et les capteurs de l'iPhone avec des images de synthèse pour créer une version améliorée, modifiée ou même déformée du monde qui vous entoure..

Cette série de didacticiels met l’accent sur la compréhension des composants disponibles sur l’iPhone qui permettent les expériences de réalité augmentée et de réalité mixte. Ceci sera réalisé en créant une simple démo d'AR, et ce tutoriel nous lancera sur cette voie en abordant la tâche la plus fondamentale de nombreuses applications d'AR: obtenir un accès programmatique au flux vidéo du périphérique..


Étape 1: Créer un nouveau projet Xcode

Commencez par lancer Xcode et créer un nouveau projet. Sélectionnez "Application basée sur la vue" comme type de modèle et cliquez sur "Suivant":


Sur l'écran suivant, entrez "MobiletutsAR" comme nom du produit.

Pour le Identifiant de l'entreprise Dans ce champ, j'ai utilisé "com.mobiletuts.ardemo", mais vous devrez fournir l'identificateur unique qui correspond à votre propre profil d'approvisionnement de développeur ou de distribution ad hoc..

Le processus de configuration d'un périphérique pour les tests d'application dépasse le cadre de ce didacticiel, mais la documentation sur ce processus est disponible aux sources suivantes:

  • Documentation officielle Apple (mise à jour pour Xcode 4)
  • Mobiletuts + Guide (À partir de 2010, illustre la configuration manuelle avec Xcode 3)
  • Question Stackoverflow

Comme mentionné ci-dessus, vous devez être membre du programme de développeur iOS payant pour tester les applications sur des périphériques iOS physiques..

Sélectionnez "iPhone" pour le Famille de périphérique menu déroulant. Bien que ce didacticiel se concentre sur la création d’une application de RA simple pour iPhone, les principes présentés s’appliqueront à tout autre appareil iOS doté du matériel requis..

Décochez la case "Inclure les tests unitaires", puis cliquez sur "Suivant". Les tests unitaires ne sont pas nécessaires pour ce projet de démonstration AR, mais peuvent être d'une grande aide dans le cycle de vie du développement logiciel (documentation officielle Apple sur les tests unitaires)..


La dernière étape de ce processus consiste à sélectionner l'emplacement de stockage du projet sur votre disque dur, puis à cliquer sur "Créer"..


Étape 2: Importer les exigences du cadre

Pour commencer à utiliser les données de la caméra et compléter ce didacticiel, nous allons avoir besoin du framework AVFoundation. La structure AVFoundation fournit les fonctionnalités nécessaires pour capturer des images à partir de la caméra du périphérique, ce qui est l'objectif principal de ce didacticiel. Il fournit également des méthodes pour créer, gérer et lire d’autres ressources multimédia..

Pour plus d'informations, consultez le Guide de programmation et de référence AVFoundation officiel d'Apple..

Le processus d'importation d'un framework dans un projet Xcode 4 est simple et probablement bien compris, mais, pour ceux qui débutent avec Xcode 4, il sera néanmoins démontré.

Sélectionnez le projet "ARDemo" dans le navigateur de projet Xcode 4. Cliquez ensuite sur la cible "ARDemo", puis sur l'onglet "Construire les phases" avant de développer la liste déroulante "Lier les fichiers binaires aux bibliothèques"..


Cliquez sur le symbole "+" et sélectionnez la valeur "AVFoundation.framework" dans la liste. Cliquez sur "Ajouter".


Une fois la structure ajoutée et affichée dans le navigateur de projet Xcode, faites-la glisser dans le dossier "Frameworks" pour que le projet reste ordonné..

Répétez cette procédure pour ajouter "CoreMedia.framework" et "CoreVideo.framework".

Maintenant que nous avons les frameworks ci-dessus dans notre projet, nous devons les rendre disponibles dans notre code. Ouvrir ARDemoViewController.h et ajoutez la ligne suivante:

 #importation 

Étape 3: Configurer l'interface View Controller

Pour cette leçon, nous allons devoir déclarer deux membres de données et une méthode dans le ARDemoViewController.h fichier:

 @interface ARDemoViewController: UIViewController AVCaptureSession * cameraCaptureSession; AVCaptureVideoPreviewLayer * cameraPreviewLayer;  - (void) initializeCaptureSession; @fin

A la ligne 3, une instance de AVCaptureSession est déclaré. le AVCaptureSession class est le composant principal utilisé pour gérer les entrées vidéo reçues de la caméra du périphérique. En plus de gérer les entrées de caméra, la classe fournit également des méthodes de délégation qui rendent chaque image disponible pour votre application pour un traitement personnalisé. Pour cette raison, j'aime penser à cela comme à un "pipeline" de médias.

A la ligne 4, une instance de AVCaptureVideoPreviewLayer est déclaré. Ceci est une sous-classe spéciale de CALayer conçu pour fonctionner avec un AVCaptureSession en affichant la sortie vidéo diffusée par la caméra.

Sur la ligne 7, le -(vide) initializeCaptureSession La méthode est déclarée. Cette méthode initialisera le cameraCaptureSession, lien cameraPreviewLayer avec cameraCaptureSession, et ajouter cameraCaptureSession à la vue.


Étape 4: Vérifiez la disponibilité de la caméra

Le reste de ce tutoriel se concentrera sur la -initializeCaptureSession method declard à l’étape 3. Cette méthode doit être appelée à partir de -viewDidLoad parce que nous voulons que la caméra de l'appareil commence immédiatement à diffuser en continu lors du chargement de l'application. Allons-y et mettons ceci en place:

 - (void) viewDidLoad [super viewDidLoad]; [auto initializeCaptureSession];  - (void) initializeCaptureSession 

Si vous avez beaucoup travaillé avec l'appareil photo dans UIKit, vous connaissez probablement déjà le UIImagePickerController méthode de classe +availableMediaTypesForSourceType: qui retourne un NSArray des types de sources disponibles. Vous pouvez ensuite parcourir le tableau retourné à la recherche du type de source souhaité pour déterminer si le périphérique peut prendre en charge la vidéo..

le AVFoundation framework fournit des fonctionnalités similaires pour rechercher les sources d'entrée disponibles (appelées "périphériques de capture").

 // Tentative d'initialisation d'AVCaptureDevice avec la caméra de recul NSArray * videoDevices = [AVCaptureDevice devicesWithMediaType: AVMediaTypeVideo]; AVCaptureDevice * captureDevice = nil; for (périphérique AVCaptureDevice * dans videoDevices) if (device.position == AVCaptureDevicePositionBack) captureDevice = device; Pause;  // Si la caméra est accessible par session de capture si (captureDevice) // AVCaptureDevice souhaité est disponible else // AVCaptureDevice souhaité n'est pas disponible. Aler l'utilisateur et caution. UIAlertView * alert = [[UIAlertView all] initWithTitle: @ "Message de caméra non disponible": @ "" délégué: nil cancelButtonTitle: @ "OK" otherButtonTitles: nil]; [émission d'alerte]; [libération d'alerte]; 

Sur la ligne 2, un ensemble de tous les périphériques de capture disponibles capables de diffuser de la vidéo en continu est créé. Sur les lignes 4 à 11, ce tableau est itéré pour tenter de trouver un périphérique avec la valeur de position AVCaptureDevicePositionBack (Si vous préférez compléter ce didacticiel avec l'appareil photo de face, vous pouvez rechercher AVCaptureDevicePositionFront).

Le reste du code ci-dessus établit simplement une condition qui teste captureDevice pour nous permettre de réagir de manière dynamique si, pour une raison quelconque, le périphérique souhaité n'est pas disponible.


Étape 5: initialiser la session de capture

Après vous être assuré que le périphérique d'entrée souhaité est bien disponible, allons-y et configurons notre session de capture vidéo:

 // Si la caméra est accessible par une session de capture si (captureDevice) // Allouer une session de capture de caméra cameraCaptureSession = [[AVCaptureSession alloc] init]; cameraCaptureSession.sessionPreset = AVCaptureSessionPresetMedium; // Configuration de l'entrée de session de capture AVCaptureDeviceInput * videoIn = [AVCaptureDeviceInput deviceInputWithDevice: captureDevice error: nil]; [cameraCaptureSession addInput: videoIn]; // Configuration de la sortie de la session de capture AVCaptureVideoDataOutput * videoOut = [[AVCaptureVideoDataOutput alloc] init]; [videoOut setAlwaysDiscardsLateVideoFrames: YES]; [cameraCaptureSession addOutput: videoOut]; [videoOut release];

Sur la ligne 6, le cameraCaptureSession est alloué (cela sera publié plus tard).

Sur la ligne 7, nous spécifions que la qualité de la sortie vidéo générée à partir de cette session de capture doit être AVCaptureSessionPresetMedium. La documentation officielle Apple répertorie les choix disponibles suivants pour ce paramètre:

AVCaptureSessionPresetPhoto
Spécifie les paramètres de capture appropriés pour une sortie en qualité photo haute résolution.
AVCaptureSessionPresetHigh
Spécifie les paramètres de capture appropriés pour une sortie vidéo et audio de haute qualité.
AVCaptureSessionPresetMedium
Spécifie les paramètres de capture adaptés aux débits binaires vidéo et audio de sortie adaptés au partage via WiFi.
AVCaptureSessionPresetLow
Spécifie les paramètres de capture adaptés aux débits binaires de sortie vidéo et audio compatibles avec le partage sur 3G.
AVCaptureSessionPreset640x480
Spécifie les paramètres de capture adaptés à la sortie vidéo de qualité VGA (640x480 pixels).
AVCaptureSessionPreset1280x720
Spécifie les paramètres de capture adaptés à la sortie vidéo de qualité 720p (1280x720pixel).

Définir une valeur de sortie plus élevée signifie que vous disposez de plus de données pour le traitement et l'analyse, en plus d'une image de sortie finale de meilleure qualité visuelle. Cependant, ces avantages ont un prix: des vitesses de traitement plus faibles. Lorsque vous travaillez avec une vidéo ou tentez une reconnaissance d'objet dynamique, vous constaterez qu'il peut être très utile de modifier ce paramètre..

Notez également que, bien que des préréglages de capture spécifiques soient disponibles (par exemple, 1280x720, 640x480), il est généralement conseillé d'utiliser l'une des valeurs plus génériques "Elevé", "Moyen" ou "Faible". Cela rend votre application plus portable et plus robuste car elle peut fonctionner sur des périphériques (actuels ou futurs!) Qui peuvent ne pas prendre en charge une valeur codée en dur donnée..

Les lignes 8 à 10 créent un AVCaptureDeviceInput objet, en utilisant le périphérique de capture que nous avons créé précédemment, puis ajoutez l'objet à notre session de capture.

Les lignes 14 à 17 établissent un AVCaptureDeviceOutput objet et l'ajouter à notre session de capture. Sur la ligne 15, nous configurons le sortie vidéo toujours ignorer les images reçues en retard. N'oubliez pas que la session de capture gérera de nombreuses images toutes les secondes et qu'en raison des variations de la charge du processeur, il est possible que certaines de ces images arrivent plus tard que d'autres. Parce que nous construisons une application qui tente de générer une fenêtre en direct sur le monde derrière l'iPhone, nous ne nous soucions pas des images en retard, nous les rejetons donc. Nous voulons seulement traiter et afficher des images aussi proches que possible de la milliseconde actuelle..


Étape 6: Ajouter un calque de prévisualisation vidéo

Une fois les entrées et les sorties de la session de capture configurées, il est temps de lier la couche de prévisualisation déclarée dans l'interface au flux vidéo de la session de capture. Cela fournira aux utilisateurs une fenêtre numérique de la réalité qui les entoure.

 // Lier la couche d'aperçu pour capturer les données de session cameraPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession: cameraCaptureSession]; CGRect layerRect = self.view.bounds; cameraPreviewLayer.bounds = self.view.bounds; cameraPreviewLayer.position = CGPointMake (CGRectGetMidX (layerRect), CGRectGetMidY (layerRect)); cameraPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; // Ajouter la couche d'aperçu à la couche UIView [self.view.layer addSublayer: cameraPreviewLayer];

Les cinq premières lignes de l'extrait de code ci-dessus allouent le calque d'aperçu et redimensionnent les limites du calque pour remplir l'écran de l'appareil..

La ligne suivante définit le videGravity propriété. Ce paramètre détermine le mode de rendu des images vidéo dans la couche d’aperçu. La documentation officielle d’Apple décrit les possibilités suivantes:

AVLayerVideoGravityResize
Spécifie que la vidéo doit être étirée pour remplir les limites du calque.
AVLayerVideoGravityResizeAspect
Spécifie que le lecteur doit conserver le rapport hauteur / largeur de la vidéo et l'adapter à la vidéo dans les limites du calque..
AVLayerVideoGravityResizeAspectFill
Spécifie que le lecteur doit conserver les proportions de la vidéo et combler les limites du calque..

Comme vous pouvez le constater d'après le code ci-dessus, je pense que AVLayerVideoGravityResizeAspectFill correspond le mieux à notre cas d'utilisation.

La dernière ligne ci-dessus est responsable de l'ajout de l'aperçu CALayer à la couche de contrôleur de vue, ce qui le rend visible à l'utilisateur.


Étape 7: Commencez le streaming vidéo

Dans les six étapes ci-dessus, nous avons créé notre projet et créé un AVCaptureSession lié à la caméra arrière pour l'entrée et un calque d'aperçu personnalisé pour la sortie. À ce stade, il ne reste plus qu'à lancer le streaming vidéo en lançant la session de capture:

 // Commencer la capture de la caméra [cameraCaptureSession startRunning]; 

Avec l’initialisation de la session de capture terminée, le temps est venu de libérer la mémoire allouée. Faites-le avec le code suivant:

 - (void) viewDidUnload [super viewDidUnload]; [cameraCaptureSession stopRunning]; [version de cameraCaptureSession], cameraCaptureSession = nil; [version de cameraPreviewLayer], cameraPreviewLayer = nil;  - (void) dealloc [cameraCaptureSession stopRunning]; [version de cameraCaptureSession]; [version de cameraPreviewLayer]; [super dealloc]; 

Si vous enregistrez, construisez et exécutez le projet après avoir ajouté les lignes de code ci-dessus, vous devriez pouvoir jeter un coup d'œil sur le monde qui vous entoure directement sur l'écran de l'iPhone..

Emballer

Ce tutoriel vous a expliqué le processus d'utilisation de la structure AVFoundation pour lancer la capture vidéo et afficher chaque image en temps quasi réel sur l'écran d'un iPhone. En raison de l'omniprésence des caméras vidéo tout autour de nous (ainsi que de l'application iPhone Camera), cela ne semble pas être un grand accomplissement, mais c'est vraiment le cas! C'est la première étape de nombreuses applications de réalité augmentée: numériser la vue de l'utilisateur sur le monde perçu. À partir de là, nous pouvons continuer dans différentes directions, allant de superposer des vues personnalisées dans le cadre réel à la manipulation des données de pixels du monde afin d'améliorer ou de modifier notre vision de la réalité..

Le prochain tutoriel premium Mobiletuts + de cette série se poursuivra en prenant notre fenêtre numérique du monde et en la rendant un peu plus intéressante. Restez à l'écoute et merci de lire!