Utilizzare Machine Learning per riconoscere immagini con IBM Watson

Non sarebbe bello se un'app per Android potesse vedere e comprendere ciò che lo circonda? Riesci a immaginare quanto potrebbe essere migliore la sua interfaccia utente se potesse guardare i suoi utenti e conoscere istantaneamente età, sesso ed emozioni? Bene, un'applicazione del genere potrebbe sembrare futuristica, ma oggi è totalmente fattibile.

Con il servizio IBM Watson Visual Recognition, la creazione di app mobili in grado di rilevare e analizzare in modo accurato gli oggetti nelle immagini è più facile che mai. In questo tutorial, ti mostrerò come utilizzarlo per creare un'app Android intelligente in grado di indovinare l'età e il sesso di una persona e identificare oggetti importanti in una fotografia.

Prerequisiti

Per poter seguire questo tutorial, devi avere:

  • un account IBM Bluemix
  • Android Studio 3.0 Canary 8 o versione successiva
  • e un dispositivo o emulatore con Android 4.4 o versioni successive

1. Attivazione del servizio di riconoscimento visivo

Come tutti i servizi Watson, anche il servizio di riconoscimento visivo deve essere attivato manualmente prima di poter essere utilizzato in un'app. Quindi, accedi alla console IBM Bluemix e vai a Servizi> Watson. Nella pagina che si apre, premi il tasto Crea un servizio Watson pulsante.

Dall'elenco dei servizi disponibili mostrati di seguito, scegliere Riconoscimento visivo.

Ora puoi dare un nome significativo al servizio e premere il tasto Creare pulsante.

Una volta che il servizio è pronto, verrà generata una chiave API. Puoi visualizzarlo aprendo il Credenziali di servizio scheda e premendo il tasto Visualizza credenziali pulsante.

2. Impostazione del progetto

In questo tutorial, utilizzeremo gli SDK Java e Android Watson durante l'interazione con il servizio di riconoscimento visivo. Useremo anche la libreria Picasso per recuperare e visualizzare le immagini da Internet. Pertanto, aggiungere quanto segue implementazione dipendenze al tuo App modulo di build.gradle file:

implementazione 'com.ibm.watson.developer_cloud: riconoscimento visivo: 3.9.1' implementazione 'com.ibm.watson.developer_cloud: android-sdk: 0.4.2' implementazione 'com.squareup.picasso: picasso: 2.5.2'

Per essere in grado di interagire con i server di Watson, la tua app avrà bisogno di INTERNET permesso, quindi richiederlo nel tuo progetto AndroidManifest.xml file.

Inoltre, l'app che creeremo oggi avrà bisogno di accedere alla fotocamera del dispositivo e ai supporti di archiviazione esterni, quindi è necessario anche richiedere il TELECAMERA e WRITE_EXTERNAL_STORAGE permessi.

 

Infine, aggiungi la chiave API del servizio di riconoscimento visivo a strings.xml file.

a1234567890bcdefe

3. Inizializzazione di un client di riconoscimento visivo

Watson Java SDK espone tutte le funzionalità offerte dal servizio di riconoscimento visivo tramite VisualRecognition classe. Pertanto, ora devi inizializzarne un'istanza utilizzando il suo costruttore, che si aspetta sia la data della versione che la chiave API come argomenti.

Durante l'utilizzo del servizio di riconoscimento visivo, di solito vuoi scattare foto con la fotocamera del dispositivo. L'SDK Android Watson ha un CameraHelper classe per aiutarti a farlo. Anche se non è necessario, ti suggerisco di inizializzarne un'istanza all'interno delle attività onCreate () metodo.

VisualRecognition privato vrClient; helper CameraHelper privato; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // Inizializza client Visual Recognition vrClient = new VisualRecognition (VisualRecognition.VERSION_DATE_2016_05_20, getString (R.string.api_key)); // Inizializza helper helper camera = new CameraHelper (this); 

A questo punto, hai tutto il necessario per iniziare ad analizzare le immagini con il servizio.

4. Rilevazione di oggetti

Il servizio di riconoscimento visivo può rilevare una grande varietà di oggetti fisici. Come input, si aspetta un'immagine ragionevolmente ben illuminata con una risoluzione di almeno 224 x 224 pixel. Per ora, usiamo la fotocamera del dispositivo per scattare una foto del genere.

Passaggio 1: definire un layout

L'utente deve essere in grado di premere un pulsante per scattare la foto, quindi il file XML di layout della tua attività deve avere a Pulsante widget di. Deve anche avere un TextView widget per elencare gli oggetti rilevati.

Facoltativamente, puoi inserire un ImageView widget per visualizzare l'immagine.

Nel codice precedente abbiamo aggiunto un gestore eventi on-click al Pulsante widget di. È possibile generare uno stub per questo widget in codice facendo clic sulla lampadina mostrata accanto.

public void takePicture (Visualizza vista) // Altro codice qui

Passaggio 2: scattare una foto

Puoi scattare una foto semplicemente chiamando il CameraHelper oggetto di dispatchTakePictureIntent () metodo, quindi aggiungi il seguente codice all'interno del gestore di eventi:

helper.dispatchTakePictureIntent ();

Il metodo precedente utilizza l'app fotocamera predefinita del dispositivo per scattare la foto. Ciò significa accedere alla foto scattata, è necessario ignorare le attività dell'utente onActivityResult () metodo e cercare i risultati il ​​cui codice di richiesta è REQUEST_IMAGE_CAPTURE. Ecco come puoi farlo:

@Override protetto void onActivityResult (int requestCode, int resultCode, Intent data) super.onActivityResult (requestCode, resultCode, data); if (requestCode == CameraHelper.REQUEST_IMAGE_CAPTURE) // Altro codice qui

Una volta trovato il risultato giusto, puoi estrarre l'immagine da essa sotto forma di a Bitmap oggetto usando il getBitmap () metodo del CameraHelper classe. Puoi anche ottenere il percorso assoluto dell'immagine usando il prendi il file() metodo. Avremo bisogno sia della bitmap che del percorso assoluto, quindi aggiungi il seguente codice seguente:

foto Bitmap finale = helper.getBitmap (resultCode); file finale photoFile = helper.getFile (resultCode);

Se hai scelto di aggiungere il ImageView widget per il layout, è possibile visualizzare l'immagine ora passando direttamente la bitmap al suo setImageBitmap () metodo.

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

Passaggio 3: classificare l'immagine

Per rilevare elementi nell'immagine, devi passare l'immagine come input per classificare() metodo del VisualRecognition oggetto. Prima di farlo, tuttavia, è necessario avvolgerlo in a ClassifyImagesOptions oggetto, che può essere creato usando il ClassifyImagesOptions.Builder classe.

Il valore di ritorno del classificare() il metodo è a ServiceCall oggetto, che supporta richieste di rete sincrone e asincrone. Per ora, chiamiamola eseguire() metodo per fare una richiesta sincrona. Naturalmente, poiché le operazioni di rete non sono consentite sul thread dell'interfaccia utente, è necessario ricordarsi di farlo da un nuovo thread.

AsyncTask.execute (new Runnable () @Override public void run () VisualClassification response = vrClient.classify (new ClassifyImagesOptions.Builder () .images (photoFile) .build ()) .execute (); // Più codice qui );

Il classificare() il metodo è progettato per gestire più immagini contemporaneamente. Di conseguenza, la sua risposta è una lista di dettagli di classificazione. Poiché al momento stiamo lavorando con una singola immagine, abbiamo solo bisogno del primo elemento della lista. Ecco come puoi ottenerlo:

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

Il servizio di riconoscimento visivo tratta ogni elemento rilevato come classe di tipo separata VisualClassifier.VisualClass. Chiamando il getClasses () metodo, è possibile ottenere un elenco di tutte le classi.

Ogni classe ha, tra gli altri dettagli, un nome e un punteggio di confidenza associati ad esso. Il seguente codice mostra come scorrere l'elenco delle classi e visualizzare i nomi solo di coloro i cui punteggi sono superiori al 70% nel TextView widget di.

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

Si noti che il codice sopra utilizza il runOnUiThread () metodo perché il contenuto del TextView il widget può essere aggiornato solo dal thread dell'interfaccia utente.

Se esegui l'app ora e fai una foto, sarai in grado di vedere la classificazione delle immagini di Watson in funzione.

5. Analizzare i volti

Il servizio di riconoscimento visivo ha un metodo dedicato per elaborare volti umani. Può determinare l'età e il sesso di una persona in qualsiasi fotografia. Se la persona è famosa, può anche nominarlo.

Passaggio 1: definire un layout

L'analisi dei volti con il servizio di riconoscimento visivo non è molto diversa dalla classificazione degli oggetti. Quindi sei libero di riutilizzare il layout che hai creato in precedenza. Tuttavia, per farti conoscere alcune altre funzionalità offerte dal servizio, creerò un nuovo layout, questo con una funzionalità leggermente diversa.

Questa volta, invece di scattare foto utilizzando la fotocamera e passandole al servizio, passiamo direttamente a un URL dell'immagine. Per consentire all'utente di digitare un URL e avviare l'analisi, il nostro layout avrà bisogno di un Modifica il testo widget e a Pulsante widget di. Avrà anche bisogno di un TextView widget per visualizzare i risultati dell'analisi.

Ti suggerisco di aggiungere anche un ImageView widget per il layout in modo che l'utente possa vedere l'immagine a cui punta l'URL.

  

Passaggio 2: Visualizza l'immagine

All'interno del gestore on-click del Pulsante widget, puoi chiamare il getText () metodo del Modifica il testo widget per determinare l'URL dell'immagine che l'utente ha digitato. Una volta che conosci l'URL, puoi semplicemente passarlo a Picasso caricare() e in() metodi per scaricare e visualizzare l'immagine in ImageView widget di.

EditText imageURLInput = findViewById (R.id.image_url); final String url = imageURLInput.getText (). toString (); ImageView preview = findViewById (R.id.preview); Picasso.with (questo) .load (url) .into (anteprima);

Passaggio 3: eseguire Analisi faccia

Per eseguire l'analisi del volto sull'URL, è necessario utilizzare il detectFaces () metodo del VisualRecognition cliente. Proprio come il classificare() metodo, anche questo metodo ha bisogno di a VisualRecognitionOptions oggetto come suo input. 

Perché sai già come usare il eseguire() metodo per effettuare richieste sincrone, chiamiamo ora il enqueue () metodo invece, che funziona in modo asincrono e ha bisogno di un callback. Il seguente codice mostra come:

vrClient.detectFaces (new VisualRecognitionOptions.Builder () .url (url) .build ()) .enqueue (new ServiceCallback() @ Override public onResponse (Risposta DetectedFaces) // Altro codice qui @Override public void onFailure (Exception e) );

Come puoi vedere nel codice sopra, all'interno di onResponse () metodo dell'oggetto callback, si ha accesso a a DetectedFaces oggetto, che contiene un elenco di risultati dell'analisi del volto. Poiché abbiamo utilizzato una singola immagine come nostro input, avremo bisogno solo del primo elemento dell'elenco. Chiamando il suo getFaces () metodo, si ottiene un elenco di tutti i Viso oggetti rilevati.

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

Ogni Viso oggetto ha un genere e fascia d'età ad esso associati, a cui si può accedere chiamando il getGender () e getAge () metodi.

Il getGender () il metodo restituisce effettivamente a Genere oggetto. Devi chiamare il suo getGender () metodo per ottenere il genere come stringa, che può essere "MALE" o "FEMMINA". Allo stesso modo, il getAge () metodo restituisce un Età oggetto. Chiamando il suo getMin () e getMax () metodi, è possibile determinare l'età approssimativa del viso in anni.

Il seguente codice mostra come scorrere l'elenco di Viso oggetti, generare una stringa contenente i sessi e le età di tutti i volti e visualizzarli nel TextView widget di:

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

Ecco un esempio di risultato dell'analisi del viso:

Conclusione

Il servizio di riconoscimento visivo di Watson rende estremamente facile la creazione di app intelligenti e consapevoli dell'ambiente circostante. In questo tutorial, hai imparato a usarlo con gli SDK Java e Android Watson per rilevare e analizzare oggetti e volti generici.

Per ulteriori informazioni sul servizio, è possibile fare riferimento alla documentazione ufficiale.

E assicurati di controllare alcuni dei nostri altri post sull'apprendimento automatico qui su Envato Tuts+!