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

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. Këto udhëzime ju tregojnë se si të përdorni Embedder-in e imazhit me aplikacionet Android.

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 i thjeshtë i një aplikacioni Image Embedder për Android. Shembulli përdor kamerën në një pajisje fizike Android për të futur vazhdimisht imazhe, dhe gjithashtu mund të ekzekutojë ngulitësin në skedarët e imazheve të ruajtura në pajisje.

Mund ta përdorni aplikacionin si pikënisje për aplikacionin tuaj Android 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
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_embedder/android
    

Pas krijimit të një versioni lokal të kodit shembull, mund ta importoni projektin në Android Studio dhe të ekzekutoni aplikacionin. Për udhëzime, shihni Udhëzuesin e konfigurimit për Android .

Komponentët kryesorë

Skedarët e mëposhtëm përmbajnë kodin vendimtar për këtë aplikacion shembulli të ngulitësit të imazheve:

  • ImageEmbedderHelper.kt : Inicializon ngulitësin e imazhit dhe trajton përzgjedhjen e modelit dhe delegatit.
  • MainActivity.kt : Zbaton aplikacionin dhe monton komponentët e ndërfaqes së përdoruesit.

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 Android .

varësitë

Image Embedder përdor bibliotekën com.google.mediapipe:tasks-vision . Shtoni këtë varësi në skedarin build.gradle të projektit tuaj të zhvillimit të aplikacionit Android. Importoni varësitë e kërkuara me kodin e mëposhtëm:

dependencies {
    ...
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

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 mbi modelet e trajnuara të disponueshme për Image Embedder, shihni seksionin Modelet e përmbledhjes së detyrave.

Zgjidhni dhe shkarkoni modelin dhe më pas ruajeni në direktorinë e projektit tuaj:

<dev-project-root>/src/main/assets

Specifikoni shtegun e modelit brenda parametrit ModelAssetPath . Në kodin e shembullit, modeli përcaktohet në funksionin setupImageEmbedder() në skedarin ImageEmbedderHelper.kt :

Përdorni metodën BaseOptions.Builder.setModelAssetPath() për të specifikuar shtegun e përdorur nga modeli. Kjo metodë është referuar në shembullin e kodit në seksionin tjetër.

Krijo detyrën

Ju mund të përdorni funksionin createFromOptions për të krijuar detyrën. Funksioni createFromOptions pranon opsionet e konfigurimit për të vendosur opsionet e embedder-it. Për më shumë informacion mbi opsionet e 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. Ju duhet të specifikoni mënyrën e ekzekutimit që korrespondon me llojin tuaj të të dhënave hyrëse kur krijoni detyrën. Zgjidhni skedën që korrespondon me llojin tuaj të të dhënave hyrëse për të parë se si të krijoni detyrën dhe të ekzekutoni konkluzionet.

Imazhi

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.IMAGE)
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

Video

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.VIDEO)
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

Transmetim i drejtpërdrejtë

ImageEmbedderOptions options =
  ImageEmbedderOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setQuantize(true)
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setResultListener((result, inputImage) -> {
         // Process the embedding result here.
    })
    .build();
imageEmbedder = ImageEmbedder.createFromOptions(context, options);
    

Implementimi i kodit shembull i lejon përdoruesit të kalojë ndërmjet mënyrave të përpunimit. Qasja e bën kodin e krijimit të detyrës më të komplikuar dhe mund të mos jetë i përshtatshëm për rastin tuaj të përdorimit. Ju mund ta shihni këtë kod në funksionin setupImageEmbedder() në skedarin ImageEmbedderHelper.kt .

Opsionet e konfigurimit

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

Emri i opsionit Përshkrimi Gama e vlerave Vlera e paracaktuar
runningMode Vendos modalitetin e ekzekutimit për detyrën. 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, resultListener duhet të thirret për të vendosur një dëgjues për të marrë rezultatet në mënyrë asinkrone.
{ IMAGE, VIDEO, LIVE_STREAM } IMAGE
l2_normalize 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. Boolean False
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 l2_normalize nëse nuk është kështu. Boolean False
resultListener Vendos dëgjuesin e rezultateve që të marrë rezultatet e ngulitjes në mënyrë asinkrone kur Embedder i imazhit është në modalitetin e transmetimit të drejtpërdrejtë. Mund të përdoret vetëm kur modaliteti i ekzekutimit është caktuar në LIVE_STREAM N/A Nuk është vendosur
errorListener Vendos një dëgjues opsional gabimi. N/A Nuk është vendosur

Përgatitni të dhënat

Image Embedder punon me imazhe, skedarë video dhe video me transmetim të drejtpërdrejtë. Detyra trajton parapërpunimin e hyrjes së të dhënave, duke përfshirë ndryshimin e madhësisë, rrotullimin dhe normalizimin e vlerës.

Ju duhet të konvertoni imazhin ose kornizën hyrëse në një objekt com.google.mediapipe.framework.image.MPImage përpara se ta kaloni atë në detyrën "Image Embedder".

Imazhi

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load an image on the users device as a Bitmap object using BitmapFactory.

// Convert an Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(bitmap).build();
    

Video

import com.google.mediapipe.framework.image.BitmapImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Load a video file on the user's device using MediaMetadataRetriever

// From the videos metadata, load the METADATA_KEY_DURATION and
// METADATA_KEY_VIDEO_FRAME_COUNT value. Youll need them
// to calculate the timestamp of each frame later.

// Loop through the video and load each frame as a Bitmap object.

// Convert the Androids Bitmap object to a MediaPipes Image object.
Image mpImage = new BitmapImageBuilder(frame).build();
    

Transmetim i drejtpërdrejtë

import com.google.mediapipe.framework.image.MediaImageBuilder;
import com.google.mediapipe.framework.image.MPImage;

// Create a CameraXs ImageAnalysis to continuously receive frames
// from the devices camera. Configure it to output frames in RGBA_8888
// format to match with what is required by the model.

// For each Androids ImageProxy object received from the ImageAnalysis,
// extract the encapsulated Androids Image object and convert it to
// a MediaPipes Image object.
android.media.Image mediaImage = imageProxy.getImage()
Image mpImage = new MediaImageBuilder(mediaImage).build();
    

Në kodin e shembullit, përgatitja e të dhënave trajtohet në skedarin ImageEmbedderHelper.kt .

Drejtoni detyrën

Mund të telefononi funksionin embed që korrespondon me modalitetin tuaj të funksionimit për të nxjerrë përfundime. Image Embedder API kthen vektorët e ngulitjes për imazhin ose kornizën hyrëse.

Imazhi

ImageEmbedderResult embedderResult = imageEmbedder.embed(image);
    

Video

// Calculate the timestamp in milliseconds of the current frame.
long frame_timestamp_ms = 1000 * video_duration * frame_index / frame_count;

// Run inference on the frame.
ImageEmbedderResult embedderResult =
    imageEmbedder.embedForVideo(image, frameTimestampMs);
    

Transmetim i drejtpërdrejtë

// Run inference on the frame. The embedding results will be available
// via the `resultListener` provided in the `ImageEmbedderOptions` when
// the image embedder was created.
imageEmbedder.embedAsync(image, frameTimestampMs);
    

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 ekzekutohet në modalitetin e imazhit ose të videos, detyra "Image Embedder" do të bllokojë 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.
  • Kur ekzekutohet në modalitetin e transmetimit të drejtpërdrejtë, detyra e Impedderit të imazhit nuk e bllokon lidhjen aktuale, por kthehet menjëherë. Ai do të thërrasë dëgjuesin e tij të rezultateve me rezultatin e zbulimit sa herë që ka përfunduar përpunimin e një kornize hyrëse. Nëse funksioni embedAsync thirret kur detyra e Image Embedder është e zënë me përpunimin e një kuadri tjetër, detyra e injoron kornizën e re hyrëse.

Në kodin e shembullit, funksioni i embed përcaktohet në skedarin ImageEmbedderHelper.kt .

Trajtoni dhe shfaqni rezultatet

Pas ekzekutimit të konkluzionit, detyra Image Embedder 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 . Shih kodin e mëposhtëm për një shembull.

// Compute cosine similarity.
double similarity = ImageEmbedder.cosineSimilarity(
  result.embeddingResult().embeddings().get(0),
  otherResult.embeddingResult().embeddings().get(0));