Zadanie detektora obiektów umożliwia wykrywanie obecności i lokalizacji wielu klas obiektów. Na przykład detektor obiektów może wykrywać psy na obrazie. Te instrukcje pokazują, jak korzystać z zadania Wykrywacz obiektów w systemie iOS. Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub.
Aby zobaczyć, jak to zadanie działa w praktyce, obejrzyj to demo. Więcej informacji o możliwościach, modelach i opcjach konfiguracji tego zadania znajdziesz w sekcji Przegląd.
Przykładowy kod
Przykładowy kod MediaPipe Tasks to podstawowe wdrożenie aplikacji wykrywającej obiekty na iOS. Przykład wykorzystuje kamerę na fizycznym urządzeniu z iOS, aby nieprzerwanie wykrywać obiekty. Może też używać obrazów i filmów z galerii urządzenia do wykrywania obiektów w sposób statyczny.
Możesz użyć tej aplikacji jako punktu wyjścia do utworzenia własnej aplikacji na iOS lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod usługi Object Detector jest hostowany na GitHub.
Pobieranie kodu
Z tych instrukcji dowiesz się, jak utworzyć lokalną kopię przykładowego kodu za pomocą narzędzia wiersza poleceń git.
Aby pobrać przykładowy kod:
Sklonuj repozytorium Git za pomocą tego polecenia:
git clone https://github.com/google-ai-edge/mediapipe-samples
Opcjonalnie skonfiguruj instancję Git do korzystania z rzadkiego sprawdzania, aby mieć tylko pliki przykładowej aplikacji Detector obiektów:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/object_detection/ios/
Po utworzeniu lokalnej wersji przykładowego kodu możesz zainstalować bibliotekę zadań MediaPipe, otworzyć projekt za pomocą Xcode i uruchomić aplikację. Instrukcje znajdziesz w przewodniku konfiguracji na iOS.
Kluczowe komponenty
Te pliki zawierają kluczowy kod aplikacji przykładowej wykrywacza obiektów:
- ObjectDetectorService.swift inicjalizuje detektor, obsługuje wybór modelu i wykonuje wnioskowanie na podstawie danych wejściowych.
- CameraViewController.swift implementuje interfejs użytkownika w trybie podglądu obrazu z kamery na żywo i wizualizuje wyniki wykrywania.
- MediaLibraryViewController.swift: implementuje interfejs użytkownika w trybie wprowadzania nieruchomych obrazów i plików wideo oraz wyświetla wyniki wykrywania.
Konfiguracja
W tej sekcji opisaliśmy najważniejsze kroki konfigurowania środowiska programistycznego i projektów kodu na potrzeby korzystania z Obiektowego modułu rozpoznawania. Ogólne informacje o konfigurowaniu środowiska programistycznego na potrzeby zadań MediaPipe, w tym o wymaganej wersji platformy, znajdziesz w przewodniku konfiguracji dla iOS.
Zależności
Wykrywacz obiektów używa biblioteki MediaPipeTasksVision
, którą trzeba zainstalować za pomocą CocoaPods. Biblioteka jest zgodna z aplikacją w języku Swift i Objective-C i nie wymaga dodatkowej konfiguracji językowej.
Instrukcje instalacji CocoaPods na macOS znajdziesz w przewodniku instalacji CocoaPods.
Instrukcje tworzenia Podfile
z podstawowymi komponentami potrzebnymi do działania aplikacji znajdziesz w artykule Korzystanie z CocoaPods.
Dodaj podproces MediaPipeTasksVision w pliku Podfile
, używając tego kodu:
target 'MyObjectDetectorApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
Jeśli Twoja aplikacja zawiera cele testu jednostkowego, zapoznaj się z przewodnikiem konfiguracji dla iOS, w którym znajdziesz dodatkowe informacje o konfigurowaniu Podfile
.
Model
Zadanie wykrywania obiektów MediaPipe wymaga wytrenowanego modelu, który jest zgodny z tym zadaniem. Więcej informacji o dostępnych wytrenowanych modelach usługi Object Detector znajdziesz w sekcji „Modele” w omówieniu zadania.
Wybierz i pobierz model, a następnie dodaj go do katalogu projektu za pomocą Xcode. Instrukcje dodawania plików do projektu Xcode znajdziesz w artykule Zarządzanie plikami i folderami w projekcie Xcode.
Użyj właściwości BaseOptions.modelAssetPath
, aby określić ścieżkę do modelu w pakiecie aplikacji. Przykład kodu znajdziesz w następnej sekcji.
Tworzenie zadania
Zadanie Wykrywacz obiektów możesz utworzyć, wywołując jeden z jego inicjatorów. Inicjalizator ObjectDetector(options:)
ustawia wartości opcji konfiguracji, w tym tryb działania, język wyświetlanych nazw, maksymalną liczbę wyników, próg ufności oraz listę dozwolonych i zabronionych kategorii.
Jeśli nie potrzebujesz wzorca do wykrywania obiektów zainicjowanego za pomocą niestandardowych opcji konfiguracji, możesz użyć funkcji inicjalizującej ObjectDetector(modelPath:)
, aby utworzyć wzorzec do wykrywania obiektów z opcjami domyślnymi. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.
Zadanie wykrywania obiektów obsługuje 3 typy danych wejściowych: zdjęcia, pliki wideo i transmisje wideo na żywo. Domyślnie ObjectDetector(modelPath:)
inicjuje zadanie dotyczące obrazów statycznych. Jeśli chcesz, aby zadanie zostało zainicjowane w celu przetwarzania plików wideo lub transmisji na żywo, użyj parametru ObjectDetector(options:)
, aby określić tryb działania związany z odtwarzaniem filmów lub transmisji na żywo. Tryb transmisji na żywo wymaga też dodatkowej opcji konfiguracji objectDetectorLiveStreamDelegate
, która umożliwia detekcja obiektów przesyłanie wyników wykrywania do delegata w trybie asynchronicznym.
Aby dowiedzieć się, jak utworzyć zadanie i przeprowadzić wnioskowanie, wybierz kartę odpowiadającą trybowi działania.
Swift
Obraz
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ObjectDetectorOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.maxResults = 5 let objectDetector = try ObjectDetector(options: options)
Wideo
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ObjectDetectorOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.maxResults = 5 let objectDetector = try ObjectDetector(options: options)
transmisja na żywo
import MediaPipeTasksVision // Class that conforms to the `ObjectDetectorLiveStreamDelegate` protocol and // implements the method that the object detector calls once it // finishes performing detection on each input frame. class ObjectDetectorResultProcessor: NSObject, ObjectDetectorLiveStreamDelegate { func objectDetector( _ objectDetector: ObjectDetector, didFinishDetection objectDetectionResult: ObjectDetectorResult?, timestampInMilliseconds: Int, error: Error?) { // Process the detection result or errors here. } } let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ObjectDetectorOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.maxResults = 5 // Assign an object of the class to the `objectDetectorLiveStreamDelegate` // property. let processor = ObjectDetectorResultProcessor() options.objectDetectorLiveStreamDelegate = processor let objectDetector = try ObjectDetector(options: options)
Objective-C
Obraz
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.maxResults = 5; MPPObjectDetector *objectDetector = [[MPPObjectDetector alloc] initWithOptions:options error:nil];
Wideo
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.maxResults = 5; MPPObjectDetector *objectDetector = [[MPPObjectDetector alloc] initWithOptions:options error:nil];
transmisja na żywo
@import MediaPipeTasksVision; // Class that conforms to the `ObjectDetectorLiveStreamDelegate` protocol and // implements the method that the object detector calls once it // finishes performing detection on each input frame. @interface APPObjectDetectorResultProcessor : NSObject@end @implementation MPPObjectDetectorResultProcessor - (void)objectDetector:(MPPObjectDetector *)objectDetector didFinishDetectionWithResult:(MPPObjectDetectorResult *)ObjectDetectorResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the detection result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPObjectDetectorOptions *options = [[MPPObjectDetectorOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.maxResults = 5; // Assign an object of the class to the `objectDetectorLiveStreamDelegate` // property. APPObjectDetectorResultProcessor *processor = [APPObjectDetectorResultProcessor new]; options.objectDetectorLiveStreamDelegate = processor; MPPObjectDetector *objectDetector = [[MPPObjectDetector alloc] initWithOptions:options error:nil];
Opcje konfiguracji
To zadanie zawiera te opcje konfiguracji aplikacji na iOS:
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
runningMode |
Ustawia tryb działania zadania. Dostępne są 3 tryby: IMAGE: tryb używany do przesyłania pojedynczego obrazu. WIDEO: tryb zdekodowanych klatek filmu. LIVE_STREAM: tryb transmisji na żywo danych wejściowych, takich jak dane z kamery. W tym trybie należy wywołać funkcję resultListener, aby skonfigurować odbiornik umożliwiający asynchroniczne otrzymywanie wyników. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
displayNamesLocales |
Określa język etykiet, które mają być używane w przypadku wyświetlanych nazw podanych w metadanych modelu zadania (jeśli są dostępne). Wartość domyślna to en w przypadku języka angielskiego. Możesz dodawać zlokalizowane etykiety do metadanych niestandardowego modelu za pomocą interfejsu TensorFlow Lite Metadata Writer API.
|
Kod języka | en |
maxResults |
Ustawia opcjonalną maksymalną liczbę wyników wykrywania o najwyższym wyniku, które mają zostać zwrócone. | Dowolne liczby dodatnie | -1 (zostaną zwrócone wszystkie wyniki) |
scoreThreshold |
Ustawia próg wyniku prognozy, który zastępuje próg podany w metadanych modelu (jeśli takie istnieją). Wyniki poniżej tej wartości są odrzucane. | Dowolna liczba | Nie ustawiono |
categoryAllowlist |
Ustawia opcjonalną listę dozwolonych nazw kategorii. Jeśli wyniki wykrywania nie są puste, a nazwa kategorii nie znajduje się w tym zbiorze, zostaną odfiltrowane. Powtarzające się lub nieznane nazwy kategorii są ignorowane.
Ta opcja jest wzajemnie wykluczająca się z opcją categoryDenylist . Użycie obu spowoduje błąd. |
dowolne ciągi znaków; | Nie ustawiono |
categoryDenylist |
Ustawia opcjonalną listę nazw kategorii, które są niedozwolone. Jeśli nie jest pusty, wyniki wykrywania, których nazwa kategorii znajduje się w tym zbiorze, zostaną odfiltrowane. Powtarzające się lub nieznane nazwy kategorii są ignorowane. Ta opcja wyklucza się z metodą categoryAllowlist i jej użycie powoduje błąd. |
dowolne ciągi znaków; | Nie ustawiono |
Konfiguracja transmisji na żywo
Gdy tryb działania jest ustawiony na transmisję na żywo, detektor obiektów wymaga dodatkowej opcji konfiguracji objectDetectorLiveStreamDelegate
, która umożliwia mu przesyłanie wyników wykrywania asynchronicznie. Delegat implementuje metodę objectDetector(_objectDetector:didFinishDetection:timestampInMilliseconds:error:)
, którą Detektor obiektów wywołuje po przetworzeniu wyniku wykrywania dla każdego kadru.
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
objectDetectorLiveStreamDelegate |
Umożliwia detektorowi obiektów asynchroniczne otrzymywanie wyników wykrywania w trybie transmisji na żywo. Klasa, której instancja jest ustawiona w tej właściwości, musi implementować metodę objectDetector(_:didFinishDetection:timestampInMilliseconds:error:) . |
Nie dotyczy | Nie ustawiono |
Przygotuj dane
Przed przekazaniem do usługi Object Detector musisz przekonwertować wejściowy obraz lub kadr na obiekt MPImage
. MPImage
obsługuje różne typy formatów obrazów iOS i może ich używać w dowolnym trybie działania do wnioskowania. Więcej informacji o MPImage
znajdziesz w dokumentacji interfejsu MPImage API.
Wybierz format obrazu iOS na podstawie przypadku użycia i trybułu działania wymaganego przez aplikację. MPImage
obsługuje formaty obrazów iOS UIImage
, CVPixelBuffer
i CMSampleBuffer
.
UIImage
Format UIImage
jest odpowiedni do tych trybów działania:
Obrazy: obrazy z pakietu aplikacji, galerii użytkownika lub systemu plików sformatowane jako obrazy
UIImage
można przekonwertować na obiektMPImage
.Filmy: użyj narzędzia AVAssetImageGenerator, aby wyodrębnić klatki wideo do formatu CGImage, a następnie przekonwertuj je na obrazy
UIImage
.
Swift
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(uiImage: image)
Objective-C
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
Przykład inicjalizuje MPImage
z domyślnym ułożeniem UIImage.Orientation.Up. Możesz zainicjować MPImage
dowolną z obsługiwanych wartości UIImage.Orientation. Detektor obiektów nie obsługuje orientacji lustrzanej, takiej jak .upMirrored
,
.downMirrored
, .leftMirrored
, .rightMirrored
.
Więcej informacji o UIImage
znajdziesz w dokumentacji UIImage dla deweloperów Apple.
CVPixelBuffer
Format CVPixelBuffer
jest odpowiedni dla aplikacji, które generują klatki i korzystają z ramy CoreImage na iOS do przetwarzania.
Format CVPixelBuffer
jest odpowiedni do tych trybów działania:
Obrazy: aplikacje, które po przetworzeniu generują obrazy
CVPixelBuffer
przy użyciu platformyCoreImage
iOS, mogą być wysyłane do wykrywacza obiektów w trybie uruchamiania obrazów.Filmy: ramki wideo można przekształcić w format
CVPixelBuffer
do przetwarzania, a następnie wysłać do usługi Object Detector w trybie wideo.transmisja na żywo: aplikacje korzystające z kamery iOS do generowania klatek mogą być konwertowane do formatu
CVPixelBuffer
na potrzeby przetwarzania przed wysłaniem do usługi Detector obiektów w trybie transmisji na żywo.
Swift
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(pixelBuffer: pixelBuffer)
Objective-C
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
Więcej informacji o CVPixelBuffer
znajdziesz w dokumentacji dla deweloperów Apple dotyczącej CVPixelBuffer.
CMSampleBuffer
Format CMSampleBuffer
przechowuje próbki multimediów o jednolitym typie i jest odpowiedni do uruchamiania transmisji na żywo. Ramki na żywo z kamer iOS są asynchronicznie dostarczane w formacie CMSampleBuffer
przez AVCaptureVideoDataOutput.
Swift
// Obtain a CMSampleBuffer. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(sampleBuffer: sampleBuffer)
Objective-C
// Obtain a `CMSampleBuffer`. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
Więcej informacji o CMSampleBuffer
znajdziesz w dokumentacji CMSampleBuffer dla deweloperów Apple.
Uruchamianie zadania
Aby uruchomić detektor obiektów, użyj metody detect()
odpowiedniej do przypisanego trybu działania:
- Statyczny obraz:
detect(image:)
- Film:
detect(videoFrame:timestampInMilliseconds:)
- livestream:
detectAsync(image:)
Poniższe przykłady kodu pokazują podstawowe przykłady uruchamiania modułu Detektor obiektów w tych trybach:
Swift
Obraz
let objectDetector.detect(image:image)
Wideo
let objectDetector.detect(videoFrame:image)
transmisja na żywo
let objectDetector.detectAsync(image:image)
Objective-C
Obraz
MPPObjectDetectorResult *result = [objectDetector detectInImage:image error:nil];
Wideo
MPPObjectDetectorResult *result = [objectDetector detectInVideoFrame:image timestampInMilliseconds:timestamp error:nil];
transmisja na żywo
BOOL success = [objectDetector detectAsyncInImage:image timestampInMilliseconds:timestamp error:nil];
Przykład kodu detektora obiektów pokazuje szczegółowo implementację każdego z tych trybów: detect(image:)
, detect(videoFrame:)
i detectAsync(image:)
. Przykładowy kod umożliwia użytkownikowi przełączanie się między trybami przetwarzania, które mogą nie być wymagane w Twoim przypadku.
Pamiętaj:
W przypadku działania w trybie wideo lub w trybie transmisji na żywo musisz też podać w zadaniu Wykrywacz obiektów sygnaturę czasową klatki wejściowej.
W trybie obrazu lub filmu zadanie wykrywania obiektów blokuje bieżący wątek, dopóki nie zakończy przetwarzania obrazu wejściowego lub klatki. Aby uniknąć blokowania bieżącego wątku, przeprowadź przetwarzanie w wątku tła za pomocą frameworków iOS Dispatch lub NSOperation.
W trybie transmisji na żywo zadanie Wykrywacz obiektów jest zwracane natychmiast i nie blokuje bieżącego wątku. Po przetworzeniu każdego kadru wejściowego wywołuje metodę
objectDetector(_objectDetector:didFinishDetection:timestampInMilliseconds:error:)
z wynikiem wykrywania. Wykrywacz obiektów asynchronicznie wywołuje tę metodę w dedykowanej kolejce szeregowej wywołań. Aby wyświetlać wyniki w interfejsie, po przetworzeniu wyników wysyłaj je do głównej kolejki. Jeśli funkcjadetectAsync
zostanie wywołana, gdy zadanie wykrywacza obiektów jest zajęte przetwarzaniem innego kadru, wykrywacz obiektów zignoruje nowy klatka wejściowa.
Obsługa i wyświetlanie wyników
Po przeprowadzeniu wnioskowania zadanie Wykrywanie obiektów zwraca obiekt ObjectDetectorResult
, który opisuje obiekty znalezione na obrazie wejściowym.
Poniżej znajdziesz przykład danych wyjściowych z tego zadania:
ObjectDetectorResult:
Detection #0:
Box: (x: 355, y: 133, w: 190, h: 206)
Categories:
index : 17
score : 0.73828
class name : dog
Detection #1:
Box: (x: 103, y: 15, w: 138, h: 369)
Categories:
index : 17
score : 0.73047
class name : dog
Ten obraz przedstawia wizualizację danych wyjściowych zadania:
Przykładowy kod usługi Object Detector pokazuje, jak wyświetlać wyniki wykrywania zwrócone przez zadanie. Szczegółowe informacje znajdziesz w przykładowym kodzie.