Reconnaître des points de repère avec ML Kit sur iOS

Vous pouvez utiliser ML Kit pour reconnaître des points de repère bien connus dans une image.

Avant de commencer

  1. Si vous n'avez pas encore ajouté Firebase à votre application, suivez la procédure décrite dans le guide de démarrage.
  2. Incluez les bibliothèques ML Kit dans votre Podfile:
    pod 'Firebase/MLVision', '6.25.0'
    
    Après avoir installé ou mis à jour les pods de votre projet, ouvrez votre Xcode projet à l'aide de son .xcworkspace.
  3. Dans votre application, importez Firebase :

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. Si vous n'avez pas encore activé les API dans le cloud pour votre projet, faites-le dès maintenant:

    1. Ouvrez la page API ML Kit de la console Firebase.
    2. Si vous n'avez pas encore fait passer votre projet à un forfait Blaze, cliquez sur Pour ce faire, effectuez une mise à niveau. (Vous ne serez invité à effectuer la mise à niveau projet n'est pas inclus dans la formule Blaze.)

      Seuls les projets de niveau Blaze peuvent utiliser des API dans le cloud.

    3. Si les API dans le cloud ne sont pas déjà activées, cliquez sur Activer les services API.

Configurer le détecteur de points de repère

Par défaut, le détecteur de cloud utilise la version stable du modèle renvoie jusqu'à 10 résultats. Si vous souhaitez modifier l'un de ces paramètres, spécifiez-les avec un objet VisionCloudDetectorOptions dans l'exemple suivant:

Swift

let options = VisionCloudDetectorOptions()
options.modelType = .latest
options.maxResults = 20

Objective-C

  FIRVisionCloudDetectorOptions *options =
      [[FIRVisionCloudDetectorOptions alloc] init];
  options.modelType = FIRVisionCloudModelTypeLatest;
  options.maxResults = 20;
  

À l'étape suivante, transmettez l'objet VisionCloudDetectorOptions lorsque vous créez l'objet détecteur Cloud.

Exécuter le détecteur de points de repère

Pour reconnaître les points de repère dans une image, transmettez-la en tant que UIImage ou CMSampleBufferRef jusqu'au detect(in:) de VisionCloudLandmarkDetector méthode:

  1. Obtenez une instance de VisionCloudLandmarkDetector:

    Swift

    lazy var vision = Vision.vision()
    
    let cloudDetector = vision.cloudLandmarkDetector(options: options)
    // Or, to use the default settings:
    // let cloudDetector = vision.cloudLandmarkDetector()

    Objective-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionCloudLandmarkDetector *landmarkDetector = [vision cloudLandmarkDetector];
    // Or, to change the default settings:
    // FIRVisionCloudLandmarkDetector *landmarkDetector =
    //     [vision cloudLandmarkDetectorWithOptions:options];
  2. Créez un objet VisionImage à l'aide d'un UIImage ou d'un CMSampleBufferRef

    Pour utiliser un UIImage:

    1. Si nécessaire, faites pivoter l'image de sorte que son imageOrientation est .up.
    2. Créez un objet VisionImage en utilisant la rotation correcte UIImage Ne spécifiez aucune métadonnée de rotation (valeur par défaut : (.topLeft).

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    Pour utiliser une CMSampleBufferRef :

    1. Créez un objet VisionImageMetadata qui spécifie l'orientation des données d'image contenues dans le tampon CMSampleBufferRef.

      Pour obtenir l'orientation de l'image:

      Swift

      func imageOrientation(
          deviceOrientation: UIDeviceOrientation,
          cameraPosition: AVCaptureDevice.Position
          ) -> VisionDetectorImageOrientation {
          switch deviceOrientation {
          case .portrait:
              return cameraPosition == .front ? .leftTop : .rightTop
          case .landscapeLeft:
              return cameraPosition == .front ? .bottomLeft : .topLeft
          case .portraitUpsideDown:
              return cameraPosition == .front ? .rightBottom : .leftBottom
          case .landscapeRight:
              return cameraPosition == .front ? .topRight : .bottomRight
          case .faceDown, .faceUp, .unknown:
              return .leftTop
          }
      }

      Objective-C

      - (FIRVisionDetectorImageOrientation)
          imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                                 cameraPosition:(AVCaptureDevicePosition)cameraPosition {
        switch (deviceOrientation) {
          case UIDeviceOrientationPortrait:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationLeftTop;
            } else {
              return FIRVisionDetectorImageOrientationRightTop;
            }
          case UIDeviceOrientationLandscapeLeft:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationBottomLeft;
            } else {
              return FIRVisionDetectorImageOrientationTopLeft;
            }
          case UIDeviceOrientationPortraitUpsideDown:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationRightBottom;
            } else {
              return FIRVisionDetectorImageOrientationLeftBottom;
            }
          case UIDeviceOrientationLandscapeRight:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationTopRight;
            } else {
              return FIRVisionDetectorImageOrientationBottomRight;
            }
          default:
            return FIRVisionDetectorImageOrientationTopLeft;
        }
      }

      Ensuite, créez l'objet de métadonnées:

      Swift

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Objective-C

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. Créez un objet VisionImage à l'aide de la méthode CMSampleBufferRef et les métadonnées de rotation:

      Swift

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Transmettez ensuite l'image à la méthode detect(in:):

    Swift

    cloudDetector.detect(in: visionImage) { landmarks, error in
      guard error == nil, let landmarks = landmarks, !landmarks.isEmpty else {
        // ...
        return
      }
    
      // Recognized landmarks
      // ...
    }

    Objective-C

    [landmarkDetector detectInImage:image
                         completion:^(NSArray<FIRVisionCloudLandmark *> *landmarks,
                                      NSError *error) {
      if (error != nil) {
        return;
      } else if (landmarks != nil) {
        // Got landmarks
      }
    }];

Obtenir des informations sur les points de repère reconnus

Si la reconnaissance des points de repère réussit, un tableau de VisionCloudLandmark sont transmis au gestionnaire d'achèvement. À partir de chaque objet, vous pouvez obtenir des informations relatives à un point de repère reconnu dans l'image.

Exemple :

Swift

for landmark in landmarks {
  let landmarkDesc = landmark.landmark
  let boundingPoly = landmark.frame
  let entityId = landmark.entityId

  // A landmark can have multiple locations: for example, the location the image
  // was taken, and the location of the landmark depicted.
  for location in landmark.locations {
    let latitude = location.latitude
    let longitude = location.longitude
  }

  let confidence = landmark.confidence
}

Objective-C

for (FIRVisionCloudLandmark *landmark in landmarks) {
   NSString *landmarkDesc = landmark.landmark;
   CGRect frame = landmark.frame;
   NSString *entityId = landmark.entityId;

   // A landmark can have multiple locations: for example, the location the image
   // was taken, and the location of the landmark depicted.
   for (FIRVisionLatitudeLongitude *location in landmark.locations) {
     double latitude = [location.latitude doubleValue];
     double longitude = [location.longitude doubleValue];
   }

   float confidence = [landmark.confidence floatValue];
}

Étapes suivantes