Puoi usare ML Kit per rilevare e tracciare oggetti in fotogrammi video successivi.
Quando passi un'immagine a ML Kit, quest'ultimo rileva fino a cinque oggetti al suo interno insieme alla posizione di ogni oggetto nell'immagine. Durante il rilevamento di oggetti in nei video stream, ogni oggetto ha un ID univoco che puoi utilizzare per monitorarlo da un frame all'altro. Facoltativamente, puoi abilitare l'oggetto approssimativo che etichetta gli oggetti con ampie descrizioni di categorie.
Prova
- Prova l'app di esempio per per vedere un esempio di utilizzo di questa API.
- Visita la Vetrina di Material Design app per un'implementazione end-to-end di questa API.
Prima di iniziare
- Includi i seguenti pod ML Kit nel podfile:
pod 'GoogleMLKit/ObjectDetection', '3.2.0'
- Dopo aver installato o aggiornato i pod del progetto, apri il progetto Xcode utilizzando la relativa
.xcworkspace
. ML Kit è supportato in Xcode versione 12.4 o successiva.
1. configura il rilevatore di oggetti
Per rilevare e monitorare gli oggetti, devi prima creare un'istanza
ObjectDetector
e, facoltativamente, specificare le impostazioni del rilevatore che preferisci
modificare quello predefinito.
Configura il rilevatore di oggetti per il tuo caso d'uso con un
ObjectDetectorOptions
oggetto. Puoi modificare le seguenti opzioni: impostazioni:Impostazioni del rilevatore di oggetti Modalità di rilevamento .stream
(predefinito) |.singleImage
In modalità flusso (impostazione predefinita), il rilevatore di oggetti funziona con un ma potrebbe produrre risultati incompleti (ad esempio, riquadri di delimitazione o categorie) alle prime chiamate di il rilevatore. Inoltre, in modalità stream, il rilevatore assegna il monitoraggio ID agli oggetti, che puoi utilizzare per tenere traccia degli oggetti nei vari frame. Utilizza questa modalità quando vuoi monitorare gli oggetti o in caso di bassa latenza è importante, ad esempio durante l'elaborazione degli stream video nel tempo.
In modalità immagine singola, il rilevatore di oggetti restituisce il risultato dopo aver determinato il riquadro di delimitazione dell'oggetto. Se attivi anche per la classificazione, restituisce il risultato dopo il riquadro di delimitazione sono entrambe disponibili. Di conseguenza, il rilevamento è potenzialmente più alta. Inoltre, in modalità immagine singola, ID non assegnati. Utilizza questa modalità se la latenza non è critica per evitare risultati parziali.
Rilevamento e tracciamento di più oggetti false
(predefinito) |true
Indica se rilevare e tracciare fino a cinque oggetti o solo il più ben visibile (impostazione predefinita).
Classificare gli oggetti false
(predefinito) |true
Indica se classificare o meno gli oggetti rilevati in categorie approssimative. Se abilitato, il rilevatore di oggetti classifica gli oggetti nell'intervallo seguenti categorie: articoli di moda, cibo, casalinghi, luoghi e piante.
L'API di rilevamento e monitoraggio degli oggetti è ottimizzata per questi due usi principali casi:
- Rilevamento e tracciamento in tempo reale dell'oggetto più in evidenza nella videocamera mirino.
- Rilevamento di più oggetti in un'immagine statica.
Per configurare l'API per questi casi d'uso:
Swift
// Live detection and tracking let options = ObjectDetectorOptions() options.shouldEnableClassification = true // Multiple object detection in static images let options = ObjectDetectorOptions() options.detectorMode = .singleImage options.shouldEnableMultipleObjects = true options.shouldEnableClassification = true
Objective-C
// Live detection and tracking MLKObjectDetectorOptions *options = [[MLKObjectDetectorOptions alloc] init]; options.shouldEnableClassification = YES; // Multiple object detection in static images MLKObjectDetectorOptions *options = [[MLKOptions alloc] init]; options.detectorMode = MLKObjectDetectorModeSingleImage; options.shouldEnableMultipleObjects = YES; options.shouldEnableClassification = YES;
- Ottieni un'istanza di
ObjectDetector
:
Swift
let objectDetector = ObjectDetector.objectDetector() // Or, to change the default settings: let objectDetector = ObjectDetector.objectDetector(options: options)
Objective-C
MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetector]; // Or, to change the default settings: MLKObjectDetector *objectDetector = [MLKObjectDetector objectDetectorWithOptions:options];
2. Prepara l'immagine di input
Per rilevare e tracciare oggetti, procedi nel seguente modo per ogni immagine o fotogramma del video.
Se hai abilitato la modalità flusso di dati, devi creare VisionImage
oggetti da
CMSampleBuffer
Crea un oggetto VisionImage
utilizzando un UIImage
o un
CMSampleBuffer
.
Se usi un UIImage
, segui questi passaggi:
- Crea un oggetto
VisionImage
conUIImage
. Assicurati di specificare il valore.orientation
corretto.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Se usi un CMSampleBuffer
, segui questi passaggi:
-
Specifica l'orientamento dei dati dell'immagine contenuti nei
CMSampleBuffer
.Per ottenere l'orientamento dell'immagine:
Swift
func imageOrientation( deviceOrientation: UIDeviceOrientation, cameraPosition: AVCaptureDevice.Position ) -> UIImage.Orientation { switch deviceOrientation { case .portrait: return cameraPosition == .front ? .leftMirrored : .right case .landscapeLeft: return cameraPosition == .front ? .downMirrored : .up case .portraitUpsideDown: return cameraPosition == .front ? .rightMirrored : .left case .landscapeRight: return cameraPosition == .front ? .upMirrored : .down case .faceDown, .faceUp, .unknown: return .up } }
Objective-C
- (UIImageOrientation) imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation cameraPosition:(AVCaptureDevicePosition)cameraPosition { switch (deviceOrientation) { case UIDeviceOrientationPortrait: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored : UIImageOrientationRight; case UIDeviceOrientationLandscapeLeft: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored : UIImageOrientationUp; case UIDeviceOrientationPortraitUpsideDown: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored : UIImageOrientationLeft; case UIDeviceOrientationLandscapeRight: return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored : UIImageOrientationDown; case UIDeviceOrientationUnknown: case UIDeviceOrientationFaceUp: case UIDeviceOrientationFaceDown: return UIImageOrientationUp; } }
- Crea un oggetto
VisionImage
utilizzando il metodoCMSampleBuffer
oggetto e orientamento:Swift
let image = VisionImage(buffer: sampleBuffer) image.orientation = imageOrientation( deviceOrientation: UIDevice.current.orientation, cameraPosition: cameraPosition)
Objective-C
MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer]; image.orientation = [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation cameraPosition:cameraPosition];
3. Elabora l'immagine
PassaVisionImage
a uno dei sistemi di elaborazione delle immagini del rilevatore di oggetti
di machine learning. Puoi utilizzare il metodo process(image:)
asincrono oppure
metodo results()
sincrono.
Per rilevare gli oggetti in modo asincrono:
Swift
objectDetector.process(image) { objects, error in guard error == nil else { // Error. return } guard !objects.isEmpty else { // No objects detected. return } // Success. Get object info here. // ... }
Objective-C
[objectDetector processImage:image completion:^(NSArray* _Nullable objects, NSError * _Nullable error) { if (error == nil) { return; } if (objects.count == 0) { // No objects detected. return; } // Success. Get object info here. }];
Per rilevare gli oggetti in modo sincrono:
Swift
var objects: [Object] do { objects = try objectDetector.results(in: image) } catch let error { print("Failed to detect object with error: \(error.localizedDescription).") return } guard !objects.isEmpty else { print("Object detector returned no results.") return } // Success. Get object info here.
Objective-C
NSError *error; NSArray*objects = [objectDetector resultsInImage:image error:&error]; if (error == nil) { return; } if (objects.count == 0) { // No objects detected. return; } // Success. Get object info here.
4. Recuperare informazioni sugli oggetti rilevati
Se la chiamata al processore di immagini ha esito positivo, passa un elenco diObject
al gestore del completamento o restituisce l'elenco, a seconda del
a seconda che tu abbia chiamato il metodo asincrono o sincrono.
Ogni Object
contiene le seguenti proprietà:
frame |
Un elemento CGRect che indica la posizione dell'oggetto nell'intervallo
dell'immagine. |
trackingID |
Un numero intero che identifica l'oggetto tra le immagini, o "nessuno" in modalità immagine singola. |
labels |
Un array di etichette che descrivono l'oggetto restituito dal rilevatore.
La proprietà è vuota se l'opzione del rilevatore
shouldEnableClassification impostata su false .
|
Swift
// objects contains one item if multiple object detection wasn't enabled. for object in objects { let frame = object.frame let trackingID = object.trackingID // If classification was enabled: let description = object.labels.enumerated().map { (index, label) in "Label \(index): \(label.text), \(label.confidence)" }.joined(separator:"\n") }
Objective-C
// The list of detected objects contains one item if multiple // object detection wasn't enabled. for (MLKObject *object in objects) { CGRect frame = object.frame; NSNumber *trackingID = object.trackingID; for (MLKObjectLabel *label in object.labels) { NSString *labelString = [NSString stringWithFormat: @"%@, %f, %lu", label.text, label.confidence, (unsigned long)label.index]; ... } }
Migliorare l'usabilità e le prestazioni
Per una migliore esperienza utente, segui queste linee guida nella tua app:
- Il successo del rilevamento degli oggetti dipende dalla complessità visiva dell'oggetto. Nella per essere rilevati, gli oggetti con un numero ridotto di caratteristiche visive potrebbero richiedere in modo da occupare una parte più grande dell'immagine. Devi fornire agli utenti indicazioni acquisire input che funzionano bene con il tipo di oggetti che si vuole rilevare.
- Quando usi la classificazione, se vuoi rilevare gli oggetti che non cadono nelle categorie supportate, implementare una gestione speciale per di oggetti strutturati.
Dai un'occhiata anche al Material Design Raccolta di pattern per le funzionalità basate sul machine learning.
Quando utilizzi la modalità flusso di dati in un'applicazione in tempo reale, segui queste linee guida per ottenere le migliori frequenze fotogrammi:
- Non utilizzare il rilevamento di più oggetti in modalità flusso di dati, perché la maggior parte dei dispositivi non essere in grado di produrre frequenze fotogrammi adeguate.
- Disabilita la classificazione se non ti serve.
- Per elaborare i fotogrammi video, utilizza l'API sincrona
results(in:)
del rilevatore. Chiama questo metodo dal diAVCaptureVideoDataOutputSampleBufferDelegate
captureOutput(_, didOutput:from:)
per ottenere in modo sincrono i risultati dal video specificato frame. Mantieni diAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
cometrue
per limitare le chiamate al rilevatore. Se un nuovo il fotogramma video diventa disponibile mentre il rilevatore è in esecuzione, quindi verrà eliminato. - Se utilizzi l'output del rilevatore per sovrapporre elementi grafici l'immagine di input, occorre prima ottenere il risultato da ML Kit, quindi eseguire il rendering dell'immagine e la sovrapposizione in un solo passaggio. In questo modo, visualizzi la pagina solo una volta per ogni frame di input elaborato. Vedi la pagina updatePreviewOverlayViewWithLastFrame. nell'esempio della guida rapida di ML Kit.