Nhận diện địa danh bằng Bộ công cụ học máy trên iOS

Bạn có thể dùng Bộ công cụ học máy để nhận ra các địa danh đã biết trong một hình ảnh.

Trước khi bắt đầu

  1. Nếu bạn chưa thêm Firebase vào ứng dụng của mình, hãy thực hiện bằng cách làm theo hướng dẫn các bước trong hướng dẫn bắt đầu sử dụng.
  2. Thêm các thư viện Bộ công cụ học máy vào Podfile của bạn:
    pod 'Firebase/MLVision', '6.25.0'
    
    Sau khi cài đặt hoặc cập nhật Nhóm của dự án, hãy nhớ mở Xcode dự án bằng .xcworkspace của nó.
  3. Trong ứng dụng của bạn, hãy nhập Firebase:

    Swift

    import Firebase

    Objective-C

    @import Firebase;
  4. Nếu bạn chưa bật API trên đám mây cho dự án của mình, hãy bật bây giờ:

    1. Mở Bộ công cụ học máy trang API của bảng điều khiển Firebase.
    2. Nếu bạn chưa nâng cấp dự án của mình lên Gói giá linh hoạt, hãy nhấp vào Hãy nâng cấp để làm điều này. (Bạn sẽ chỉ được nhắc nâng cấp nếu không có trong Kế hoạch linh hoạt.)

      Chỉ các dự án cấp Blaze mới có thể sử dụng API trên đám mây.

    3. Nếu bạn chưa bật API trên đám mây, hãy nhấp vào Bật API dựa trên đám mây API.

Định cấu hình trình phát hiện điểm mốc

Theo mặc định, trình phát hiện đám mây sử dụng phiên bản ổn định của mô hình và sẽ trả về tối đa 10 kết quả. Nếu bạn muốn thay đổi một trong hai chế độ cài đặt này, hãy chỉ định chúng bằng đối tượng VisionCloudDetectorOptions dưới dạng trong ví dụ sau:

Swift

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

Objective-C

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

Trong bước tiếp theo, hãy truyền VisionCloudDetectorOptions khi bạn tạo đối tượng Trình phát hiện đám mây.

Chạy trình phát hiện mốc

Để nhận dạng địa danh trong hình ảnh, hãy truyền hình ảnh đó dưới dạng UIImage hoặc CMSampleBufferRef vào detect(in:) của VisionCloudLandmarkDetector phương thức:

  1. Nhận một thực thể của 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. Tạo đối tượng VisionImage bằng UIImage hoặc CMSampleBufferRef.

    Cách sử dụng UIImage:

    1. Nếu cần, hãy xoay hình ảnh để imageOrientation.up.
    2. Tạo đối tượng VisionImage bằng chế độ xoay chính xác UIImage Không chỉ định bất kỳ siêu dữ liệu xoay vòng nào—mặc định bạn phải sử dụng giá trị .topLeft.

      Swift

      let image = VisionImage(image: uiImage)

      Objective-C

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

    Cách sử dụng CMSampleBufferRef:

    1. Tạo đối tượng VisionImageMetadata chỉ định của dữ liệu hình ảnh chứa trong Vùng đệm CMSampleBufferRef.

      Cách lấy hướng ảnh:

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

      Sau đó, hãy tạo đối tượng siêu dữ liệu:

      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. Tạo đối tượng VisionImage bằng Đối tượng CMSampleBufferRef và siêu dữ liệu xoay:

      Swift

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

      Objective-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Sau đó, hãy truyền hình ảnh đó vào phương thức 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
      }
    }];

Xem thông tin về các địa danh được công nhận

Nếu tính năng nhận dạng mốc thành công, một mảng VisionCloudLandmark các đối tượng này sẽ được chuyển đến trình xử lý hoàn thành. Từ mỗi đối tượng, bạn có thể lấy được thông tin về địa danh được nhận dạng trong hình ảnh.

Ví dụ:

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

Các bước tiếp theo