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 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 podstawowa implementacja aplikacji do klasyfikowania obrazów na iOS. W tym przykładzie do ciągłego klasyfikowania obiektów używana jest kamera na fizycznym urządzeniu z iOS. Można też wykorzystywać obrazy i filmy z galerii urządzenia do statycznego klasyfikowania obiektów.
Możesz użyć tej aplikacji jako punktu wyjścia do tworzenia własnej aplikacji na iOS lub jako odniesienia podczas modyfikowania istniejącej aplikacji. Przykładowy kod Image Classifier 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 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 danych wejściowych.
- CameraViewController.swift: implementuje interfejs użytkownika dla trybu wejścia z kamery na żywo 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 konfigurowania środowiska programistycznego i projektów kodu na potrzeby korzystania 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
Narzędzie do klasyfikowania obrazó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 'MyImageClassifierApp' 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 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. Inicjalizator ImageClassifier(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 klasyfikatora obrazów zainicjowanego za pomocą niestandardowych opcji konfiguracji, możesz użyć funkcji inicjalizacyjnej ImageClassifier(modelPath:)
, aby utworzyć klasyfikator obrazów z opcjami domyślnymi. Więcej informacji o opcjach konfiguracji znajdziesz w artykule Omówienie konfiguracji.
Zadanie klasyfikatora obrazów obsługuje 3 typy danych wejściowych: obrazy, pliki wideo i transmisje 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: 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 |
displayNamesLocale |
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 |
Określa opcjonalną maksymalną liczbę najlepszych wyników klasyfikacji do zwrócenia. Jeśli wartość jest mniejsza od 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 zmiennych typu float | 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 |
Spowoduje, że odbiorca wyników będzie otrzymywać wyniki klasyfikacji asynchronicznie, gdy klasyfikator obrazów będzie w trybie transmisji na żywo. Można go używać tylko wtedy, gdy tryb działania ma wartość 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. Delegate 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 |
Umożliwia klasyfikatorowi obrazów otrzymywanie wyników klasyfikacji asynchronicznie 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
Przed przekazaniem go do usługi Image Classifier 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 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. 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
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
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 CMSampleBuffer
znajdziesz w dokumentacji CMSampleBuffer dla deweloperów Apple.
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ższe przykłady kodu pokazują podstawowe przykłady uruchamiania usługi Image Classifier w tych trybach:
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 w ramach dedykowanej kolejki wysyłania sekwencyjnego. Aby wyświetlić wyniki w interfejsie, prześlij je do kolejki głównej po przetworzeniu. Jeśli funkcjaclassifyAsync
zostanie wywołana, gdy zadanie klasyfikatora obrazów jest zajęte przetwarzaniem innego kadru, klasyfikator obrazów zignoruje nowy wejściowy kadr.
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ład danych wyjściowych z 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świetlać wyniki klasyfikacji zwrócone przez zadanie. Szczegółowe informacje znajdziesz w przykładowym kodzie.