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

Detyra MediaPipe Image Classifier ju lejon të kryeni klasifikimin e imazheve. Ju mund ta përdorni këtë detyrë për të identifikuar se çfarë përfaqëson një imazh midis një grupi kategorish të përcaktuara në kohën e trajnimit. Këto udhëzime ju tregojnë se si të përdorni Klasifikuesin e Imazheve me aplikacionet Android. 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ë demonstrimin 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 i thjeshtë i një aplikacioni të Klasifikimit të Imazheve për Android. Shembulli përdor kamerën në një pajisje fizike Android për të klasifikuar vazhdimisht objektet, dhe gjithashtu mund të përdorë imazhe dhe video nga galeria e pajisjes për të klasifikuar objektet në mënyrë statike.

Mund ta përdorni aplikacionin si pikënisje për aplikacionin tuaj Android ose t'i referoheni kur modifikoni një aplikacion ekzistues. Shembulli i kodit të Klasifikuesit të Imazhit ë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 "Klasifikimi i imazheve":
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_classification/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ë klasifikimit të imazheve:

Konfigurimi

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

Klasifikimi 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 Classifier 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 Klasifikuesin 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ë Klasifikimit të Imazhit, modeli përcaktohet në skedarin ImageClassifierHelper.kt .

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ë modalitetin e ekzekutimit, vendndodhjen e emrave të shfaqur, numrin maksimal të rezultateve, pragun e besimit dhe listën e lejimit ose listës së refuzimit të kategorive. Për më shumë informacion mbi opsionet e konfigurimit, shihni Përmbledhjen e konfigurimit .

Detyra "Klasifikuesi i imazheve" 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

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.IMAGE)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

Video

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.VIDEO)
    .setMaxResults(5)
    .build();
imageClassifier = ImageClassifier.createFromOptions(context, options);
    

Transmetim i drejtpërdrejtë

ImageClassifierOptions options =
  ImageClassifierOptions.builder()
    .setBaseOptions(
      BaseOptions.builder().setModelAssetPath("model.tflite").build())
    .setRunningMode(RunningMode.LIVE_STREAM)
    .setMaxResults(5)
    .setResultListener((result, inputImage) -> {
         // Process the classification result here.
    })
    .setErrorListener((result, inputImage) -> {
         // Process the classification errors here.
    })
    .build()
imageClassifier = ImageClassifier.createFromOptions(context, options)
    

Zbatimi i kodit të shembullit të Klasifikuesit të Imazhit 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 setupImageClassifier() të skedarit ImageClassifierHelper.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. 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
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
maxResults Vendos numrin maksimal opsional të rezultateve të klasifikimit me pikët më të mira për t'u kthyer. Nëse < 0, të gjitha rezultatet e disponueshme do të kthehen. Çdo numër pozitiv -1
scoreThreshold Vendos pragun e rezultatit të parashikimit që tejkalon atë të dhënë në meta të dhënat e modelit (nëse ka). Rezultatet nën këtë vlerë refuzohen. Çdo noton Nuk është vendosur
categoryAllowlist Vendos listën opsionale të emrave të kategorive të lejuara. Nëse nuk janë bosh, rezultatet e klasifikimit emri i kategorisë së të cilave nuk është në këtë grup do të filtrohen. Emrat e kopjuar ose të panjohur të kategorive shpërfillen. Ky opsion është reciprokisht ekskluziv me categoryDenylist dhe duke përdorur të dyja rezulton në një gabim. Çdo varg Nuk është vendosur
categoryDenylist Vendos listën opsionale të emrave të kategorive që nuk lejohen. Nëse nuk janë bosh, rezultatet e klasifikimit emri i kategorisë së të cilave është në këtë grup do të filtrohen. Emrat e kopjuar ose të panjohur të kategorive shpërfillen. Ky opsion është reciprokisht ekskluziv me categoryAllowlist dhe duke përdorur të dyja rezultatet në një gabim. Çdo varg Nuk është vendosur
resultListener Vendos dëgjuesin e rezultateve që të marrë rezultatet e klasifikimit në mënyrë asinkrone kur Klasifikuesi 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

Klasifikuesi i imazheve 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ë te "Klasifikuesi 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 të Klasifikimit të Imazhit, përgatitja e të dhënave trajtohet në skedarin ImageClassifierHelper.kt .

Drejtoni detyrën

Ju mund të telefononi funksionin classify që korrespondon me modalitetin tuaj të drejtimit për të shkaktuar përfundime. API-ja e klasifikuesit të imazhit kthen kategoritë e mundshme për objektin brenda imazhit ose kornizës hyrëse.

Imazhi

ImageClassifierResult classifierResult = imageClassifier.classify(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.
ImageClassifierResult classifierResult =
    imageClassifier.classifyForVideo(image, frameTimestampMs);
    

Transmetim i drejtpërdrejtë

// Run inference on the frame. The classifications results will be available 
// via the `resultListener` provided in the `ImageClassifierOptions` when 
// the image classifier was created.
imageClassifier.classifyAsync(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 "Klasifikimi i imazhit".
  • Kur ekzekutohet në modalitetin e imazhit ose të videos, detyra e Klasifikimit të Imazhit 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 Klasifikimit 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 classifyAsync thirret kur detyra e Klasifikimit 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ë Klasifikimit të Imazhit, funksionet classify përcaktohen në skedarin ImageClassifierHelper.kt .

Trajtoni dhe shfaqni rezultatet

Pas ekzekutimit të përfundimit, detyra e Klasifikimit të Imazhit kthen një objekt ImageClassifierResult i cili përmban listën e kategorive të mundshme për objektet brenda imazhit ose kornizës hyrëse.

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

ImageClassifierResult:
 Classifications #0 (single classification head):
  head index: 0
  category #0:
   category name: "/m/01bwb9"
   display name: "Passer domesticus"
   score: 0.91406
   index: 671
  category #1:
   category name: "/m/01bwbt"
   display name: "Passer montanus"
   score: 0.00391
   index: 670

Ky rezultat është marrë duke ekzekutuar klasifikuesin e shpendëve në:

Fotografi nga afër e një harabeli shtëpie

Në kodin e shembullit të Klasifikimit të Imazhit, klasa ClassificationResultsAdapter në skedarin ClassificationResultsAdapter.kt trajton rezultatet:

fun updateResults(imageClassifierResult: ImageClassifierResult? = null) {
    categories = MutableList(adapterSize) { null }
    if (imageClassifierResult != null) {
        val sortedCategories = imageClassifierResult.classificationResult()
            .classifications()[0].categories().sortedBy { it.index() }
        val min = kotlin.math.min(sortedCategories.size, categories.size)
        for (i in 0 until min) {
            categories[i] = sortedCategories[i]
        }
    }
}