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:
- Klononi depon e git duke përdorur komandën e mëposhtme:
git clone https://github.com/google-ai-edge/mediapipe-samples
- 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 user’s device as a Bitmap object using BitmapFactory. // Convert an Android’s Bitmap object to a MediaPipe’s 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 video’s metadata, load the METADATA_KEY_DURATION and // METADATA_KEY_VIDEO_FRAME_COUNT value. You’ll need them // to calculate the timestamp of each frame later. // Loop through the video and load each frame as a Bitmap object. // Convert the Android’s Bitmap object to a MediaPipe’s 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 CameraX’s ImageAnalysis to continuously receive frames // from the device’s camera. Configure it to output frames in RGBA_8888 // format to match with what is required by the model. // For each Android’s ImageProxy object received from the ImageAnalysis, // extract the encapsulated Android’s Image object and convert it to // a MediaPipe’s 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:
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));