Zadanie segmentacji obrazów pozwala podzielić obrazy na regiony na podstawie wstępnie zdefiniowanych kategorii i stosować efekty wizualne, np. rozmycie tła. Te jak używać segmentacji 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, wejdź na stronę wersji demonstracyjnej. Więcej informacji o funkcjach, modelach i opcjach konfiguracji zapoznaj się z Przegląd.
Przykładowy kod
Przykładowy kod MediaPipe Tasks zawiera prostą implementację Aplikacja Image Segmenter na iOS.
W tym przykładzie zaimplementowane jest segmentowanie obrazów, które zwraca maski kategorii. Wykorzystuje z aparatu na fizycznym urządzeniu z iOS, by segmentować obraz na żywo. z kamery czy na zdjęciach i filmach z galerii urządzenia.
Możesz użyć tej aplikacji jako punktu wyjścia dla własnej aplikacji na iOS lub skorzystać z niej podczas modyfikowania istniejącej aplikacji. Przykładowy kod narzędzia do segmentowania obrazów jest hostowany GitHub
Pobieranie kodu
Poniżej znajdziesz instrukcje tworzenia lokalnej kopii przykładu. 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 możesz skonfigurować instancję git tak, aby wykorzystywała rozproszony proces płatności, aby tylko pliki przykładowej aplikacji Image Segmenter:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_segmentation/ios/
Po utworzeniu lokalnej wersji przykładowego kodu możesz zainstalować w bibliotece zadań MediaPipe, otwórz projekt za pomocą Xcode i uruchom aplikację. Dla: więcej instrukcji znajdziesz w Przewodniku po konfiguracji na iOS.
Kluczowe elementy
Poniższe pliki zawierają kluczowy kod przykładowego narzędzia do segmentowania obrazów aplikacja:
- ImageSegmenterService.swift: Inicjuje segmentację obrazów, obsługuje wybór modelu i uruchamia wnioskowania na danych wejściowych.
- CameraViewController.swift: Implementuje interfejs trybu wprowadzania obrazu z kamery na żywo i wizualizuje wyników.
- MediaLibraryViewController.swift ma interfejs dla trybu wprowadzania zdjęć i filmów oraz i wizualizuje wyniki.
Konfiguracja
W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz w projektach kodu, w których można używać segmentowania obrazów. Ogólne informacje o konfigurowaniu środowisko programistyczne do używania zadań MediaPipe, w tym wersja platformy wymagania znajdziesz w przewodniku konfiguracji dla iOS.
Zależności
Segmentacja obrazów korzysta z biblioteki MediaPipeTasksVision
, którą należy zainstalować
za pomocą CocoaPods. Biblioteka jest zgodna z aplikacjami Swift i Objective-C.
i nie wymaga żadnej dodatkowej konfiguracji.
Instrukcje instalowania CocoaPods w macOS znajdziesz w CocoaPods
przewodnik instalacji.
Aby dowiedzieć się, jak utworzyć Podfile
z podami niezbędnymi dla Twojego
aplikacji można znaleźć w sekcji Korzystanie
CocoaPods.
Dodaj pod MediaPipeTasksVision w tabeli Podfile
przy użyciu tego kodu:
target 'MyImageSegmenterApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
Jeśli Twoja aplikacja zawiera cele testów jednostkowych, zapoznaj się z przewodnikiem po konfiguracji
iOS, gdzie znajdziesz dodatkowe informacje o konfigurowaniu
Podfile
.
Model
Zadanie MediaPipe Image segmenter wymaga wytrenowanego modelu, który jest zgodny. w tym zadaniu. Aby uzyskać więcej informacji o dostępnych wytrenowanych modelach dla Segmentator obrazów, zobacz omówienie zadania Modele .
Wybierz i pobierz model, a następnie dodaj go do katalogu projektu za pomocą Xcode. Instrukcje dodawania plików do projektu Xcode znajdziesz w sekcji Zarządzanie pliki i foldery w Xcode projekt.
Użyj właściwości BaseOptions.modelAssetPath
, aby określić ścieżkę do modelu
w pakiecie aplikacji. Przykładowy kod znajdziesz w następnej sekcji.
Tworzenie zadania
Zadanie segmentacji obrazów możesz utworzyć, wywołując jeden z jego inicjatorów.
Inicjator ImageSegmenter(options:)
akceptuje wartości konfiguracji
.
Jeśli nie potrzebujesz segmentu graficznego zainicjowanego z użyciem niestandardowej konfiguracji
możesz użyć inicjatora ImageSegmenter(modelPath:)
do utworzenia
Segmentacja obrazów z opcjami domyślnymi. Więcej informacji o konfiguracji
Więcej informacji znajdziesz w artykule Omówienie konfiguracji.
Zadanie segmentacji obrazów obsługuje 3 typy danych wejściowych: obrazy i pliki wideo
i transmisje wideo na żywo. Domyślnie ImageSegmenter(modelPath:)
inicjuje
dla nieruchomych obrazów. Jeśli chcesz, aby zadanie zostało zainicjowane do przetworzenia filmu
plików lub transmisji wideo na żywo, użyj właściwości ImageSegmenter(options:)
, aby określić wideo.
czy w trybie biegowym transmisji na żywo. Tryb transmisji na żywo wymaga też dodatkowych
imageSegmenterLiveStreamDelegate
, która włącza
Segmentacja obrazów dostarczana jest przedstawicielowi wyników segmentacji obrazu.
asynchronicznie.
Wybierz kartę odpowiadającą Twojemu trybowi biegowemu, aby zobaczyć, jak utworzyć zadanie i prowadź wnioskowanie.
Swift
Obraz
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false let imageSegmenter = try ImageSegmenter(options: options)
Wideo
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false let imageSegmenter = try ImageSegmenter(options: options)
Transmisja na żywo
import MediaPipeTasksVision // Class that conforms to the `imageSegmenterLiveStreamDelegate` protocol and // implements the method that the image segmenter calls once it finishes // performing segmentation of each input frame. class ImageSegmenterResultProcessor: NSObject, ImageSegmenterLiveStreamDelegate { func imageSegmenter( _ imageSegmenter: ImageSegmenter, didFinishSegmentation result: ImageSegmenterResult?, timestampInMilliseconds: Int, error: Error?) { // Process the image segmentation result or errors here. } } let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false // Set `imageSegmenterLiveStreamDelegate` to the object of the class that // confirms to the `ImageSegmenterLiveStreamDelegate` protocol. let processor = ImageSegmenterResultProcessor() options.imageSegmenterLiveStreamDelegate = processor let imageSegmenter = try ImageSegmenter(options: options)
Objective-C
Obraz
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
Wideo
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
Transmisja na żywo
@import MediaPipeTasksVision; // Class that conforms to the `MPPImageSegmenterLiveStreamDelegate` protocol // and implements the method that the image segmenter calls once it finishes // performing segmentation of each input frame. @interface APPImageSegmenterResultProcessor : NSObject@end @implementation APPImageSegmenterResultProcessor - (void)imageSegmenter:(MPPImageSegmenter *)imageSegmenter didFinishSegmentationWithResult:(MPPImageSegmenterResult *)imageSegmenterResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the image segmentation result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; // Set `imageSegmenterLiveStreamDelegate` to the object of the class that // confirms to the `MPPImageSegmenterLiveStreamDelegate` protocol. APPImageSegmenterResultProcessor *processor = [APPImageSegmenterResultProcessor new]; options.imageSegmenterLiveStreamDelegate = processor; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
Przykładowa implementacja kodu segmentacji obrazów pozwala użytkownikowi przełączać się między i przetwarzania danych. Takie podejście sprawia, że kod tworzenia zadań jest bardziej skomplikowany, może nie być odpowiednia w Twoim przypadku użycia.
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. Są trzy
tryby: IMAGE: tryb wprowadzania pojedynczego obrazu. WIDEO: tryb zdekodowanych klatek filmu. LIVE_STREAM: tryb transmisji danych wejściowych na przykład z kamery. W tym trybie: ImageSegmenterLiveStreamDelegate
musi być ustawiona na instancję klasy, która implementuje
ImageSegmenterLiveStreamDelegate , aby otrzymać segmentację
asynchronicznie.
|
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
shouldOutputCategoryMask |
Jeśli ma wartość True , dane wyjściowe będą zawierały maskę podziału na segmenty.
jako obraz uint8, gdzie każda wartość w pikselach wskazuje zwycięską kategorię
. |
{True, False } |
False |
shouldOutputConfidenceMasks |
Jeśli ma wartość True , dane wyjściowe będą zawierały maskę podziału na segmenty.
jako obraz wartości zmiennoprzecinkowej, gdzie każda wartość zmiennoprzecinkowa odzwierciedla poziom ufności
punktację danej kategorii. |
{True, False } |
True |
displayNamesLocale |
Ustawia język etykiet, które mają być używane w przypadku nazw wyświetlanych w kolumnie
metadane modelu zadania, jeśli są dostępne. Wartość domyślna to en dla
Angielski. Do metadanych modelu niestandardowego możesz dodać zlokalizowane etykiety
za pomocą interfejsu TensorFlow Lite Metadata Writer API. |
Kod języka | en |
result_callback |
Konfiguruje detektor wyników, który ma otrzymywać wyniki podziału na segmenty
asynchronicznie, gdy segmenter obrazów działa w trybie LIVE_STREAM .
Tej opcji można używać tylko wtedy, gdy tryb działania jest ustawiony na LIVE_STREAM |
Nie dotyczy | Nie dotyczy |
Gdy tryb działania jest ustawiony na LIVE_STREAM
, segmenter obrazów wymaga parametru
dodatkowej opcji konfiguracji imageSegmenterLiveStreamDelegate
, która
umożliwia segmentowanie obrazów asynchronicznie.
Przedstawiciel musi zaimplementować
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
,
który wywołuje segmenter obrazu po przetworzeniu wyników
lub segmentację w każdej ramce.
Nazwa opcji | Opis | Zakres wartości | Wartość domyślna |
---|---|---|---|
imageSegmenterLiveStreamDelegate |
Umożliwia segmenterowi obrazów otrzymywanie wyników analizy obrazu
asynchronicznie w trybie transmisji na żywo. Klasa, której instancja jest
ustawiony na tę właściwość musi implementować
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
. |
Nie dotyczy | Nie ustawiono |
Przygotuj dane
Musisz przekonwertować obraz lub ramkę wejściową na obiekt MPImage
przed
i przekazujemy ją do segmentowania obrazów. MPImage
obsługuje różne typy obrazów z iOS
formatów i używać ich w dowolnym trybie działania do wnioskowania. Więcej
informacje na temat marki MPImage
znajdziesz w
Interfejs MPImage API
Wybierz format obrazu na iOS na podstawie swojego przypadku użycia i trybu uruchamiania
wymagane jest zgłoszenie.MPImage
akceptuje UIImage
, CVPixelBuffer
i
CMSampleBuffer
Formaty obrazów w iOS.
UIImage
Format UIImage
sprawdza się w tych trybach biegu:
Obrazy: obrazy z pakietu aplikacji, galerii użytkownika lub systemu plików w formacie Obrazy (
UIImage
) można przekonwertować na obiektMPImage
.Filmy: użyj narzędzia AVAssetImageGenerator. aby wyodrębnić klatki wideo do CGImage a potem przekonwertuj je na
UIImage
obrazy.
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 MPImage
z domyślną wartością
UIImage.Orientation.Up
orientacji ekranu. Możesz zainicjować MPImage
przy użyciu dowolnej z obsługiwanych
UIImage.Orientation
. Segmentacja obrazu nie obsługuje lustrzanych orientacji, takich jak .upMirrored
,
.downMirrored
, .leftMirrored
, .rightMirrored
.
Więcej informacji o UIImage
znajdziesz na stronie UIImage dla deweloperów Apple
Dokumentacja.
CVPixelBuffer
Format CVPixelBuffer
sprawdza się w przypadku aplikacji generujących ramki.
i zastosuj CoreImage na iOS
platformy przetwarzania danych.
Format CVPixelBuffer
sprawdza się w tych trybach biegu:
Obrazy: aplikacje, które po przetworzeniu generują
CVPixelBuffer
obrazy. używając platformyCoreImage
systemu iOS, można wysłać do segmentowania obrazów w funkcji w trybie uruchamiania obrazu.Filmy: klatki wideo można konwertować do formatu
CVPixelBuffer
dla który przetwarza dane, a potem wysyła je do segmentacji obrazu w trybie wideo.transmisja na żywo: aplikacje korzystające z aparatu w iOS do generowania klatek mogą być konwertowane w formacie
CVPixelBuffer
do przetworzenia przed wysłaniem do Segmentowanie 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 tutaj: CVPixelBuffer Apple
Dla programistów
Dokumentacja.
CMSampleBuffer
Format CMSampleBuffer
przechowuje próbki multimediów jednolitego typu mediów i jest
co sprawdza się w trybie biegowym transmisji na żywo. Klatki na żywo z aparatów z iOS są
asynchronicznie dostarczone w formacie CMSampleBuffer
przez iOS
AVCaptureVideoDataOutput (Wyjście 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 tutaj: CMSampleBuffer Apple
Dla programistów
Dokumentacja.
Uruchamianie zadania
Aby uruchomić segmentowanie obrazów, użyj metody segment()
charakterystycznej dla przypisanego
tryb działania:
- Zdjęcie:
segment(image:)
- Film:
segment(videoFrame:timestampInMilliseconds:)
- Transmisja na żywo:
segmentAsync(image:timestampInMilliseconds:)
Poniżej znajdziesz przykładowy kod pokazujący, jak w prosty sposób uruchomić segmentację obrazów w różnych trybach:
Swift
Obraz
let result = try imageSegmenter.segment(image: image)
Wideo
let result = try imageSegmenter.segment( videoFrame: image, timestampInMilliseconds: timestamp)
Transmisja na żywo
try imageSegmenter.segmentAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
Obraz
MPPImageSegmenterResult *result = [imageSegmenter segmentImage:image error:nil];
Wideo
MPPImageSegmenterResult *result = [imageSegmenter segmentVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Transmisja na żywo
BOOL success = [imageSegmenter segmentAsyncImage:image timestampInMilliseconds:timestamp error:nil];
Przykładowy kod segmentacji obrazów pokazuje implementacje każdego z tych trybów
segment(image:)
, więcej informacji
segment(videoFrame:timestampInMilliseconds:)
i
segmentAsync(image:timestampInMilliseconds:)
Pamiętaj:
Korzystając z trybu wideo lub transmisji na żywo, musisz też podać: sygnatura czasowa ramki wejściowej zadania segmentacji obrazów.
W trybie obrazu lub wideo zadanie segmentacji obrazów blokuje w bieżącym wątku aż do zakończenia przetwarzania obrazu lub ramki wejściowej. Do unikaj blokowania bieżącego wątku, uruchamiaj przetwarzanie w tle w iOS na iOS Dispatch lub NSOperation zasad.
W trybie transmisji na żywo zadanie segmentacji obrazów powraca natychmiast. i nie blokuje bieżącego wątku. Wywołuje on metodę
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
za pomocą narzędzia do segmentowania obrazów po przetworzeniu każdej klatki wejściowej. Narzędzie do segmentowania obrazów wywołuje tę metodę asynchronicznie na dedykowanym kolejki wysyłki. Aby wyświetlić wyniki w interfejsie, wyślij do głównej kolejki po przetworzeniu wyników. Jeśli FunkcjasegmentAsync
jest wywoływana, gdy zadanie segmentacji obrazów jest zajęte. podczas przetwarzania kolejnej klatki, segmenter obrazów zignoruje nową.
Obsługa i wyświetlanie wyników
Po przeprowadzeniu wnioskowania zadanie segmentacji obrazów zwraca wartość ImageSegmenterResult
.
który zawiera wyniki zadania segmentacji. Zawartość
zależy od typu danych wyjściowych –
skonfigurowane
danego zadania.
Te obrazy przedstawiają wizualizację danych wyjściowych zadania dla kategorii
maską wartości. Zakres maski kategorii wynosi [0, 255]
i każda wartość piksela
reprezentuje indeks zwycięskiej kategorii danych wyjściowych modelu. Zwycięska kategoria
indeks ma najwyższy wynik spośród kategorii, które model może rozpoznać.
Oryginalny obraz i maska kategorii. Obraz źródłowy z Pascal VOC 2012 w zbiorze danych.
Przykładowy kod segmentacji obrazów pokazuje, jak wyświetlić segmentację obrazów , zobacz kod przykład .