Udhëzues për ndarjen e imazheve për Android

Detyra MediaPipe Image Segmenter ju lejon të ndani imazhet në rajone bazuar në kategoritë e paracaktuara për aplikimin e efekteve vizuale të tilla si mjegullimi i sfondit. Këto udhëzime ju tregojnë se si të përdorni Segmenterin e Imazheve me aplikacionet Android. Shembulli i kodit i përshkruar në këto udhëzime është i disponueshëm në GitHub . Për më shumë informacion rreth aftësive, modeleve dhe opsioneve të konfigurimit të kësaj detyre, shihni Përmbledhjen .

Shembull kodi

Shembulli i kodit MediaPipe Tasks përmban dy implementime të thjeshta të një aplikacioni Image Segmenter për Android:

Shembujt përdorin kamerën në një pajisje fizike Android për të kryer segmentimin e imazheve në një furnizim të drejtpërdrejtë të kamerës ose mund të zgjidhni imazhe dhe video nga galeria e pajisjes. Mund t'i përdorni aplikacionet si pikënisje për aplikacionin tuaj Android ose t'u referoheni atyre kur modifikoni një aplikacion ekzistues. Shembulli i kodit të Segmenterit të Imazhit është pritur në GitHub .

Seksionet e mëposhtme i referohen Segmenterit të Imazheve me një aplikacion maskash kategorie .

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 Segmenter:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_segmentation/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ë segmentimit të imazheve:

  • ImageSegmenterHelper.kt - Inicializon detyrën "Imazh Segmenter" dhe trajton përzgjedhjen e modelit dhe delegatit.
  • CameraFragment.kt - Ofron ndërfaqen e përdoruesit dhe kodin e kontrollit për një aparat fotografik.
  • GalleryFragment.kt - Ofron ndërfaqen e përdoruesit dhe kodin e kontrollit për zgjedhjen e skedarëve të imazheve dhe videove.
  • OverlayView.kt - Trajton dhe formaton rezultatet e segmentimit.

Konfigurimi

Ky seksion përshkruan hapat kryesorë për konfigurimin e mjedisit tuaj të zhvillimit dhe projekteve të kodit për të përdorur Segmenterin e imazhit. 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ë

Segmentuesi i imazheve 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 Segmenter 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 Segmenterin e imazheve, 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

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.

kodin e shembullit të segmentit të imazhit, modeli përcaktohet në klasën ImageSegmenterHelper.kt në funksionin setupImageSegmenter() .

Krijo detyrën

Ju mund të përdorni funksionin createFromOptions për të krijuar detyrën. Funksioni createFromOptions pranon opsionet e konfigurimit duke përfshirë llojet e daljes së maskës. Për më shumë informacion mbi konfigurimin e detyrës, shihni Opsionet e konfigurimit .

Detyra "Imazh Segmenter" mbështet llojet e mëposhtme të të dhënave hyrëse: imazhe statike, skedarë video dhe transmetime video të drejtpërdrejta. 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 për llojin tuaj të të dhënave hyrëse për të parë se si ta krijoni atë detyrë.

Imazhi

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

Video

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .build();
imagesegmenter = ImageSegmenter.createFromOptions(context, options);
    

Transmetim i drejtpërdrejtë

ImageSegmenterOptions options =
  ImageSegmenterOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setOutputCategoryMask(true)
    .setOutputConfidenceMasks(false)
    .setResultListener((result, inputImage) -> {
         // Process the segmentation result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the segmentation errors here.
    })
    .build()
imagesegmenter = ImageSegmenter.createFromOptions(context, options)
    

Implementimi i kodit të shembullit të Segmenterit të imazhit lejon përdoruesin të kalojë midis 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ë klasën ImageSegmenterHelper nga funksioni setupImageSegmenter() .

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. Ekzistojnë 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
outputCategoryMask Nëse vendoset në True , dalja përfshin një maskë segmentimi si një imazh uint8, ku çdo vlerë piksel tregon vlerën e kategorisë fituese. { True, False } False
outputConfidenceMasks Nëse vendoset në True , dalja përfshin një maskë segmentimi si një imazh me vlerë notuese, ku çdo vlerë notuese përfaqëson hartën e rezultateve të besimit të kategorisë. { True, False } True
displayNamesLocale Vendos gjuhën e etiketave për t'u përdorur për emrat e shfaqur të dhëna në meta të dhënat e modelit të detyrës, nëse disponohet. Parazgjedhja është en për anglisht. Ju mund të shtoni etiketa të lokalizuara në meta të dhënat e një modeli të personalizuar duke përdorur API-në e shkrimtarit metadata TensorFlow Lite Kodi lokal sq
resultListener Vendos dëgjuesin e rezultateve që të marrë rezultatet e segmentimit në mënyrë asinkrone kur segmentuesi i imazhit është në modalitetin LIVE_STREAM . Mund të përdoret vetëm kur modaliteti i ekzekutimit është caktuar në LIVE_STREAM N/A N/A
errorListener Vendos një dëgjues opsional gabimi. N/A Nuk është vendosur

Përgatitni të dhënat

Segmentuesi i imazheve funksionon 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ë te Segmentuesi i imazhit.

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 Image Segmenter, përgatitja e të dhënave trajtohet në klasën ImageSegmenterHelper nga funksioni segmentLiveStreamFrame() .

Drejtoni detyrën

Ju thërrisni një funksion tjetër segment bazuar në modalitetin e funksionimit që po përdorni. Funksioni "Segmentuesi i imazhit" kthen rajonet e segmentit të identifikuar brenda imazhit ose kornizës hyrëse.

Imazhi

ImageSegmenterResult segmenterResult = imagesegmenter.segment(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.
ImageSegmenterResult segmenterResult =
    imagesegmenter.segmentForVideo(image, frameTimestampMs);
    

Transmetim i drejtpërdrejtë

// Run inference on the frame. The segmentations results will be available via
// the `resultListener` provided in the `ImageSegmenterOptions` when the image
// segmenter was created.
imagesegmenter.segmentAsync(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 "Imazh Segmenter".
  • Kur ekzekutohet në modalitetin e imazhit ose të videos, detyra "Imazh Segmenter" bllokon fillin aktual derisa të përfundojë përpunimin e imazhit ose kornizës hyrëse. Për të shmangur bllokimin e ndërfaqes së përdoruesit, ekzekutoni përpunimin në një fill në sfond.
  • Kur ekzekutohet në modalitetin e transmetimit të drejtpërdrejtë, detyra e Segmenterit 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 segmentAsync thirret kur detyra e Segmenterit të imazhit ë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 të segmentit të imazhit, funksionet segment përcaktohen në skedarin ImageSegmenterHelper.kt .

Trajtoni dhe shfaqni rezultatet

Pas ekzekutimit të konkluzionit, detyra e Segmenterit të imazhit kthen një objekt ImageSegmenterResult i cili përmban rezultatet e detyrës së segmentimit. Përmbajtja e daljes varet nga lloji outputType që keni vendosur kur keni konfiguruar detyrën.

Seksionet e mëposhtme tregojnë shembuj të të dhënave dalëse nga kjo detyrë:

Besimi i kategorisë

Imazhet e mëposhtme tregojnë një vizualizim të rezultatit të detyrës për një maskë besimi të kategorisë. Dalja e maskës së besimit përmban vlerat float midis [0, 1] .

Dy vajza hipur në kalë dhe një vajzë që ecën pranë kalitMaska e imazhit që përshkruan formën e vajzave dhe kalit nga fotografia e mëparshme. Gjysma e majtë e skicës së figurës kapet, por gjysma e djathtë e figurës jo

Dalja origjinale e maskës së besimit të imazhit dhe kategorisë. Imazhi burim nga grupi i të dhënave Pascal VOC 2012 .

Vlera e kategorisë

Imazhet e mëposhtme tregojnë një vizualizim të daljes së detyrës për një maskë me vlerë kategorie. Gama e maskës së kategorisë është [0, 255] dhe çdo vlerë piksel përfaqëson indeksin e kategorisë fituese të prodhimit të modelit. Indeksi i kategorisë fituese ka rezultatin më të lartë midis kategorive që modeli mund të njohë.

Dy vajza hipur në kalë dhe një vajzë që ecën pranë kalitMaska e imazhit që përshkruan formën e vajzave dhe kalit nga imazhi i mëparshëm. Forma e të tre vajzave dhe kalit janë maskuar me saktësi

Dalja origjinale e imazhit dhe maskës së kategorisë. Imazhi burim nga grupi i të dhënave Pascal VOC 2012 .