Bruk maskinlæring for å gjenkjenne bilder med IBM Watson

Ville det ikke vært bra hvis en Android-app kunne se og forstå omgivelsene sine? Kan du forestille deg hvor mye bedre brukergrensesnittet kan være hvis det kan se på brukerne og umiddelbart kjenne sine aldre, kjønn og følelser? Vel, en slik app kan virke futuristisk, men det er helt gjennomførbart i dag.

Med IBM Watson Visual Recognition-tjenesten er det enklere enn noensinne å lage mobilapper som nøyaktig kan oppdage og analysere objekter i bilder. I denne veiledningen viser jeg deg hvordan du bruker den til å lage en smart Android-app som kan gjette en persons alder og kjønn og identifisere fremtredende objekter på et fotografi.

Forutsetninger

For å kunne følge denne opplæringen må du ha:

  • en IBM Bluemix-konto
  • Android Studio 3.0 Canary 8 eller høyere
  • og en enhet eller emulator som kjører Android 4.4 eller høyere

1. Aktivering av Visual Recognition Service

Som alle Watson-tjenester må også Visual Recognition-tjenesten aktiveres manuelt før den kan brukes i en app. Så logg inn på IBM Bluemix-konsollen og naviger til Tjenester> Watson. På siden som åpnes, trykk på Opprett Watson service knapp.

Fra listen over tilgjengelige tjenester som vises neste, velg Visuell anerkjennelse.

Du kan nå gi et meningsfylt navn til tjenesten og trykke på Skape knapp.

Når tjenesten er klar, genereres en API-nøkkel for den. Du kan vise det ved å åpne Tjenestegodkjenninger fanen og trykke på Se påloggingsinformasjon knapp.

2. Prosjektoppsett

I denne opplæringen bruker vi Watson Java og Android SDKs mens du samhandler med tjenesten Visual Recognition. Vi bruker også Picasso-biblioteket for å hente og vise bilder fra Internett. Legg derfor til følgende gjennomføring avhengigheter til din app modulens build.gradle fil:

implementering 'com.ibm.watson.developer_cloud: visuell anerkjennelse: 3.9.1' implementering 'com.ibm.watson.developer_cloud: android-sdk: 0.4.2' implementering 'com.squareup.picasso: picasso: 2.5.2'

For å kunne kommunisere med Watsons servere, trenger appen din INTERNETT Tillatelse, så be om det i prosjektets AndroidManifest.xml fil.

I tillegg vil appen vi skal skape i dag, trenge tilgang til enhetens kamera og eksterne lagringsmedier, så du må også be om KAMERA og WRITE_EXTERNAL_STORAGE tillatelser.

 

Til slutt legger du til API-nøkkelen for Visual Recognition-tjenesten til strings.xml fil.

a1234567890bcdefe

3. Initialisering av en visuell gjenkjenningsklient

Watson Java SDK avslører alle funksjonene Visual Recognition-tjenesten tilbyr gjennom VisualRecognition klasse. Derfor må du initialisere en forekomst av den ved hjelp av sin konstruktør, som forventer både en versionsdato og API-nøkkelen som sine argumenter.

Når du bruker tjenesten Visual Recognition, vil du vanligvis ta bilder med enhetens kamera. Watson Android SDK har en CameraHelper klassen for å hjelpe deg med å gjøre det. Selv om du ikke trenger det, foreslår jeg at du også initialiserer en forekomst av den inne i aktiviteten din onCreate () metode.

privat VisualRecognition vrClient; privat CameraHelper hjelper; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // Initialiser Visual Recognition-klienten vrClient = ny VisualRecognition (VisualRecognition.VERSION_DATE_2016_05_20, getString (R.string.api_key)); // Initialiser kamerahjelpshjelpen = ny CameraHelper (dette); 

På dette punktet har du alt du trenger for å begynne å analysere bilder med tjenesten.

4. Oppdage objekter

Tjenesten Visual Recognition kan oppdage et stort utvalg av fysiske objekter. Som input, forventer det et rimelig godt opplyst bilde hvis oppløsning er minst 224 x 224 piksler. For nå, la oss bruke enhetskameraet til å ta et slikt bilde.

Trinn 1: Definer en layout

Brukeren må kunne trykke på en knapp for å ta bildet, så aktivitetens layout XML-fil må ha en Knapp widget. Det må også ha a TextView widget for å liste opp objekter som er oppdaget.

Eventuelt kan du kaste inn en Imageview widget for å vise bildet.

I den ovennevnte koden har vi lagt til en hendelseshåndterer på klikk på Knapp widget. Du kan generere en stub for denne widgeten i kode den ved å klikke på lyspæren vist ved siden av den.

offentlig tomgang ta bilde (se visning) // Mer kode her

Trinn 2: Ta et bilde

Du kan ta et bilde ved å bare ringe til CameraHelper objektets dispatchTakePictureIntent () metode, så legg til følgende kode inne i hendelseshandleren:

helper.dispatchTakePictureIntent ();

Ovenstående metode bruker enhetens standard kameraapp for å ta bildet. Det betyr å få tilgang til bildet tatt, du må overstyre aktiviteten din onActivityResult () metode og se etter resultater hvis forespørselskode er REQUEST_IMAGE_CAPTURE. Slik gjør du det:

@Override protected void onActivityResult (int requestCode, int resultCode, Intent data) super.onActivityResult (requestCode, resultCode, data); hvis (requestCode == CameraHelper.REQUEST_IMAGE_CAPTURE) // Mer kode her

Når du har funnet det riktige resultatet, kan du trekke bildet ut av det i form av a bitmap objekt ved hjelp av getBitmap () metode av CameraHelper klasse. Du kan også få den absolutte banen til bildet ved hjelp av getFile () metode. Vi trenger både bitmappen og den absolutte banen, så legg til følgende kode neste:

siste Bitmap photo = helper.getBitmap (resultCode); endelig fil photoFile = helper.getFile (resultCode);

Hvis du valgte å legge til Imageview widget til oppsettet ditt, kan du vise bildet nå ved å sende bitmapet direkte til det setImageBitmap () metode.

ImageView forhåndsvisning = findViewById (R.id.preview); preview.setImageBitmap (foto);

Trinn 3: Klassifiser bildet

For å oppdage elementer i bildet, må du sende bildet som en inngang til klassifisere() metode av VisualRecognition gjenstand. Før du gjør det, må du imidlertid pakke det inn i en ClassifyImagesOptions objekt, som kan opprettes ved hjelp av ClassifyImagesOptions.Builder klasse.

Returneringsverdien til klassifisere() metoden er a ServiceCall objekt, som støtter både synkron og asynkron nettverksforespørsler. For nå, la oss ringe det henrette() metode for å lage en synkron forespørsel. Selvfølgelig, fordi nettverksoperasjoner ikke er tillatt på brukergrensesnittet, må du huske å gjøre det fra en ny tråd.

AsyncTask.execute (new Runnable () @Override public void run () VisualClassification response = vrClient.classify (ny ClassifyImagesOptions.Builder () .images (photoFile) .build ()) .execute (); // Mer kode her );

De klassifisere() Metoden er bygget for å håndtere flere bilder samtidig. Følgelig er responsen en liste over klassifikasjonsdetaljer. Fordi vi for tiden jobber med et enkelt bilde, trenger vi bare det første elementet i listen. Slik kan du få det:

ImageClassification klassifisering = response.getImages (). Get (0); VisualClassifier classifier = klassifisering.getClassifiers (). Get (0);

Tjenesten Visual Recognition behandler hvert element det har oppdaget som en egen klasse av type VisualClassifier.VisualClass. Ved å ringe getClasses () Metode, du kan få en liste over alle klassene.

Hver klasse har blant annet et navn og en tillitsscore som er knyttet til den. Følgende kode viser deg hvordan du går gjennom listen over klasser og viser navnene til bare de som har en score på over 70% i TextView widget.

siste StringBuffer-utgang = ny StringBuffer (); for (VisualClassifier.VisualClass objekt: classifier.getClasses ()) if (object.getScore ()> 0.7f) output.append ("<") .append(object.getName()) .append("> "); runOnUiThread (ny Runnable () @Override public void run () TextView detectedObjects = findViewById (R.id.detected_objects); detectedObjects.setText (output););

Vær oppmerksom på at koden ovenfor bruker runOnUiThread () metode fordi innholdet i TextView widgeten kan bare oppdateres fra brukergrensesnittet.

Hvis du kjører appen nå og tar et bilde, vil du kunne se Watsons bildeklassifisering arbeid.

5. Analyse av ansikter

Tjenesten Visual Recognition har en dedikert metode for å behandle menneskelige ansikter. Det kan bestemme alder og kjønn til en person i et hvilket som helst fotografi. Hvis personen er kjent, kan den også nevne ham eller henne.

Trinn 1: Definer en layout

Analysere ansikter med tjenesten Visual Recognition er ikke så annerledes enn å klassifisere objekter. Så du er fri til å gjenbruke layoutet du opprettet tidligere. Men for å introdusere deg til noen flere funksjoner tjenesten tilbyr, skal jeg lage et nytt layout, denne med en litt annen funksjonalitet.

Denne gangen, i stedet for å ta bilder ved hjelp av kameraet og sende dem til tjenesten, la oss direkte sende en bildeadresse til den. For å la brukeren skrive inn en nettadresse og starte analysen, trenger vår layout en EditText widget og a Knapp widget. Det vil også trenge en TextView widget for å vise resultatene av analysen.

Jeg foreslår at du også legger til en Imageview widget til oppsettet slik at brukeren kan se bildet URL-adressen peker på.

  

Trinn 2: Vis bildet

Inne i klikkhåndtereren på Knapp widget, kan du ringe GetText () metode av EditText widget for å bestemme bildeadressen som brukeren skrev inn. Når du kjenner nettadressen, kan du bare sende den til Picassos laste() og inn i() metoder for å laste ned og vise bildet i Imageview widget.

EditText imageURLInput = findViewById (R.id.image_url); siste streng url = imageURLInput.getText (). toString (); ImageView forhåndsvisning = findViewById (R.id.preview); Picasso.with (denne) .load (url) .into (forhåndsvisning);

Trinn 3: Kjør ansiktsanalyse

For å kjøre ansiktsanalyse på nettadressen, må du bruke detectFaces () metode av VisualRecognition klient. Akkurat som klassifisere() metode, denne metoden har også behov for a VisualRecognitionOptions objekt som sin inngang. 

Fordi du allerede vet hvordan du bruker henrette() Metode for å lage synkrone forespørsler, la oss nå ringe Enqueue () metode i stedet, som går asynkront og trenger tilbakekalling. Følgende kode viser deg hvordan:

vrClient.detectFaces (ny VisualRecognitionOptions.Builder () .url (url) .build ()) .enqueue (ny ServiceCallback() @Override offentlig ugyldig onResponse (DetectedFaces respons) // Mer kode her @Override public void onFailure (Unntak e) );

Som du kan se i koden ovenfor, inne i onResponse () Metode for tilbakeringingsobjektet, du har tilgang til a DetectedFaces objekt, som inneholder en liste over ansiktsanalyseresultater. Fordi vi brukte et enkelt bilde som vår inngang, behøver vi bare det første elementet i listen. Ved å ringe det getFaces () metode, du får en liste over alle Ansikt objekter oppdaget.

Liste ansikter = response.getImages (). get (0) .getFaces ();

Hver Ansikt objektet har et kjønn og aldersgruppe som er tilknyttet det, som kan nås ved å ringe getGender () og getAge () fremgangsmåter.

De getGender () Metoden returnerer faktisk a Kjønn gjenstand. Du må ringe sin egen getGender () metode for å få kjønn som en streng, som enten er "MALE" eller "FEMALE". På samme måte, getAge () Metoden returnerer en Alder gjenstand. Ved å ringe det getMin () og getMax () metoder, kan du bestemme ansiktets omtrentlige alder i år.

Følgende kode viser deg hvordan du går gjennom listen over Ansikt objekter, generer en streng som inneholder kjønnene og alderen til alle ansiktene, og vis den i TextView widget:

String output = ""; for (ansiktsflate: ansikter) output + = "<" + face.getGender().getGender() + ", " + face.getAge().getMin() + " - " + face.getAge().getMax() + " years old>\ n "; TextView personDetails = findViewById (R.id.person_details); personDetails.setText (output);

Her er et resultat for prøveanalyseanalyse:

Konklusjon

Watson Visual Recognition-tjenesten gjør det svært enkelt for deg å lage apps som er klare og klar over omgivelsene. I denne opplæringen lærte du hvordan du bruker den med Watson Java og Android SDK til å oppdage og analysere generiske objekter og ansikter.

For å lære mer om tjenesten, kan du se den offisielle dokumentasjonen.

Og sørg for å sjekke ut noen av våre andre innlegg om maskinlæring her på Envato Tuts+!