Gebruik Machine Learning om afbeeldingen te herkennen met IBM Watson

Zou het niet geweldig zijn als een Android-app de omgeving zou kunnen zien en begrijpen? Kun je je voorstellen hoe veel beter de gebruikersinterface zou kunnen zijn als het naar de gebruikers zou kunnen kijken en onmiddellijk hun leeftijden, geslachten en emoties zou kennen? Nou, zo'n app lijkt misschien futuristisch, maar het is vandaag helemaal te doen.

Met de IBM Watson Visual Recognition-service is het maken van mobiele apps die objecten in afbeeldingen nauwkeurig kunnen detecteren en analyseren, eenvoudiger dan ooit. In deze zelfstudie laat ik je zien hoe je deze kunt gebruiken om een ​​slimme Android-app te maken die iemands leeftijd en geslacht kan raden en prominente objecten op een foto kan identificeren.

voorwaarden

Om deze tutorial te kunnen volgen, moet u beschikken over:

  • een IBM Bluemix-account
  • Android Studio 3.0 Canary 8 of hoger
  • en een apparaat of emulator met Android 4.4 of hoger

1. De Visual Recognition-service activeren

Zoals alle Watson-services moet ook de Visual Recognition-service handmatig worden geactiveerd voordat deze in een app kan worden gebruikt. Dus log in op de IBM Bluemix-console en navigeer naar Diensten> Watson. Druk op de pagina die wordt geopend op Maak een Watson-service knop.

Kies uit de lijst met beschikbare services die hierna wordt weergegeven Visuele herkenning.

U kunt nu een betekenisvolle naam aan de service geven en op de creëren knop.

Zodra de service gereed is, wordt er een API-sleutel voor gegenereerd. U kunt het bekijken door de. Te openen Serviceformulieren tab en druk op de Bekijk legitimatiegegevens knop.

2. Projectinstellingen

In deze zelfstudie gebruiken we de Watson Java- en Android SDK's tijdens de interactie met de Visual Recognition-service. We zullen ook de Picasso-bibliotheek gebruiken om afbeeldingen van internet te halen en weer te geven. Voeg daarom het volgende toe implementatie afhankelijkheden van uw app module build.gradle het dossier:

implementatie 'com.ibm.watson.developer_cloud: visuele herkenning: 3.9.1' implementatie 'com.ibm.watson.developer_cloud: android-sdk: 0.4.2' implementatie 'com.squareup.picasso: picasso: 2.5.2'

Om de Watson-servers te kunnen gebruiken, heeft uw app de INTERNET toestemming, dus vraag ernaar in uw project AndroidManifest.xml het dossier.

Bovendien heeft de app die we vandaag zullen maken toegang nodig tot de camera en externe opslagmedia van het apparaat, dus u moet ook om het CAMERA en WRITE_EXTERNAL_STORAGE toestemmingen.

 

Voeg ten slotte de API-sleutel van uw Visual Recognition-service toe aan de strings.xml het dossier.

a1234567890bcdefe

3. Initialisatie van een Visual Recognition-client

De Watson Java SDK onthult alle functies die de Visual Recognition-service biedt via de VisualRecognition klasse. Daarom moet u nu een instantie ervan initialiseren met behulp van de constructor, die zowel een versiedatum als de API-sleutel als zijn argumenten verwacht.

Tijdens het gebruik van de Visual Recognition-service wilt u meestal foto's maken met de camera van het apparaat. De Watson Android SDK heeft een CameraHelper klas om je te helpen dit te doen. Hoewel u dit niet hoeft te doen, raad ik aan dat u ook een exemplaar ervan initialiseert binnen de activiteiten van uw activiteit onCreate () methode.

private VisualRecognition vrClient; privé CameraHelper-helper; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // Visuele herkenningsklant initialiseren vrClient = nieuwe VisualRecognition (VisualRecognition.VERSION_DATE_2016_05_20, getString (R.string.api_key)); // Initialiseer camera helper helper = nieuwe CameraHelper (this); 

Op dit moment hebt u alles wat u nodig hebt om te beginnen met het analyseren van afbeeldingen met de service.

4. Objecten detecteren

De visuele herkenningsservice kan een grote verscheidenheid aan fysieke objecten detecteren. Als invoer verwacht het een redelijk goed belichte foto met een resolutie van minimaal 224 x 224 pixels. Laten we voorlopig de camera van het apparaat gebruiken om een ​​dergelijke foto te maken.

Stap 1: Definieer een lay-out

De gebruiker moet op een knop kunnen drukken om de foto te maken, dus het XML-bestand met de lay-out van de activiteit moet een Knop widget. Het moet ook een hebben Tekstweergave widget om de gedetecteerde objecten weer te geven.

Optioneel kun je een Figuurweergave widget om de afbeelding weer te geven.

In de bovenstaande code hebben we een gebeurtenishandler voor de klik toegevoegd aan de Knop widget. U kunt een beginnetje voor deze widget genereren door deze te coderen door op de hiernaast afgebeelde gloeilamp te klikken.

openbare nietige takePicture (weergave weergeven) // Meer code hier

Stap 2: Maak een foto

U kunt een foto maken door eenvoudigweg te bellen naar CameraHelper voorwerpen dispatchTakePictureIntent () methode, dus voeg de volgende code toe aan de gebeurtenishandler:

helper.dispatchTakePictureIntent ();

De bovenstaande methode maakt gebruik van de standaard camera-app van het apparaat om de foto te maken. Dat betekent om toegang te krijgen tot de gemaakte foto, je moet je activiteiten overschrijven onActivityResult () methode en zoek naar resultaten waarvan de aanvraagcode is REQUEST_IMAGE_CAPTURE. Hier is hoe je dat kunt doen:

@Override beschermde leegte onActivityResult (int requestCode, int resultCode, Intent-gegevens) super.onActivityResult (requestCode, resultCode, data); if (requestCode == CameraHelper.REQUEST_IMAGE_CAPTURE) // Meer code hier

Zodra u het juiste resultaat hebt gevonden, kunt u de afbeelding eruit halen in de vorm van een Bitmap object met behulp van de getBitmap () methode van de CameraHelper klasse. U kunt ook het absolute pad van de foto krijgen met behulp van de getFile () methode. We hebben zowel de bitmap als het absolute pad nodig, dus voeg de volgende code toe:

laatste bitmapfoto = helper.getBitmap (resultCode); laatste bestand photoFile = helper.getFile (resultCode);

Als u ervoor kiest om de Figuurweergave widget naar uw lay-out, u kunt de afbeelding nu weergeven door de bitmap rechtstreeks naar de afbeelding te leiden setImageBitmap () methode.

ImageView-preview = findViewById (R.id.preview); preview.setImageBitmap (foto);

Stap 3: Classificeer de afbeelding

Om items in de afbeelding te detecteren, moet u de afbeelding als invoer voor de afbeelding doorgeven classificeren() methode van de VisualRecognition voorwerp. Voordat u dit echter doet, moet u het in a verpakken ClassifyImagesOptions object, dat kan worden gemaakt met behulp van de ClassifyImagesOptions.Builder klasse.

De retourwaarde van de classificeren() methode is een ServiceCall object, dat zowel synchrone als asynchrone netwerkaanvragen ondersteunt. Laten we voor nu bellen execute () methode om een ​​synchroon verzoek in te dienen. Natuurlijk, omdat netwerkbewerkingen niet zijn toegestaan ​​in de UI-thread, moet u dit onthouden vanuit een nieuwe thread.

AsyncTask.execute (nieuw Runnable () @Override public void run () VisualClassification response = vrClient.classify (nieuw ClassifyImagesOptions.Builder () .images (photoFile) .build ()) .execute (); // Meer code hier );

De classificeren() methode is gemaakt om meerdere afbeeldingen tegelijk te verwerken. Bijgevolg is het antwoord een lijst met classificatiegegevens. Omdat we momenteel met één afbeelding werken, hebben we alleen het eerste item van de lijst nodig. Zo kunt u het krijgen:

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

De Visual Recognition-service behandelt elk item dat is gedetecteerd als een afzonderlijke klasse van het type VisualClassifier.VisualClass. Door de getClasses () methode, kunt u een lijst van alle klassen krijgen.

Elke klas heeft, onder andere, een naam en een vertrouwensscore die ermee verbonden zijn. De volgende code laat zien hoe je door de lijst met klassen loopt en alleen de namen weergeeft van wie de scores hoger zijn dan 70% in de Tekstweergave widget.

laatste StringBuffer-uitvoer = nieuwe StringBuffer (); for (VisualClassifier.VisualClass-object: classifier.getClasses ()) if (object.getScore ()> 0.7f) output.append ("<") .append(object.getName()) .append("> "); runOnUiThread (nieuw Runnable () @Override openbare ongeldige run () TextView detectedObjects = findViewById (R.id.detected_objects); detectedObjects.setText (output););

Merk op dat de bovenstaande code de runOnUiThread () methode omdat de inhoud van de Tekstweergave widget kan alleen worden bijgewerkt vanuit de UI-thread.

Als je de app nu uitvoert en een foto maakt, kun je de beeldclassificatie van Watson zien werken.

5. Gezichten analyseren

De Visual Recognition-service heeft een speciale methode om menselijke gezichten te verwerken. Het kan de leeftijd en het geslacht van een persoon in elke foto bepalen. Als de persoon beroemd is, kan het ook hem of haar benoemen.

Stap 1: Definieer een lay-out

Het analyseren van gezichten met de Visual Recognition-service is niet veel anders dan het classificeren van objecten. U bent dus vrij om de lay-out die u eerder hebt gemaakt opnieuw te gebruiken. Om u echter kennis te laten maken met een paar andere functies die de service biedt, ga ik een nieuwe lay-out maken, deze met een iets andere functionaliteit.

Laten we deze keer in plaats van foto's te maken met behulp van de camera en deze door te geven aan de service, direct een afbeeldings-URL doorgeven. Om de gebruiker toe te staan ​​een URL in te typen en de analyse te starten, heeft onze lay-out een Tekst bewerken widget en a Knop widget. Het heeft ook een Tekstweergave widget om de resultaten van de analyse weer te geven.

Ik stel voor dat je ook een Figuurweergave widget naar de lay-out, zodat de gebruiker de afbeelding ziet waarnaar de URL verwijst.

  

Stap 2: Geef de afbeelding weer

In de on-click-handler van de Knop widget, je kunt de getText () methode van de Tekst bewerken widget om de afbeeldings-URL te bepalen die de gebruiker heeft ingevoerd. Zodra u de URL kent, kunt u deze gewoon doorgeven aan Picasso's laden() en in() methoden om de afbeelding te downloaden en weer te geven in de Figuurweergave widget.

EditText imageURLInput = findViewById (R.id.image_url); final String-URL = imageURLInput.getText (). toString (); ImageView-preview = findViewById (R.id.preview); Picasso.with (this) .load (url) .into (voorbeeld);

Stap 3: Gezichtsanalyse uitvoeren

Als u gezichtsanalyse op de URL wilt uitvoeren, moet u de detectFaces () methode van de VisualRecognition cliënt. Net als de classificeren() methode, deze methode heeft ook een VisualRecognitionOptions object als zijn invoer. 

Omdat je al weet hoe je de execute () methode om synchrone verzoeken te maken, laten we nu de enqueue () methode in plaats daarvan, die asynchroon wordt uitgevoerd en een callback vereist. De volgende code laat zien hoe:

vrClient.detectFaces (nieuwe VisualRecognitionOptions.Builder () .url (url) .build ()) .enqueue (new ServiceCallback() @Oeverride public void onResponse (DetectedFaces response) // Meer code hier @Override public void onFailure (Exception e) );

Zoals je kunt zien in de bovenstaande code, in de onResponse () methode van het callback-object, hebt u toegang tot a DetectedFaces object, dat een lijst met gezichtsanalyseresultaten bevat. Omdat we een enkele afbeelding als onze invoer hebben gebruikt, hebben we alleen het eerste item van de lijst nodig. Door het te noemen getFaces () methode, krijg je een lijst van alle Gezicht objecten gedetecteerd.

Lijst faces = response.getImages (). get (0) .getFaces ();

Elk Gezicht object heeft een geslacht en leeftijdsbereik dat ermee geassocieerd is, dat toegankelijk is door het te gebruiken getGender () en getAge () methoden.

De getGender () methode retourneert eigenlijk een Geslacht voorwerp. Je moet zijn eigen roepen getGender () methode om het geslacht als een tekenreeks te krijgen, die "MANNELIJK" of "VROUWELIJK" zal zijn. Evenzo is de getAge () methode retourneert een Leeftijd voorwerp. Door het te noemen getMin () en getMax () methoden, kunt u de geschatte ouderdom van het gezicht in jaren bepalen.

De volgende code laat zien hoe je door de lijst van moet luspen Gezicht objecten, genereer een reeks met de geslachten en leeftijden van alle vlakken en geef deze weer in de Tekstweergave widget:

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

Hier volgt een voorbeeld van een gezichtsanalyseresultaat:

Conclusie

Met de Watson Visual Recognition-service kunt u heel eenvoudig apps maken die slim zijn en zich bewust zijn van hun omgeving. In deze zelfstudie hebt u geleerd hoe u deze kunt gebruiken met de Watson Java- en Android-SDK's om generieke objecten en gezichten te detecteren en te analyseren.

Voor meer informatie over de service, kunt u de officiële documentatie raadplegen.

En vergeet niet om een ​​aantal van onze andere berichten over machine learning hier op Envato Tuts te bekijken+!