Reconheça pontos de referência com kit de ML no iOS

Você pode usar o ML Kit para reconhecer pontos de referência conhecidos em uma imagem.

Antes de você começar

  1. Se você ainda não adicionou o Firebase ao seu aplicativo, faça isso seguindo as etapas do guia de primeiros passos .
  2. Inclua as bibliotecas do ML Kit em seu Podfile:
    pod 'Firebase/MLVision', '6.25.0'
    
    Depois de instalar ou atualizar os pods do seu projeto, certifique-se de abrir seu projeto Xcode usando seu .xcworkspace .
  3. No seu aplicativo, importe o Firebase:

    Rápido

    import Firebase

    Objetivo-C

    @import Firebase;
  4. Se você ainda não habilitou APIs baseadas em nuvem para seu projeto, faça-o agora:

    1. Abra a página APIs do kit de ML do console do Firebase.
    2. Se você ainda não atualizou seu projeto para um plano de preços Blaze, clique em Atualizar para fazer isso. (Você será solicitado a atualizar somente se o seu projeto não estiver no plano Blaze.)

      Somente projetos no nível Blaze podem usar APIs baseadas em nuvem.

    3. Se as APIs baseadas em nuvem ainda não estiverem habilitadas, clique em Habilitar APIs baseadas em nuvem .

Configurar o detector de pontos de referência

Por padrão, o detector de nuvem usa a versão estável do modelo e retorna até 10 resultados. Se desejar alterar qualquer uma dessas configurações, especifique-as com um objeto VisionCloudDetectorOptions como no exemplo a seguir:

Rápido

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

Objetivo-C

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

Na próxima etapa, passe o objeto VisionCloudDetectorOptions ao criar o objeto Detector de nuvem.

Execute o detector de pontos de referência

Para reconhecer pontos de referência em uma imagem, passe a imagem como UIImage ou CMSampleBufferRef para o método detect(in:) do VisionCloudLandmarkDetector :

  1. Obtenha uma instância do VisionCloudLandmarkDetector :

    Rápido

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

    Objetivo-C

    FIRVision *vision = [FIRVision vision];
    FIRVisionCloudLandmarkDetector *landmarkDetector = [vision cloudLandmarkDetector];
    // Or, to change the default settings:
    // FIRVisionCloudLandmarkDetector *landmarkDetector =
    //     [vision cloudLandmarkDetectorWithOptions:options];
    
  2. Crie um objeto VisionImage usando UIImage ou CMSampleBufferRef .

    Para usar uma UIImage :

    1. Se necessário, gire a imagem para que sua propriedade imageOrientation seja .up .
    2. Crie um objeto VisionImage usando o UIImage girado corretamente. Não especifique nenhum metadado de rotação — o valor padrão, .topLeft , deve ser usado.

      Rápido

      let image = VisionImage(image: uiImage)

      Objetivo-C

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

    Para usar um CMSampleBufferRef :

    1. Crie um objeto VisionImageMetadata que especifique a orientação dos dados de imagem contidos no buffer CMSampleBufferRef .

      Para obter a orientação da imagem:

      Rápido

      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
          }
      }

      Objetivo-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;
        }
      }

      Em seguida, crie o objeto de metadados:

      Rápido

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

      Objetivo-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. Crie um objeto VisionImage usando o objeto CMSampleBufferRef e os metadados de rotação:

      Rápido

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

      Objetivo-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Em seguida, passe a imagem para o método detect(in:) :

    Rápido

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

    Objetivo-C

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

Obtenha informações sobre os pontos de referência reconhecidos

Se o reconhecimento de pontos de referência for bem-sucedido, uma matriz de objetos VisionCloudLandmark será passada para o manipulador de conclusão. De cada objeto você pode obter informações sobre um ponto de referência reconhecido na imagem.

Por exemplo:

Rápido

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
}

Objetivo-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];
}

Próximos passos