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. Z tych instrukcji dowiesz się, jak korzystać z zadania Wykrywanie obiektów na iOS. Przykładowy kod opisany w tych instrukcjach jest dostępny na GitHub.
Aby zobaczyć, jak to zadanie działa w praktyce, obejrzyj prezentację internetową. 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 ObjectDetector na iOS. Przykład wykorzystuje aparat 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 tworzenia 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-samplesOpcjonalnie skonfiguruj instancję git do korzystania z rzadkiego sprawdzania, aby mieć tylko pliki przykładowej aplikacji Detector obiektów:
cd mediapipe-samples 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 wprowadzania danych z kamery na żywo i wizualizuje wyniki wykrywania.
- MediaLibraryViewController.swift implementuje interfejs użytkownika dla trybu wprowadzania statycznych obrazów i plików wideo oraz wizualizuje wyniki wykrywania.
Konfiguracja
W tej sekcji opisaliśmy najważniejsze kroki konfiguracji środowiska programistycznego i projektów kodu na potrzeby korzystania z Obiektowego modułu rozpoznawania. Ogólne informacje o konfigurowaniu środowiska programistycznego do korzystania z zadań MediaPipe, w tym wymagania dotyczące wersji platformy, znajdziesz w przewodniku konfiguracji dla iOS.
Zależności
Detektor obiektów korzysta z biblioteki MediaPipeTasksVision, którą należy 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 testów jednostkowych, dodatkowe informacje o konfigurowaniu Podfile znajdziesz w przewodniku konfiguracji na iOS.
Model
Zadanie Wykrywanie 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
Zadaniem wykrywania obiektów możesz utworzyć, wywołując jedną z jego funkcji inicjującej. Inicjalizator ObjectDetector(options:) ustawia wartości opcji konfiguracji, w tym tryb działania, język wyświetlania 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
W tym zadaniu dostępne są 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: OBRAZ: tryb dla pojedynczych obrazów wejściowych. FILM: tryb dekodowanych klatek filmu. LIVE_STREAM: tryb transmisji na żywo danych wejściowych, takich jak dane z kamery. W tym trybie należy wywołać metodę resultListener, aby skonfigurować odbiornik, który będzie asynchronicznie odbierał wyniki. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream} |
RunningMode.image |
displayNamesLocales |
Określa język etykiet, których należy używać do 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 modelu niestandardowego, korzystając z 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 (zwracane są 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 zmiennych typu float | 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 jest wzajemnie wykluczająca się z opcją categoryAllowlist, a użycie obu spowoduje 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 go do usługi Object Detector musisz przekonwertować wejściowy obraz lub ramkę 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
UIImagemożna przekształcić w 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 do 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 generują obrazy
CVPixelBufferpo przetworzeniu ich za pomocą interfejsuCoreImagew iOS, mogą wysyłać je do usługi Object Detector w trybie uruchamiania obrazu.Filmy: ramki wideo można przekształcić w format
CVPixelBufferdo przetwarzania, a następnie wysłać do usługi Object Detector w trybie wideo.transmisja na żywo: aplikacje korzystające z aparatu iOS do generowania klatek mogą być konwertowane do formatu
CVPixelBufferna 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 trybie wideo lub transmisji na żywo musisz też podać sygnaturę czasową ramki wejściowej do zadania Detector obiektów.
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 wykrywania obiektów zwraca wynik 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. Wzorzec do wykrywania obiektów wywołuje tę metodę asynchronicznie na dedykowanej kolejce wysyłania sekwencyjnego. Aby wyświetlić wyniki w interfejsie, prześlij je do kolejki głównej po przetworzeniu. Jeśli funkcjadetectAsynczostanie 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 wejściowym obrazie.
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
Na ilustracji poniżej widać wizualizację wyniku 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.