شناسایی و ردیابی اشیاء با کیت ML در iOS

می‌توانید از کیت ML برای شناسایی و ردیابی اشیا در فریم‌های ویدیو استفاده کنید.

هنگامی که تصاویر ML Kit را ارسال می کنید، ML Kit برای هر تصویر، فهرستی از حداکثر پنج شی شناسایی شده و موقعیت آنها در تصویر را برمی گرداند. هنگام شناسایی اشیاء در جریان های ویدیویی، هر شی دارای شناسه ای است که می توانید از آن برای ردیابی شی در بین تصاویر استفاده کنید. همچنین می‌توانید به‌صورت اختیاری طبقه‌بندی اشیاء درشت را فعال کنید، که اشیا را با توضیحات دسته‌بندی گسترده برچسب‌گذاری می‌کند.

قبل از اینکه شروع کنی

  1. اگر قبلاً Firebase را به برنامه خود اضافه نکرده اید، این کار را با دنبال کردن مراحل راهنمای شروع کار انجام دهید.
  2. کتابخانه‌های ML Kit را در فایل پادفایل خود قرار دهید:
    pod 'Firebase/MLVision', '6.25.0'
    pod 'Firebase/MLVisionObjectDetection', '6.25.0'
    
    پس از نصب یا به‌روزرسانی Pods پروژه، حتماً پروژه Xcode خود را با استفاده از .xcworkspace آن باز کنید.
  3. در برنامه خود، Firebase را وارد کنید:

    سریع

    import Firebase

    هدف-C

    @import Firebase;

1. آشکارساز شی را پیکربندی کنید

برای شروع شناسایی و ردیابی اشیاء، ابتدا یک نمونه از VisionObjectDetector ایجاد کنید، به صورت اختیاری تنظیمات آشکارساز را که می خواهید از حالت پیش فرض تغییر دهید، مشخص کنید.

  1. با یک شی VisionObjectDetectorOptions آشکارساز شی را برای مورد استفاده خود پیکربندی کنید. می توانید تنظیمات زیر را تغییر دهید:

    تنظیمات آشکارساز شی
    حالت تشخیص .stream (پیش فرض) | .singleImage

    در حالت استریم (پیش‌فرض)، آشکارساز شی با تأخیر بسیار کم کار می‌کند، اما ممکن است نتایج ناقصی (مانند جعبه‌های مرزی نامشخص یا دسته) در چند فراخوانی اول آشکارساز ایجاد کند. همچنین، در حالت استریم، آشکارساز شناسه های ردیابی را به اشیا اختصاص می دهد که می توانید از آنها برای ردیابی اشیاء در فریم ها استفاده کنید. زمانی که می‌خواهید اشیاء را ردیابی کنید، یا زمانی که تأخیر کم اهمیت دارد، از این حالت استفاده کنید، مانند هنگام پردازش جریان‌های ویدیویی در زمان واقعی.

    در حالت تک تصویری، آشکارساز شی منتظر می‌ماند تا جعبه مرزی یک شی شناسایی شده و دسته‌بندی (اگر طبقه‌بندی را فعال کرده باشید) قبل از بازگرداندن نتیجه در دسترس باشد. در نتیجه، تاخیر تشخیص به طور بالقوه بالاتر است. همچنین در حالت تک تصویر، شناسه های ردیابی تخصیص داده نمی شود. اگر تأخیر حیاتی نیست و نمی‌خواهید با نتایج جزئی مقابله کنید، از این حالت استفاده کنید.

    چندین اشیاء را شناسایی و ردیابی کنید false (پیش فرض) | true

    آیا برای شناسایی و ردیابی حداکثر پنج شی یا فقط برجسته ترین شی (پیش فرض).

    طبقه بندی اشیاء false (پیش فرض) | true

    اینکه آیا اشیاء شناسایی شده در دسته های درشت طبقه بندی شوند یا نه. هنگامی که آشکارساز شیء فعال باشد، اشیاء را به دسته‌های زیر طبقه‌بندی می‌کند: کالاهای مد، غذا، کالاهای خانگی، مکان‌ها، گیاهان و ناشناخته.

    API تشخیص و ردیابی شی برای این دو مورد اصلی بهینه شده است:

    • تشخیص زنده و ردیابی برجسته ترین شی در منظره یاب دوربین
    • تشخیص چندین شی در یک تصویر ثابت

    برای پیکربندی API برای این موارد استفاده:

    سریع

    // Live detection and tracking
    let options = VisionObjectDetectorOptions()
    options.detectorMode = .stream
    options.shouldEnableMultipleObjects = false
    options.shouldEnableClassification = true  // Optional
    
    // Multiple object detection in static images
    let options = VisionObjectDetectorOptions()
    options.detectorMode = .singleImage
    options.shouldEnableMultipleObjects = true
    options.shouldEnableClassification = true  // Optional
    

    هدف-C

    // Live detection and tracking
    FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init];
    options.detectorMode = FIRVisionObjectDetectorModeStream;
    options.shouldEnableMultipleObjects = NO;
    options.shouldEnableClassification = YES;  // Optional
    
    // Multiple object detection in static images
    FIRVisionObjectDetectorOptions *options = [[FIRVisionObjectDetectorOptions alloc] init];
    options.detectorMode = FIRVisionObjectDetectorModeSingleImage;
    options.shouldEnableMultipleObjects = YES;
    options.shouldEnableClassification = YES;  // Optional
    
  2. یک نمونه از FirebaseVisionObjectDetector را دریافت کنید:

    سریع

    let objectDetector = Vision.vision().objectDetector()
    
    // Or, to change the default settings:
    let objectDetector = Vision.vision().objectDetector(options: options)
    

    هدف-C

    FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetector];
    
    // Or, to change the default settings:
    FIRVisionObjectDetector *objectDetector = [[FIRVision vision] objectDetectorWithOptions:options];
    

2. آشکارساز شی را اجرا کنید

برای شناسایی و ردیابی اشیاء، برای هر تصویر یا فریم ویدیو، موارد زیر را انجام دهید. اگر حالت استریم را فعال کرده اید، باید اشیاء VisionImage را از CMSampleBufferRef s ایجاد کنید.

  1. یک شی VisionImage با استفاده از UIImage یا CMSampleBufferRef ایجاد کنید.

    برای استفاده از UIImage :

    1. در صورت لزوم، تصویر را بچرخانید تا ویژگی imageOrientation آن .up باشد.
    2. یک شی VisionImage با استفاده از UIImage با چرخش صحیح ایجاد کنید. هیچ ابرداده چرخشی را مشخص نکنید—مقدار پیش‌فرض، .topLeft . باید استفاده شود.

      سریع

      let image = VisionImage(image: uiImage)

      هدف-C

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

    برای استفاده از CMSampleBufferRef :

    1. یک شی VisionImageMetadata ایجاد کنید که جهت داده های تصویر موجود در بافر CMSampleBufferRef را مشخص می کند.

      برای دریافت جهت تصویر:

      سریع

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

      هدف-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;
        }
      }

      سپس، شی فوق داده را ایجاد کنید:

      سریع

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

      هدف-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. یک شی VisionImage با استفاده از شی CMSampleBufferRef و ابرداده چرخش ایجاد کنید:

      سریع

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

      هدف-C

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  2. VisionImage را به یکی از روش های پردازش تصویر آشکارساز شی منتقل کنید. می توانید از روش process(image:) یا results() استفاده کنید.

    برای تشخیص اشیا به صورت ناهمزمان:

    سریع

    objectDetector.process(image) { detectedObjects, error in
      guard error == nil else {
        // Error.
        return
      }
      guard let detectedObjects = detectedObjects, !detectedObjects.isEmpty else {
        // No objects detected.
        return
      }
    
      // Success. Get object info here.
      // ...
    }
    

    هدف-C

    [objectDetector processImage:image
                      completion:^(NSArray<FIRVisionObject *> * _Nullable objects,
                                   NSError * _Nullable error) {
                        if (error == nil) {
                          return;
                        }
                        if (objects == nil | objects.count == 0) {
                          // No objects detected.
                          return;
                        }
    
                        // Success. Get object info here.
                        // ...
                      }];
    

    برای تشخیص همزمان اشیا:

    سریع

    var results: [VisionObject]? = nil
    do {
      results = try objectDetector.results(in: image)
    } catch let error {
      print("Failed to detect object with error: \(error.localizedDescription).")
      return
    }
    guard let detectedObjects = results, !detectedObjects.isEmpty else {
      print("Object detector returned no results.")
      return
    }
    
    // ...
    

    هدف-C

    NSError *error;
    NSArray<FIRVisionObject *> *objects = [objectDetector resultsInImage:image
                                                                   error:&error];
    if (error == nil) {
      return;
    }
    if (objects == nil | objects.count == 0) {
      // No objects detected.
      return;
    }
    
    // Success. Get object info here.
    // ...
    
  3. اگر فراخوانی پردازشگر تصویر با موفقیت انجام شود، بسته به اینکه روش ناهمزمان یا همزمان را فراخوانی کرده اید، فهرستی از VisionObject را به کنترل کننده تکمیل ارسال می کند یا لیست را برمی گرداند.

    هر VisionObject دارای ویژگی های زیر است:

    frame یک CGRect که موقعیت شی را در تصویر نشان می دهد.
    trackingID یک عدد صحیح که شی را در بین تصاویر شناسایی می کند. صفر در حالت تک تصویر.
    classificationCategory دسته درشت جسم. اگر آشکارساز شی طبقه بندی را فعال نکرده باشد، همیشه .unknown است.
    confidence ارزش اطمینان طبقه بندی شی. اگر آشکارساز شی طبقه‌بندی را فعال نکرده باشد، یا شی به‌عنوان ناشناخته طبقه‌بندی شود، این nil است.

    سریع

    // detectedObjects contains one item if multiple object detection wasn't enabled.
    for obj in detectedObjects {
      let bounds = obj.frame
      let id = obj.trackingID
    
      // If classification was enabled:
      let category = obj.classificationCategory
      let confidence = obj.confidence
    }
    

    هدف-C

    // The list of detected objects contains one item if multiple
    // object detection wasn't enabled.
    for (FIRVisionObject *obj in objects) {
      CGRect bounds = obj.frame;
      if (obj.trackingID) {
        NSInteger id = obj.trackingID.integerValue;
      }
    
      // If classification was enabled:
      FIRVisionObjectCategory category = obj.classificationCategory;
      float confidence = obj.confidence.floatValue;
    }
    

بهبود قابلیت استفاده و عملکرد

برای بهترین تجربه کاربری، این دستورالعمل ها را در برنامه خود دنبال کنید:

  • تشخیص موفق شی به پیچیدگی بصری شی بستگی دارد. اشیاء با تعداد کمی ویژگی بصری ممکن است نیاز داشته باشند که قسمت بزرگتری از تصویر را به خود اختصاص دهند تا شناسایی شوند. شما باید راهنمایی هایی را در مورد گرفتن ورودی به کاربران ارائه دهید که به خوبی با نوع اشیایی که می خواهید شناسایی کنید کار می کند.
  • هنگام استفاده از طبقه‌بندی، اگر می‌خواهید اشیایی را شناسایی کنید که به‌طور واضح در دسته‌های پشتیبانی‌شده قرار نمی‌گیرند، مدیریت خاصی را برای اشیاء ناشناخته اجرا کنید.

همچنین، [ML Kit Material Design showcase app][showcase-link]{: .external } و الگوهای طراحی مواد برای مجموعه ویژگی‌های مبتنی بر یادگیری ماشین را بررسی کنید.

هنگام استفاده از حالت پخش در یک برنامه بلادرنگ، این دستورالعمل ها را برای دستیابی به بهترین نرخ فریم دنبال کنید:

  • از تشخیص چند شی در حالت پخش استفاده نکنید، زیرا اکثر دستگاه‌ها قادر به تولید نرخ فریم مناسب نیستند.

  • اگر به آن نیاز ندارید، طبقه بندی را غیرفعال کنید.

  • دریچه گاز به آشکارساز زنگ می زند. اگر یک قاب ویدیویی جدید در حین کار کردن آشکارساز در دسترس قرار گرفت، قاب را رها کنید.
  • اگر از خروجی آشکارساز برای همپوشانی گرافیک روی تصویر ورودی استفاده می‌کنید، ابتدا نتیجه را از کیت ML بگیرید، سپس تصویر را در یک مرحله رندر کنید و همپوشانی کنید. با انجام این کار، برای هر فریم ورودی تنها یک بار به سطح نمایشگر رندر می دهید. به عنوان مثال، کلاس‌های previewOverlayView و FIRDetectionOverlayView را در برنامه نمونه ویترینی ببینید.