Utiliser Machine Learning pour reconnaître des images avec IBM Watson

Ne serait-il pas formidable si une application Android pouvait voir et comprendre ses environs? Pouvez-vous imaginer à quel point son interface utilisateur pourrait être meilleure si elle pouvait regarder ses utilisateurs et connaître instantanément leur âge, leur sexe et leurs émotions? Eh bien, une telle application peut sembler futuriste, mais elle est totalement faisable aujourd'hui..

Avec le service IBM Watson Visual Recognition, la création d'applications mobiles capables de détecter et d'analyser avec précision des objets dans des images est plus simple que jamais. Dans ce didacticiel, je vais vous montrer comment utiliser cette application pour créer une application Android intelligente, capable de deviner l'âge et le sexe d'une personne, et d'identifier des objets saillants sur une photographie..

Conditions préalables

Pour pouvoir suivre ce tutoriel, vous devez avoir:

  • un compte IBM Bluemix
  • Android Studio 3.0 Canary 8 ou supérieur
  • et un appareil ou un émulateur fonctionnant sous Android 4.4 ou supérieur

1. Activer le service de reconnaissance visuelle

Comme tous les services Watson, le service Visual Recognition doit également être activé manuellement avant de pouvoir être utilisé dans une application. Alors connectez-vous à la console IBM Bluemix et accédez à Services> Watson. Dans la page qui s’ouvre, appuyez sur le bouton Créer un service Watson bouton.

Dans la liste des services disponibles affichée ci-après, choisissez Reconnaissance visuelle.

Vous pouvez maintenant donner un nom significatif au service et appuyer sur le bouton Créer bouton.

Une fois le service prêt, une clé API sera générée pour celui-ci. Vous pouvez le voir en ouvrant le Identifiants de service onglet et en appuyant sur la Voir les références bouton.

2. Configuration du projet

Dans ce didacticiel, nous utiliserons les kits de développement logiciel (SDK) Watson Java et Android lors de l’interaction avec le service Visual Recognition. Nous allons également utiliser la bibliothèque Picasso pour récupérer et afficher des images à partir d'Internet. Par conséquent, ajoutez ce qui suit la mise en oeuvre dépendances à votre app modules build.gradle fichier:

implémentation 'com.ibm.watson.developer_cloud: reconnaissance visuelle: 3.9.1' implémentation 'com.ibm.watson.developer_cloud: android-sdk: 0.4.2' implémentation 'com.squareup.picasso: picasso: 2.5.2'

Pour pouvoir interagir avec les serveurs de Watson, votre application aura besoin de la L'INTERNET permission, alors demandez-le dans votre projet AndroidManifest.xml fichier.

En outre, l'application que nous allons créer aujourd'hui devra avoir accès à la caméra et au support de stockage externe de l'appareil. Vous devez donc également demander le CAMÉRA et WRITE_EXTERNAL_STORAGE autorisations.

 

Enfin, ajoutez la clé API de votre service Visual Recognition au strings.xml fichier.

a1234567890bcdefe

3. Initialisation d'un client de reconnaissance visuelle

Le kit de développement logiciel (SDK) Watson Java présente toutes les fonctionnalités offertes par le service Visual Recognition via Reconnaissance visuelle classe. Par conséquent, vous devez maintenant initialiser une instance de celle-ci à l'aide de son constructeur, qui attend à la fois une date de version et la clé API comme arguments..

Lorsque vous utilisez le service de reconnaissance visuelle, vous souhaiterez généralement prendre des photos avec l'appareil photo du périphérique. Le SDK Watson Android a une CameraHelper classe pour vous aider à le faire. Bien que vous n’ayez pas à le faire, je vous suggère également d’en initialiser une instance à l’intérieur de votre activité. onCreate () méthode.

private VisualRecognition vrClient; assistant privé de CameraHelper; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); // Initialisation du client Visual Recognition vrClient = new VisualRecognition (VisualRecognition.VERSION_DATE_2016_05_20, getString (R.string.api_key)); // Initialise l'assistant d'assistance de caméra = new CameraHelper (this); 

À ce stade, vous avez tout ce dont vous avez besoin pour commencer à analyser les images avec le service.

4. Détecter des objets

Le service de reconnaissance visuelle peut détecter une grande variété d'objets physiques. En entrée, il attend une image raisonnablement bien éclairée, dont la résolution est d’au moins 224 x 224 pixels. Pour le moment, utilisons l'appareil photo du périphérique pour prendre une telle photo.

Étape 1: Définir une mise en page

L'utilisateur doit pouvoir appuyer sur un bouton pour prendre la photo. Le fichier XML de présentation de votre activité doit donc avoir un Bouton widget. Il doit aussi avoir un Affichage widget pour lister les objets détectés.

En option, vous pouvez ajouter un ImageView widget pour afficher l'image.

Dans le code ci-dessus, nous avons ajouté un gestionnaire d’événements sur clic à la Bouton widget. Vous pouvez générer une souche pour ce widget dans le code en cliquant sur l'ampoule affichée à côté de celui-ci..

public void takePicture (Afficher la vue) // More code here

Étape 2: Prenez une photo

Vous pouvez prendre une photo en appelant simplement le CameraHelper objets dispatchTakePictureIntent () méthode, ajoutez donc le code suivant dans le gestionnaire d’événements:

helper.dispatchTakePictureIntent ();

La méthode ci-dessus utilise l'application de caméra par défaut du périphérique pour prendre la photo. Cela signifie que pour accéder à la photo prise, vous devez remplacer celle de votre activité. onActivityResult () méthode et rechercher des résultats dont le code de demande est REQUEST_IMAGE_CAPTURE. Voici comment vous pouvez faire cela:

@Override protected void onActivityResult (int requestCode, int resultCode, données d'intention) super.onActivityResult (requestCode, resultCode, data); if (requestCode == CameraHelper.REQUEST_IMAGE_CAPTURE) // Plus de code ici

Une fois que vous avez trouvé le bon résultat, vous pouvez en extraire l’image sous forme de Bitmap objet en utilisant le getBitmap () méthode du CameraHelper classe. Vous pouvez également obtenir le chemin absolu de l'image à l'aide du bouton getFile () méthode. Nous aurons besoin à la fois du bitmap et du chemin absolu, ajoutez donc le code suivant:

final Bitmap photo = helper.getBitmap (resultCode); Fichier final photoFile = helper.getFile (resultCode);

Si vous avez choisi d'ajouter le ImageView à votre mise en page, vous pouvez afficher la photo maintenant en passant directement le bitmap à sa setImageBitmap () méthode.

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

Étape 3: Classer l'image

Pour détecter des éléments dans l’image, vous devez transmettre l’image en tant qu’entrée au classer() méthode du Reconnaissance visuelle objet. Avant de le faire, cependant, vous devez l’envelopper dans un ClassifyImagesOptions objet, qui peut être créé en utilisant le ClassifyImagesOptions.Builder classe.

La valeur de retour de la classer() la méthode est un Appel de service objet, qui prend en charge les requêtes réseau synchrones et asynchrones. Pour l'instant, appelons son exécuter() méthode pour faire une demande synchrone. Bien sûr, les opérations réseau n'étant pas autorisées sur le thread d'interface utilisateur, vous devez vous rappeler de le faire à partir d'un nouveau thread..

AsyncTask.execute (new Runnable () @Override public void run () VisualClassification réponse = vrClient.classify (new ClassifyImagesOptions.Builder () .images (photoFile) .build ()) .execute (); // Plus de code ici );

le classer() La méthode est conçue pour gérer plusieurs images à la fois. Par conséquent, sa réponse est une liste de détails de classification. Comme nous travaillons actuellement avec une seule image, nous avons simplement besoin du premier élément de la liste. Voici comment vous pouvez l'obtenir:

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

Le service de reconnaissance visuelle traite chaque élément détecté comme une classe de type distincte. VisualClassifier.VisualClass. En appelant le getClasses () méthode, vous pouvez obtenir une liste de toutes les classes.

Chaque classe a, entre autres détails, un nom et un score de confiance qui lui sont associés. Le code suivant montre comment parcourir la liste des classes et afficher uniquement les noms de celles dont les scores sont supérieurs à 70%. Affichage widget.

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

Notez que le code ci-dessus utilise le runOnUiThread () méthode parce que le contenu de la Affichage le widget peut être mis à jour uniquement à partir du fil de l'interface utilisateur.

Si vous exécutez l'application maintenant et prenez une photo, vous pourrez voir la classification des images de Watson fonctionner.

5. Analyser les visages

Le service de reconnaissance visuelle dispose d'une méthode dédiée pour traiter les visages humains. Il peut déterminer l’âge et le sexe d’une personne sur n’importe quelle photo. Si la personne est célèbre, elle peut aussi l'appeler.

Étape 1: Définir une mise en page

L'analyse des visages avec le service Visual Recognition n'est pas trop différente de la classification des objets. Vous êtes donc libre de réutiliser la mise en page créée précédemment. Cependant, pour vous présenter quelques fonctionnalités supplémentaires offertes par le service, je vais créer une nouvelle présentation, celle-ci présentant une fonctionnalité légèrement différente..

Cette fois, au lieu de prendre des photos à l'aide de l'appareil photo et de les transmettre au service, transmettons directement une URL d'image à celui-ci. Pour permettre à l’utilisateur de saisir une URL et de lancer l’analyse, notre mise en page nécessite un Éditer le texte widget et un Bouton widget. Il faudra aussi un Affichage widget pour afficher les résultats de l'analyse.

Je vous suggère également d'ajouter un ImageView widget à la mise en page afin que l'utilisateur puisse voir l'image de l'URL pointe vers.

  

Étape 2: Afficher l'image

Dans le gestionnaire de clic sur le Bouton widget, vous pouvez appeler le getText () méthode du Éditer le texte widget pour déterminer l'URL de l'image saisie par l'utilisateur. Une fois que vous connaissez l'URL, vous pouvez simplement la transmettre à Picasso. charge() et dans() méthodes de téléchargement et d'affichage de l'image dans le ImageView 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 (aperçu);

Étape 3: Exécuter une analyse de visage

Pour exécuter l’analyse faciale sur l’URL, vous devez utiliser le detectFaces () méthode du Reconnaissance visuelle client. Comme le classer() méthode, cette méthode a aussi besoin d’un VisualRecognitionOptions objet comme entrée. 

Parce que vous savez déjà comment utiliser le exécuter() méthode pour faire des demandes synchrones, appelons maintenant le enqueue () méthode à la place, qui s'exécute de manière asynchrone et nécessite un rappel. Le code suivant vous montre comment:

vrClient.detectFaces (new VisualRecognitionOptions.Builder () .url (url) .build ()) .enqueue (new ServiceCallback() @Override public void onResponse (réponse DetectedFaces) // Plus de code ici @Override public void onFailure (Exception e) );

Comme vous pouvez le voir dans le code ci-dessus, à l'intérieur du onResponse () méthode de l'objet de rappel, vous avez accès à un Surfaces détectées objet, qui contient une liste de résultats d'analyse de visage. Comme nous avons utilisé une seule image comme entrée, nous n’avons besoin que du premier élément de la liste. En appelant getFaces () méthode, vous obtenez une liste de tous les Visage objets détectés.

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

Chaque Visage l’objet est associé à un sexe et à une tranche d’âge auxquels on peut accéder en appelant le getGender () et getAge () les méthodes.

le getGender () la méthode retourne en fait un Le sexe objet. Vous devez appeler le sien getGender () méthode pour obtenir le genre en tant que chaîne, qui sera soit "MALE", soit "FEMELLE". De même, le getAge () méthode retourne un Âge objet. En appelant getMin () et getMax () méthodes, vous pouvez déterminer l'âge approximatif du visage en années.

Le code suivant montre comment parcourir en boucle la liste des Visage des objets, générez une chaîne contenant les sexes et les âges de toutes les faces et affichez-la dans le champ. Affichage widget:

Sortie de chaîne = ""; pour (Face face: faces) sortie + = "<" + face.getGender().getGender() + ", " + face.getAge().getMin() + " - " + face.getAge().getMax() + " years old>\ n "; TextView personDetails = findViewById (R.id.person_details); personDetails.setText (sortie);

Voici un exemple de résultat d'analyse de visage:

Conclusion

Le service Watson Visual Recognition vous permet de créer des applications intelligentes et conscientes de leur environnement extrêmement facilement. Dans ce didacticiel, vous avez appris à l’utiliser avec les kits SDK Watson Java et Android pour détecter et analyser des objets et des visages génériques..

Pour en savoir plus sur le service, vous pouvez vous référer à la documentation officielle.

Et n'oubliez pas de consulter quelques-uns de nos autres articles sur l'apprentissage automatique ici sur Envato Tuts+!