Zadanie Klasyfikator obrazów umożliwia klasyfikowanie obrazów. Za pomocą tego zadania możesz określić, co przedstawia obraz spośród zestawu kategorii zdefiniowanych w czasie szkolenia. Te instrukcje pokazują, jak korzystać z klasyfikatora obrazów w aplikacjach na 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 podstawowa implementacja aplikacji do klasyfikowania obrazów na iOS. W tym przykładzie do ciągłej klasyfikacji obiektów używana jest kamera na fizycznym urządzeniu z iOS. Można też używać obrazów i filmów z galerii urządzenia do statycznej klasyfikacji obiektów.
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 klasyfikatora obrazów 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, aby używać selektywnego sprawdzania, dzięki czemu będziesz mieć tylko pliki przykładowej aplikacji Image Classifier:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_classification/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 Klasyfikator obrazów:
- ImageClassifierService.swift inicjalizuje klasyfikator obrazów, obsługuje wybór modelu i wykonuje wnioskowanie na podstawie danych wejściowych.
- CameraViewController.swift: realizuje interfejs użytkownika dla trybu wejścia z obrazu na żywo z kamery i wizualizuje wyniki.
- MediaLibraryViewController.swift: implementuje interfejs użytkownika dla trybu wprowadzania statycznych obrazów i plików wideo oraz wizualizuje wyniki.
Konfiguracja
W tej sekcji opisaliśmy najważniejsze kroki konfiguracji środowiska programistycznego i projektów kodu, które umożliwiają korzystanie z klasyfikatora obrazów. 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
Image Classifier korzysta z 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 'MyImageClassifierApp' 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 MediaPipe Image Classifier wymaga wytrenowanego modelu, który jest zgodny z tym zadaniem. Więcej informacji o dostępnych wytrenowanych modelach usługi Image Classifier 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 klasyfikatora obrazów możesz utworzyć, wywołując jedną z jego funkcji inicjujących. Inicjator ImageClassifier(options:)
ustawia wartości opcji konfiguracji, w tym tryb działania, język nazw wyświetlanych, maksymalną liczbę wyników, próg ufności, listę dozwolonych kategorii i listę odrzuconych.
Jeśli nie potrzebujesz klasyfikatora obrazów zainicjowanego z niestandardowymi opcjami konfiguracji, możesz użyć inicjatora ImageClassifier(modelPath:)
, aby utworzyć klasyfikator obrazów z opcjami domyślnymi. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.
Zadanie Klasyfikator obrazów obsługuje 3 typy danych wejściowych: obrazy, pliki wideo i strumieni wideo na żywo. Domyślnie ImageClassifier(modelPath:)
inicjuje zadanie dotyczące obrazów statycznych. Jeśli chcesz, aby zadanie było inicjowane w celu przetwarzania plików wideo lub transmisji na żywo, użyj parametru ImageClassifier(options:)
, aby określić tryb działania związany z odtwarzaniem filmów lub transmisji na żywo. Tryb transmisji na żywo wymaga również dodatkowej opcji konfiguracji imageClassifierLiveStreamDelegate
, która umożliwia klasyfikatorowi obrazów asynchroniczne przesyłanie wyników klasyfikacji obrazów do delegowanego procesu.
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 = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.maxResults = 5 let imageClassifier = try ImageClassifier(options: options)
Wideo
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.maxResults = 5 let imageClassifier = try ImageClassifier(options: options)
Transmisja na żywo
import MediaPipeTasksVision // Class that conforms to the `ImageClassifierLiveStreamDelegate` protocol and // implements the method that the image classifier calls once it // finishes performing classification on each input frame. class ImageClassifierResultProcessor: NSObject, ImageClassifierLiveStreamDelegate { func imageClassifier( _ imageClassifier: ImageClassifier, didFinishClassification result: ImageClassifierResult?, timestampInMilliseconds: Int, error: Error?) { // Process the image classifier result or errors here. } } let modelPath = Bundle.main.path( forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.maxResults = 5 // Assign an object of the class to the `imageClassifierLiveStreamDelegate` // property. let processor = ImageClassifierResultProcessor() options.imageClassifierLiveStreamDelegate = processor let imageClassifier = try ImageClassifier(options: options)
Objective-C
Obraz
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.maxResults = 5; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
Wideo
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.maxResults = 5; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
Transmisja na żywo
@import MediaPipeTasksVision; // Class that conforms to the `MPPImageClassifierLiveStreamDelegate` protocol // and implements the method that the image classifier calls once it finishes // performing classification on each input frame. @interface APPImageClassifierResultProcessor : NSObject@end @implementation APPImageClassifierResultProcessor - (void)imageClassifier:(MPPImageClassifier *)imageClassifier didFinishClassificationWithResult:(MPPImageClassifierResult *)imageClassifierResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the image classifier result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.maxResults = 5; // Assign an object of the class to the `imageClassifierLiveStreamDelegate` // property. APPImageClassifierResultProcessor *processor = [APPImageClassifierResultProcessor new]; options.imageClassifierLiveStreamDelegate = processor; MPPImageClassifier *imageClassifier = [[MPPImageClassifier 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: IMAGE: tryb używany do przesyłania pojedynczego obrazu. FILM: tryb dekodowanych klatek filmu. TRANSMISJA NA ŻYWO: tryb transmisji danych wejściowych, np. 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 |
displayNamesLocale |
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 |
Określa opcjonalną maksymalną liczbę najlepszych wyników klasyfikacji do zwrócenia. Jeśli wartość jest mniejsza niż 0, zwracane są wszystkie dostępne wyniki. | dowolne liczby dodatnie, | -1 |
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 zmiennoprzecinkowa | Nie ustawiono |
categoryAllowlist |
Ustawia opcjonalną listę dozwolonych nazw kategorii. Jeśli wyniki klasyfikacji 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 klasyfikacji, 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 |
resultListener |
Konfiguruje detektor wyników tak, aby asynchronicznie otrzymywał wyniki klasyfikacji, gdy klasyfikator obrazów jest w trybie transmisji na żywo. Tej opcji można używać tylko wtedy, gdy tryb działania jest ustawiony na LIVE_STREAM |
Nie dotyczy | Nie ustawiono |
Konfiguracja transmisji na żywo
Gdy tryb działania jest ustawiony na „Transmisja na żywo”, klasyfikator obrazów wymaga dodatkowej opcji konfiguracji imageClassifierLiveStreamDelegate
, która umożliwia asynchroniczne dostarczanie wyników klasyfikacji. Delegat implementuje metodę imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)
, którą Klasyfikator obrazów wywołuje po przetworzeniu wyników klasyfikacji dla każdego kadru.
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
imageClassifierLiveStreamDelegate |
Włącza klasyfikator obrazów, aby asynchronicznie otrzymywać wyniki klasyfikacji w trybie transmisji na żywo. Klasa, której instancja jest ustawiona w tej właściwości, musi implementować metodę imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) . |
Nie dotyczy | Nie ustawiono |
Przygotuj dane
Musisz przekonwertować obraz lub ramkę wejściową na obiekt MPImage
, zanim przekażesz go do klasyfikatora obrazów. 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 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];
Ten przykład inicjuje obiekt MPImage
z domyślną orientacją UIImage.Orientation.Up. Możesz zainicjować MPImage
dowolną z obsługiwanych wartości UIImage.Orientation. Klasyfikator obrazó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
sprawdza się w aplikacjach, które generują ramki i wykorzystują do przetwarzania platformę CoreImage na iOS.
Format CVPixelBuffer
sprawdza się w tych trybach biegu:
Obrazy: aplikacje, które generują obrazy
CVPixelBuffer
po przetworzeniu ich za pomocą interfejsuCoreImage
w iOS, mogą wysyłać je do klasyfikatora obrazów w trybie uruchamiania obrazu.Filmy: ramki wideo można przekształcić w format
CVPixelBuffer
do przetwarzania, a następnie wysłać do usługi Image Classifier w trybie wideo.transmisja na żywo: aplikacje korzystające z aparatu iOS do generowania klatek mogą zostać przekonwertowane do formatu
CVPixelBuffer
w celu przetworzenia, zanim zostaną wysłane do klasyfikatora obrazó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 właściwości CMSampleBuffer
znajdziesz w dokumentacji dla programistów Apple CMSampleBuffer.
Uruchamianie zadania
Aby uruchomić klasyfikator obrazów, użyj metody classify()
odpowiedniej do przypisanego trybu działania:
- Statyczny obraz:
classify(image:)
- Film:
classify(videoFrame:timestampInMilliseconds:)
- livestream:
classifyAsync(image:timestampInMilliseconds:)
Usługa Image Classifier zwraca możliwe kategorie obiektu na obrazie lub w ramce wejściowej.
Poniżej znajdziesz przykładowy kod pokazujący, jak uruchomić klasyfikator obrazów w różnych trybach działania:
Swift
Obraz
let result = try imageClassifier.classify(image: image)
Wideo
let result = try imageClassifier.classify( videoFrame: image, timestampInMilliseconds: timestamp)
Transmisja na żywo
try imageClassifier.classifyAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
Obraz
MPPImageClassifierResult *result = [imageClassifier classifyImage:image error:nil];
Wideo
MPPImageClassifierResult *result = [imageClassifier classifyVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Transmisja na żywo
BOOL success = [imageClassifier classifyAsyncImage:image timestampInMilliseconds:timestamp error:nil];
Przykładowy kod usługi klasyfikacji obrazów zawiera szczegółowe informacje o wdrożeniu każdego z tych trybów: classify(image:)
, classify(videoFrame:timestampInMilliseconds:)
i classifyAsync(image:timestampInMilliseconds:)
. 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ć znacznik czasu ramki wejściowej zadaniu Klasyfikator obrazów.
W trybie obrazu lub filmu zadanie klasyfikatora obrazów blokuje bieżący wątek, dopóki nie zakończy przetwarzania wejściowego obrazu 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 klasyfikatora obrazów zwraca wynik natychmiast i nie blokuje bieżącego wątku. Po przetworzeniu każdego wejściowego obrazu wywołuje metodę
imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)
z wynikiem klasyfikacji. Klasyfikator obrazów wywołuje tę metodę asynchronicznie z dedykowanej kolejki szeregowej wysyłania. Aby wyświetlać wyniki w interfejsie, po ich przetworzeniu prześlij wyniki do głównej kolejki. Jeśli funkcjaclassifyAsync
zostanie wywołana, gdy zadanie klasyfikatora obrazów jest zajęte przetwarzaniem innego kadru, klasyfikator obrazów zignoruje nowy klatka wejściowy.
Obsługa i wyświetlanie wyników
Po przeprowadzeniu wnioskowania zadanie klasyfikacji obrazu zwraca obiekt ImageClassifierResult
, który zawiera listę możliwych kategorii obiektów na obrazie lub klatce wejściowej.
Poniżej znajdziesz przykładowe dane wyjściowe tego zadania:
ImageClassifierResult:
Classifications #0 (single classification head):
head index: 0
category #0:
category name: "/m/01bwb9"
display name: "Passer domesticus"
score: 0.91406
index: 671
category #1:
category name: "/m/01bwbt"
display name: "Passer montanus"
score: 0.00391
index: 670
Ten wynik został uzyskany przez uruchomienie Klasyfikatora ptaków w przypadku:
Przykładowy kod klasyfikatora obrazów pokazuje, jak wyświetlić wyniki klasyfikacji zwrócone przez zadanie. Szczegóły znajdziesz w przykładowym kodzie.