Udhëzues për futjen e imazhit për iOS

Detyra MediaPipe Image Embedder ju lejon të konvertoni të dhënat e imazhit në një paraqitje numerike për të përmbushur detyrat e përpunimit të imazhit të lidhura me ML, të tilla si krahasimi i ngjashmërisë së dy imazheve.

Shembulli i kodit i përshkruar në këto udhëzime është i disponueshëm në GitHub . Ju mund ta shihni këtë detyrë në veprim duke parë këtë demonstrim në ueb . Për më shumë informacion rreth aftësive, modeleve dhe opsioneve të konfigurimit të kësaj detyre, shihni Përmbledhjen .

Shembull kodi

Kodi i shembullit të MediaPipe Tasks është një zbatim bazë i një aplikacioni Image Embedder për iOS. Shembulli përdor kamerën në një pajisje fizike iOS për të futur vazhdimisht imazhe, dhe gjithashtu mund të ekzekutojë ngulitësin në skedarët e imazheve nga galeria e pajisjes.

Mund ta përdorni aplikacionin si pikënisje për aplikacionin tuaj iOS ose t'i referoheni kur modifikoni një aplikacion ekzistues. Kodi i shembullit të Image Embedder është pritur në GitHub .

Shkarkoni kodin

Udhëzimet e mëposhtme ju tregojnë se si të krijoni një kopje lokale të kodit shembull duke përdorur mjetin e linjës së komandës git .

Për të shkarkuar kodin shembull:

  1. Klononi depon e git duke përdorur komandën e mëposhtme:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opsionale, konfiguroni shembullin tuaj të git për të përdorur arkëtimin e rrallë, në mënyrë që të keni vetëm skedarët për shembullin e aplikacionit Image Embedder:

    cd mediapipe-samples
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_embedder/ios
    

Pas krijimit të një versioni lokal të kodit shembull, mund të instaloni bibliotekën e detyrave MediaPipe, të hapni projektin duke përdorur Xcode dhe të ekzekutoni aplikacionin. Për udhëzime, shihni Udhëzuesin e konfigurimit për iOS .

Komponentët kryesorë

Skedarët e mëposhtëm përmbajnë kodin vendimtar për shembullin e aplikacionit Image Embedder:

  • ImageEmbedderService.swift : Inicializon Embedder-in e imazhit, trajton zgjedhjen e modelit dhe ekzekuton konkluzionet në të dhënat hyrëse.
  • CameraViewController.swift : Zbaton ndërfaqen e përdoruesit për modalitetin e hyrjes së furnizimit të drejtpërdrejtë të kamerës dhe vizualizon rezultatet.
  • MediaLibraryViewController.swift : Zbaton ndërfaqen e përdoruesit për modalitetin e futjes së imazheve të palëvizshme dhe vizualizon rezultatet.

Konfigurimi

Ky seksion përshkruan hapat kryesorë për konfigurimin e mjedisit tuaj të zhvillimit dhe projekteve të kodit për të përdorur Image Embedder. Për informacion të përgjithshëm mbi konfigurimin e mjedisit tuaj të zhvillimit për përdorimin e detyrave të MediaPipe, duke përfshirë kërkesat e versionit të platformës, shihni udhëzuesin e konfigurimit për iOS .

varësitë

Image Embedder përdor bibliotekën MediaPipeTasksVision , e cila duhet të instalohet duke përdorur CocoaPods. Biblioteka është e pajtueshme me të dy aplikacionet Swift dhe Objective-C dhe nuk kërkon ndonjë konfigurim shtesë specifik për gjuhën.

Për udhëzime për instalimin e CocoaPods në macOS, referojuni udhëzuesit të instalimit të CocoaPods . Për udhëzime se si të krijoni një Podfile me pods-et e nevojshme për aplikacionin tuaj, referojuni Përdorimit të CocoaPods .

Shtoni podin MediaPipeTasksVisionPodfile duke përdorur kodin e mëposhtëm:

target 'MyImageEmbedderApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Nëse aplikacioni juaj përfshin objektiva testimi të njësisë, referojuni Udhëzuesit të konfigurimit për iOS për informacion shtesë mbi konfigurimin e skedarit tuaj Podfile .

Model

Detyra MediaPipe Image Embedder kërkon një model të trajnuar që është në përputhje me këtë detyrë. Për më shumë informacion në lidhje me modelet e trajnuara të disponueshme për Image Embedder, shihni seksionin Modelet .

Zgjidhni dhe shkarkoni një model dhe shtoni atë në drejtorinë e projektit tuaj duke përdorur Xcode. Për udhëzime se si të shtoni skedarë në projektin tuaj Xcode, referojuni Menaxhimi i skedarëve dhe dosjeve në projektin tuaj Xcode .

Përdorni veçorinë BaseOptions.modelAssetPath për të specifikuar shtegun drejt modelit në paketën tuaj të aplikacionit.

Krijo detyrën

Ju mund të krijoni detyrën "Image Embedder" duke thirrur një nga inicializuesit e saj. Inicializuesi ImageEmbedder(options:) pranon vlerat për opsionet e konfigurimit.

Nëse nuk keni nevojë për një Impedder imazhi të inicializuar me opsione të personalizuara të konfigurimit, mund të përdorni iniciatorin ImageEmbedder(modelPath:) për të krijuar një Embedder imazhi me opsionet e paracaktuara. Për më shumë informacion rreth opsioneve të konfigurimit, shihni Përmbledhjen e konfigurimit .

Detyra Image Embedder mbështet 3 lloje të dhënash hyrëse: imazhe statike, skedarë video dhe transmetime video të drejtpërdrejta. Si parazgjedhje, ImageEmbedder(modelPath:) inicializon një detyrë për imazhet statike. Nëse dëshironi që detyra juaj të inicializohet për të përpunuar skedarë video ose transmetime video të drejtpërdrejta, përdorni ImageEmbedder(options:) për të specifikuar modalitetin e ekzekutimit të videos ose transmetimit të drejtpërdrejtë. Modaliteti i transmetimit të drejtpërdrejtë kërkon gjithashtu opsionin shtesë të konfigurimit të imageEmbedderLiveStreamDelegate , i cili i mundëson Embedder-it të imazhit t'i japë delegatit rezultatet e ngulitjes së imazhit në mënyrë asinkrone.

Zgjidhni skedën që korrespondon me modalitetin tuaj të ekzekutimit për të parë se si të krijoni detyrën dhe të ekzekutoni konkluzionet.

Swift

Imazhi

import MediaPipeTasksVision

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = ImageEmbedderOptions()
options.baseOptions.modelAssetPath = modelPath
options.quantize = true
options.l2Normalize = true

let imageEmbedder = try ImageEmbedder(options: options)
    

Video

import MediaPipeTasksVision

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = ImageEmbedderOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video
options.quantize = true
options.l2Normalize = true

let imageEmbedder = try ImageEmbedder(options: options)
    

Transmetim i drejtpërdrejtë

import MediaPipeTasksVision

// Class that conforms to the `ImageEmbedderLiveStreamDelegate` protocol and
// implements the method that the image embedder calls once it finishes
// embedding each input frame.
class ImageEmbedderResultProcessor: NSObject, ImageEmbedderLiveStreamDelegate {

  func imageEmbedder(
    _ imageEmbedder: ImageEmbedder,
    didFinishEmbedding result: ImageEmbedderResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the image embedder result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = ImageEmbedderOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream
options.quantize = true
options.l2Normalize = true

// Assign an object of the class to the `imageEmbedderLiveStreamDelegate`
// property.
let processor = ImageEmbedderResultProcessor()
options.imageEmbedderLiveStreamDelegate = processor

let imageEmbedder = try ImageEmbedder(options: options)
    

Objektivi-C

Imazhi

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPImageEmbedderOptions *options = [[MPPImageEmbedderOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;
options.quantize = YES;
options.l2Normalize = YES;

MPPImageEmbedder *imageEmbedder =
  [[MPPImageEmbedder alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPImageEmbedderOptions *options = [[MPPImageEmbedderOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;
options.quantize = YES;
options.l2Normalize = YES;

MPPImageEmbedder *imageEmbedder =
  [[MPPImageEmbedder alloc] initWithOptions:options error:nil];
    

Transmetim i drejtpërdrejtë

@import MediaPipeTasksVision;

// Class that conforms to the `MPPImageEmbedderLiveStreamDelegate` protocol
// and implements the method that the image embedder calls once it finishes
// embedding each input frame.
@interface APPImageEmbedderResultProcessor : NSObject 

@end

@implementation APPImageEmbedderResultProcessor

-   (void)imageEmbedder:(MPPImageEmbedder *)imageEmbedder
    didFinishEmbeddingWithResult:(MPPImageEmbedderResult *)imageEmbedderResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the image embedder result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPImageEmbedderOptions *options = [[MPPImageEmbedderOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;
options.quantize = YES;
options.l2Normalize = YES;

// Assign an object of the class to the `imageEmbedderLiveStreamDelegate`
// property.
APPImageEmbedderResultProcessor *processor =
  [APPImageEmbedderResultProcessor new];
options.imageEmbedderLiveStreamDelegate = processor;

MPPImageEmbedder *imageEmbedder =
  [[MPPImageEmbedder alloc] initWithOptions:options error:nil];
    

Opsionet e konfigurimit

Kjo detyrë ka opsionet e mëposhtme të konfigurimit për aplikacionet iOS:

Emri i opsionit Përshkrimi Gama e vlerave Vlera e paracaktuar
runningMode Vendos modalitetin e ekzekutimit për detyrën. Image Embedder ka tre mënyra:

IMAGE: Modaliteti për hyrjet e një imazhi të vetëm.

VIDEO: Modaliteti për kornizat e dekoduara të një videoje.

LIVE_STREAM: Modaliteti për një transmetim të drejtpërdrejtë të të dhënave hyrëse, si p.sh. nga një aparat fotografik. Në këtë modalitet, imageEmbedderLiveStreamDelegate duhet të vendoset në një shembull të një klase që zbaton ImageEmbedderLiveStreamDelegate për të marrë rezultatet e futjes së kornizave të imazhit në mënyrë asinkrone.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} {RunningMode.image}
l2Normalize Nëse do të normalizohet vektori i tipareve të kthyera me normën L2. Përdoreni këtë opsion vetëm nëse modeli nuk përmban tashmë një L2_NORMALIZATION TFLite Op. Në shumicën e rasteve, ky është tashmë rasti dhe normalizimi i L2 arrihet në këtë mënyrë përmes përfundimit të TFLite pa pasur nevojë për këtë opsion. Bool e rreme
quantize Nëse futja e kthyer duhet të kuantizohet në bajt nëpërmjet kuantizimit skalar. Përfshirjet supozohen në mënyrë implicite si njësi-normë dhe për këtë arsye çdo dimension është i garantuar të ketë një vlerë në [-1.0, 1.0]. Përdorni opsionin l2Normalize nëse nuk është kështu. Bool e rreme

Kur modaliteti i ekzekutimit është vendosur në transmetim të drejtpërdrejtë, "Image Embedder" kërkon opsionin shtesë të konfigurimit të imageEmbedderLiveStreamDelegate , i cili mundëson që "Image Embedder" të japë rezultatet e ngulitjes së imazhit në mënyrë asinkrone. I deleguari duhet të zbatojë metodën imageEmbedder(_:didFinishEmbedding:timestampInMilliseconds:error:) , të cilën Image Embedder e thërret pas përpunimit të rezultateve të futjes së çdo kornize imazhi hyrëse.

Emri i opsionit Përshkrimi Gama e vlerave Vlera e paracaktuar
imageEmbedderLiveStreamDelegate Aktivizon Image Embedder që të marrë rezultatet e futjes së imazheve në mënyrë asinkrone në modalitetin e transmetimit të drejtpërdrejtë. Klasa, instanca e së cilës është caktuar në këtë veti, duhet të zbatojë metodën imageEmbedder(_:didFinishEmbedding:timestampInMilliseconds:error:) . E pazbatueshme Nuk është vendosur

Përgatitni të dhënat

Ju duhet të konvertoni imazhin ose kornizën hyrëse në një objekt MPImage përpara se ta kaloni atë te "Image Embedder". MPImage mbështet lloje të ndryshme të formateve të imazhit iOS dhe mund t'i përdorë ato në çdo modalitet ekzekutimi për përfundime. Për më shumë informacion rreth MPImage , referojuni MPImage API .

Zgjidhni një format imazhi iOS bazuar në rastin tuaj të përdorimit dhe mënyrën e ekzekutimit që kërkon aplikacioni juaj. MPImage pranon formatet e imazhit UIImage , CVPixelBuffer dhe CMSampleBuffer iOS.

UIIimazh

Formati UIImage është i përshtatshëm për mënyrat e mëposhtme të funksionimit:

  • Imazhet: imazhet nga një grup aplikacioni, galeri përdoruesish ose sistem skedarësh të formatuar si imazhe UIImage mund të konvertohen në një objekt MPImage .

  • Videot: përdorni AVAssetImageGenerator për të nxjerrë kornizat video në formatin CGImage , më pas i konvertoni ato në imazhe 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)
    

Objektivi-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];
    

Shembulli inicializon një MPImage me orientimin e paracaktuar UIImage.Orientation.Up . Mund të inicializoni një MPImage me ndonjë nga vlerat e mbështetura të UIImage.Orientation . Image Embedder nuk mbështet orientime të pasqyruara si .upMirrored , .downMirrored , .leftMirrored , .rightMirrored .

Për më shumë informacion rreth UIImage , referojuni Dokumentacionit të Zhvilluesit të UIImage Apple .

CVPixelBuffer

Formati CVPixelBuffer është i përshtatshëm për aplikacionet që gjenerojnë korniza dhe përdorin kornizën iOS CoreImage për përpunim.

Formati CVPixelBuffer është i përshtatshëm për mënyrat e mëposhtme të funksionimit:

  • Imazhet: aplikacionet që gjenerojnë imazhe CVPixelBuffer pas disa përpunimit duke përdorur kornizën CoreImage të iOS, mund të dërgohen në Embedder i imazhit në modalitetin e ekzekutimit të imazhit.

  • Videot: kornizat e videove mund të konvertohen në formatin CVPixelBuffer për përpunim, dhe më pas të dërgohen në Impedder imazhi në modalitetin e videos.

  • transmetimi i drejtpërdrejtë: aplikacionet që përdorin një kamerë iOS për të gjeneruar korniza mund të konvertohen në formatin CVPixelBuffer për përpunim përpara se të dërgohen në Embedder të imazhit në modalitetin e transmetimit të drejtpërdrejtë.

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)
    

Objektivi-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];
    

Për më shumë informacion rreth CVPixelBuffer , referojuni Dokumentacionit të Zhvilluesit të Apple CVPixelBuffer .

CMSampleBuffer

Formati CMSampleBuffer ruan mostrat e mediave të një lloji uniform të medias dhe është i përshtatshëm për modalitetin e ekzekutimit të transmetimit të drejtpërdrejtë. Kornizat e drejtpërdrejta nga kamerat iOS shpërndahen në mënyrë asinkrone në formatin CMSampleBuffer nga iOS 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)
    

Objektivi-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];
    

Për më shumë informacion rreth CMSampleBuffer , referojuni Dokumentacionit të Zhvilluesit të Apple CMSampleBuffer .

Drejtoni detyrën

Për të ekzekutuar Embedder-in e imazhit, përdorni metodën embed() specifike për modalitetin e caktuar të funksionimit:

  • Imazhi i palëvizshëm: embed(image:)
  • Video: embed(videoFrame:timestampInMilliseconds:)
  • Transmetimi i drejtpërdrejtë: embedAsync(image:timestampInMilliseconds:)

Shembujt e mëposhtëm të kodit tregojnë shembuj bazë se si të ekzekutohet Image Embedder në këto mënyra të ndryshme funksionimi:

Swift

Imazhi

let result = try imageEmbedder.embed(image: image)
    

Video

let result = try imageEmbedder.embed(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Transmetim i drejtpërdrejtë

try imageEmbedder.embedAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objektivi-C

Imazhi

MPPImageEmbedderResult *result =
  [imageEmbedder embedImage:image error:nil];
    

Video

MPPImageEmbedderResult *result =
  [imageEmbedder embedVideoFrame:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Transmetim i drejtpërdrejtë

BOOL success =
  [imageEmbedder embedAsyncImage:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Shembulli i kodit Image Embedder tregon implementimet e secilit prej këtyre mënyrave në më shumë detaje embed(image:) , embed(videoFrame:timestampInMilliseconds:) dhe embedAsync(image:timestampInMilliseconds:) . Kodi shembull i lejon përdoruesit të kalojë ndërmjet mënyrave të përpunimit që mund të mos kërkohen për rastin tuaj të përdorimit.

Vini re sa vijon:

  • Kur ekzekutoni në modalitetin e videos ose në modalitetin e transmetimit të drejtpërdrejtë, duhet të jepni gjithashtu vulën kohore të kornizës së hyrjes në detyrën "Image Embedder".

  • Kur funksionon në modalitetin e imazhit ose të videos, detyra "Image Embedder" bllokon lidhjen aktuale derisa të përfundojë përpunimin e imazhit ose kornizës hyrëse. Për të shmangur bllokimin e fillit aktual, ekzekutoni përpunimin në një fill në sfond duke përdorur kornizat iOS Dispatch ose NSOoperation . Nëse aplikacioni juaj është krijuar duke përdorur Swift, mund të përdorni gjithashtu Swift Concurrency për ekzekutimin e fillit në sfond.

  • Kur ekzekutohet në modalitetin e transmetimit të drejtpërdrejtë, detyra e Impedder-it të imazhit kthehet menjëherë dhe nuk bllokon lidhjen aktuale. Ai thërret metodën imageEmbedder(_:didFinishEmbedding:timestampInMilliseconds:error:) me rezultatet, pas futjes së çdo kornize hyrëse. Embedder-i i imazhit e thërret këtë metodë në mënyrë asinkrone në një radhë të dedikuar dërgimi serik. Për shfaqjen e rezultateve në ndërfaqen e përdoruesit, dërgoni rezultatet në radhën kryesore pas përpunimit të rezultateve. Nëse funksioni embedAsync thirret kur detyra e Image Embedder është e zënë duke përpunuar një kornizë tjetër, Image Embedder injoron kornizën e re hyrëse.

Trajtoni dhe shfaqni rezultatet

Pas ekzekutimit të konkluzionit, Embedder-i i imazhit kthen një objekt ImageEmbedderResult që përmban një listë ngulitjesh (qoftë me pikë lundruese ose të kuantizuara në shkallë) për imazhin e hyrjes.

Më poshtë tregon një shembull të të dhënave dalëse nga kjo detyrë:

ImageEmbedderResult:
  Embedding #0 (sole embedding head):
    float_embedding: {0.0, 0.0, ..., 0.0, 1.0, 0.0, 0.0, 2.0}
    head_index: 0

Ky rezultat u mor duke futur imazhin e mëposhtëm:

Foto mesatare e një mace ekzotike

Ju mund të krahasoni ngjashmërinë e dy futjeve duke përdorur funksionin ImageEmbedder.cosineSimilarity .

Swift

let similarity = try ImageEmbedder.cosineSimilarity(
  embedding1: result.embeddingResult.embeddings[0],
  embedding2: otherResult.embeddingResult.embeddings[0])
    

Objektivi-C

NSNumber *similarity = [MPPImageEmbedder
      cosineSimilarityBetweenEmbedding1:result.embeddingResult.embeddings[0]
                          andEmbedding2:otherResult.embeddingResult.embeddings[0]
                                  error:nil];