Google Cloud Machine Learning Services voor Android gebruiken

Nieuws is tegenwoordig vol met buzzwords zoals automatisering, kunstmatige intelligentie en machine learning. Dat is waarschijnlijk de reden waarom steeds meer smartphonegebruikers op zoek gaan naar slimmere apps. Als normale ontwikkelaar van Android-apps ontbreekt het je echter aan de benodigde middelen om dergelijke apps helemaal opnieuw te maken.

Gelukkig heeft Google onlangs een Cloud Machine Learning-platform gelanceerd, dat neurale netwerken aanbiedt die vooraf zijn opgeleid om verschillende taken uit te voeren. De meeste van zijn modellen zijn niet alleen zeer nauwkeurig, maar verbeteren ook constant. En raad eens? U kunt ze gebruiken door simpelweg een paar REST API-aanroepen te maken!

In deze tutorial zal ik je kennis laten maken met het Cloud Machine Learning-platform en laten zien hoe je het kunt gebruiken om een ​​slimme Android-app te maken die real-world-objecten kan herkennen en deze in meerdere talen kan benoemen.

voorwaarden

Om het beste uit deze tutorial te halen, is alles wat je nodig hebt:

  • de nieuwste versie van Android Studio
  • een apparaat met Android 4.4 of hoger
  • en een Google Cloud Platform-account

1. Een API-sleutel verkrijgen

Om de machine-leerdiensten van Google in uw Android-app te kunnen gebruiken, hebt u een API-sleutel nodig. U kunt er een krijgen door een nieuw project te maken in de Google Cloud Platform-console.

Begin door u aan te melden bij de console en op te drukken Maak een nieuw project knop. Geef in het dialoogvenster dat verschijnt een betekenisvolle naam aan het project.

Nadat het project is gemaakt, gaat u naar API Manager> Dashboard en druk op de API inschakelen knop.

In het volgende scherm, onder de Google Cloud Machine Learning rubriek, kunt u alle verschillende computerleren-API's bekijken die voor u beschikbaar zijn. In deze zelfstudie gebruiken we alleen de Vision- en Translation-API's.

Om de Vision API in te schakelen, klikt u op de koppeling en drukt u op in staat stellen knop.

Evenzo, om de Translation API in te schakelen, klikt u op de koppeling en drukt u op in staat stellen knop.

U hebt slechts één sleutel nodig om beide API's te gebruiken. Om het te krijgen, ga naar de Geloofsbrieven tab, druk op de Aanmeldingsgegevens maken knop en selecteer API sleutel.

U zou nu een popup met uw geheime API-sleutel moeten zien.

2. Een nieuw Android-project maken

Start Android Studio en maak een nieuw project met een lege activiteit. Ik stel voor dat u op zijn minst API-niveau 19 kiest voor de minimaal ondersteunde SDK.

Hoewel u dat niet hoeft te doen, is het altijd een goed idee om een ​​robuuste netwerkbibliotheek te gebruiken om te communiceren met het Google Cloud Machine Learning-platform. In deze zelfstudie gebruiken we een dergelijke bibliotheek met de naam Fuel. Voeg het toe als een compileren afhankelijkheid in de app module build.gradle het dossier:

compileer 'com.github.kittinunf.fuel: brandstof-android: 1.5.0'

druk op Synchroniseer nu om uw project bij te werken.

Vervolgens heeft onze app de INTERNET toestemming om te communiceren met de servers van Google. Voeg daarom de volgende regel toe aan het manifestbestand van het project:

Voeg ten slotte uw API-sleutel toe aan de waarden / strings.xml het dossier:

ABCDEF12345-abcdef12345-123

3. Gebruik van de Vision API

Met de Vision API kunt u apps maken die de omgeving van de gebruiker kunnen zien en begrijpen. Gezichtsdetectie, emotieherkenning, optische tekenherkenning en beeldannotatie zijn enkele van de vele functies. Voorlopig richten we ons alleen op de krachtige beeldannotatiefunctie, ook wel labeldetectie genoemd, die naar mijn mening erg nuttig is.

Zoals je zou verwachten, verwacht de API een afbeelding als een van zijn ingangen. Laten we daarom nu een scherm maken waarin de gebruiker foto's kan maken met de camera van het apparaat.

Stap 1: maak een lay-out

De lay-out van ons scherm zal een Knop widget die de gebruiker kan indrukken om een ​​foto te maken, een Figuurweergave widget om de afbeelding weer te geven, en a Tekstweergave widget om de labels of annotaties weer te geven die door de API zijn gegenereerd. Voeg daarom de volgende code toe aan het lay-out XML-bestand van uw activiteit:

Houd er rekening mee dat we een hebben gekoppeld bij klikken handler met de knop. We zullen het in de volgende stap definiëren.

Stap 2: maak een intentie

Door een nieuwe intentie te creëren met de ACTION_IMAGE_CAPTURE actie en doorgeven aan de startActivityForResult () methode, kunt u de standaard camera-app van het apparaat van de gebruiker vragen om foto's te maken en door te geven aan uw app. Voeg daarom de volgende code toe aan uw Activiteit klasse:

openbare definitieve statische int MY_REQUEST_CODE = 1; public void takePicture (View view) Intent intent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult (intentie, MY_REQUEST_CODE); 

Om de beelden te ontvangen die zijn vastgelegd met de standaardcamera-app, moet u de onActivityResult () methode van uw Activiteit klasse. Binnen de methode hebt u toegang tot een Bundel object dat alle afbeeldingsgegevens bevat. U kunt de afbeeldingsgegevens renderen door deze eenvoudig in een te converteren Bitmap en doorgeven aan de Figuurweergave widget.

@Override beschermde leegte onActivityResult (int requestCode, int resultCode, Intent-gegevens) if (requestCode == MY_REQUEST_CODE && resultCode == RESULT_OK) // Converteer afbeeldingsgegevens naar bitmap Bitmap picture = (Bitmap) data.getExtras (). Get ( "gegevens"); // Stel de bitmap in als de bron van de ImageView ((ImageView) findViewById (R.id.previewImage)) .setImageBitmap (afbeelding); // Meer code gaat hier

Als u de app nu uitvoert en een foto maakt, ziet u dat de grootte van de foto vrij klein is. Dat is prima, de Cloud Vision API is zelfs met beeldminiaturen erg nauwkeurig.

Stap 3: Codeer de afbeelding

De Vision API kan niet gebruiken Bitmap objecten direct. In plaats daarvan verwacht het een Base64-gecodeerde reeks gecomprimeerde afbeeldingsgegevens.

Om de afbeeldingsgegevens te comprimeren, kunt u de samenpersen() methode van de Bitmap klasse. Als zijn argumenten verwacht de methode dat het compressieformaat wordt gebruikt, de gewenste uitvoerkwaliteit en a ByteArrayOutputStream voorwerp. De volgende code comprimeert de bitmap met behulp van het JPEG-formaat en zorgt er ook voor dat de kwaliteit van de resulterende afbeelding voldoende hoog is:

ByteArrayOutputStream byteStream = new ByteArrayOutputStream (); picture.compress (Bitmap.CompressFormat.JPEG, 90, byteStream);

U kunt nu de Base64-string genereren met behulp van de encodeToString () methode van de Base64 klasse.

String base64Data = Base64.encodeToString (byteStream.toByteArray (), Base64.URL_SAFE);

Stap 4: Verwerk de afbeelding

Na al dat harde werk hebt u alles wat u nodig hebt om te communiceren met de Vision API. Begin met het maken van een tekenreeks die zowel de URL van de API als uw API-sleutel bevat:

String requestURL = "https://vision.googleapis.com/v1/images:annotate?key=" + getResources (). GetString (R.string.mykey);

Als u gegevens naar de API wilt verzenden, moet u een HTTP POST-aanvraag maken. De hoofdtekst van het verzoek moet een JSON-document zijn dat de Base64-gecodeerde afbeeldingsgegevens bevat. Voor labeldetectie moet het document ook een Kenmerken array met de waarde LABEL_DETECTION. Dit is de indeling van het JSON-document:

"aanvragen": ["image": "inhoud":  , "kenmerken": ["type": "LABEL_DETECTION"]]

Hoewel het mogelijk is om het JSON-document met de hand te coderen, is het programmatisch maken ervan minder foutgevoelig. De volgende code laat zien hoe u dit doet met behulp van de JSONObject en JSONArray klassen:

// Maak een array met // de LABEL_DETECTION-functie JSONArray features = new JSONArray (); JSONObject feature = new JSONObject (); feature.put ("type", "LABEL_DETECTION"); features.put (mogelijkheden); // Maak een object met // de Base64-gecodeerde afbeeldingsgegevens JSONObject imageContent = new JSONObject (); imageContent.put ("content", base64Data); // Plaats de array en het object in een enkel verzoek // en plaats het verzoek vervolgens in een reeks aanvragen JSONArray requests = new JSONArray (); JSONObject-aanvraag = nieuw JSONObject (); request.put ("image", imageContent); request.put ("kenmerken", functies); requests.put (verzoek); JSONObject postData = nieuw JSONObject (); postData.put ("verzoeken", verzoeken); // Converteer de JSON naar een // string String body = postData.toString ();

Op dit punt kunnen we de post() methode van de Brandstof klasse om het HTTP POST-verzoek te maken. Als enige argument verwacht de methode de URL van de API. U moet ook het Inhoud lengte en inhoudstype headers in het verzoek. Gebruik hiervoor de header () methode. Om het JSON-document toe te voegen aan de hoofdtekst van de POST-aanvraag, gebruikt u de post() methode.

Ten slotte door de responseString () methode en het doorgeven van een nieuw exemplaar van de handler klasse, kunt u de reactie van het verzoek asynchroon als een string krijgen. Voeg daarom de volgende code toe:

Fuel.post (requestURL) .header (nieuw paar("inhoudslengte", body.length ()), nieuw paar("inhoudstype", "toepassing / json")) .body (body.getBytes ()) .responseString (nieuwe handler() @ Overmatig publiekig ongeldig succes annuleren (@NotNull Verzoek om verzoek, @NotNull Responsantwoord, String-gegevens) // Meer code hiernaartoe @Override openbare nietige fout (@NotNull Verzoek om Verzoek, @NotNull Reactie Antwoord, @NotNull FuelError fuelError ) );

Wanneer u de labeldetectiefunctie gebruikt, retourneert de Vision API een JSON-document met labels. Samen met elk label krijgt u ook een score die aangeeft hoe nauwkeurig het label is. Het document ziet er als volgt uit:

"responses": ["labelAnnotations": ["mid": "/ m / id1", "description": "label1", "score": 0.91, "mid": "/ m / id2" , "description": "label2", "score": 0.90, ...]

Laten we nu eerst alle objecten in de. Lus doorlopen labelAnnotations matrix en voeg de waarde van elk toe Omschrijving sleutel tot de Tekstweergave widget van onze lay-out. Hier is hoe je dat kunt doen in de succes() methode van de handler klasse:

// Toegang tot het labelAnnotations-arrays JSONArray-labels = nieuw JSONObject (gegevens) .getJSONArray ("responses") .getJSONObject (0) .getJSONArray ("labelAnnotations"); Tekenreeksresultaten = ""; // Doorloop de array en pak de // description-key voor elk item uit voor (int i = 0; i

U kunt nu de app uitvoeren, een foto maken van elk object in de buurt en de labels bekijken die de Vision API ervoor genereert.

4. De vertaal-API gebruiken

De Cloud Translation API, zoals de naam al doet vermoeden, kan tekst van en naar meer dan 100 talen vertalen. Door het effectief te gebruiken, kunt u slimme apps maken die in uw eigen taal met uw gebruikers kunnen communiceren.

In de vorige stap zag je dat de labels die onze app genereert, in het Engels zijn. Laten we nu een knop toevoegen om die labels naar het Duits te vertalen.

Stap 1: werk de lay-out bij

Voeg een ... toe Knop widget tegen het einde van de lay-out van uw activiteit met behulp van de volgende code:

Merk op dat deze knop ook een heeft bij klikken gebeurtenishandler die moet worden gedefinieerd in uw Activiteit klasse.

Stap 2: Vertaal de labels

Het gebruik van de Translation API is veel eenvoudiger dan het gebruik van de Vision API, vooral omdat u geen JSON-document hoeft te maken om uw verzoek te definiëren. In plaats daarvan kunt u eenvoudig parameters doorgeven in een querytekenreeks.

Maak het translateToGerman () methode en maak daarbinnen een string aan die de URL van de Translation API bevat.

public void translateToGerman (Weergave weergeven) String requestURL = "https://translation.googleapis.com/language/translate/v2"; // Meer code gaat hier

Om velden aan de querystring van de bovenstaande URL toe te voegen, kunnen we een Lijst van Paar voorwerpen. De volgende velden zijn belangrijk:

  • sleutel, het specificeren van uw geheime API-sleutel
  • bron, de taal specificeren van waaruit u wilt vertalen
  • doelwit, specificeren van de taal waarnaar u wilt vertalen
  • q, specificeren van de tekst die u wilt vertalen

De volgende code laat zien hoe de API moet worden geconfigureerd om te vertalen van Engels naar Duits:

Lijst> params = new ArrayList <> (); // API-sleutel toevoegen params.add (nieuw paar("key", getResources (). getString (R.string.mykey))); // Stel de bron- en doeltalen in params.add (nieuw paar("source", "en")); params.add (nieuw paar("doel", "de"));

Omdat de querystring meerdere kan bevatten q velden, we voegen er een toe voor elk label dat aanwezig is in onze lay-outs Tekstweergave widget. Hier is hoe:

String [] queries = ((TextView) findViewById (R.id.resultsText)) .getText (). ToString (). Split ("\ n"); for (Stringquery: queries) params.add (nieuw paar("q", query)); 

Eindelijk kunt u bellen met de krijgen() methode van de Brandstof klasse om een ​​HTTP GET-verzoek naar de vertaal-API te maken. Ook deze keer kunt u de responseString () methode om het antwoord asynchroon als een string te krijgen.

Fuel.get (requestURL, params) .responseString (nieuwe handler() @ Overrive public void success (@NotNull Request request, @NotNull Response Response, String data) // Meer code hier @Override public void failure (@NotNull Request request, @NotNull Response response, @NotNull FuelError fuelError) );

Het antwoord van de vertaal-API is een JSON-document met een reeks vertalingen. Het heeft de volgende indeling:

"data": "translations": ["vertaalText": "...", "translationText": "...", ...]

Voor nu, binnen de succes() methode van de handler klas, laten we gewoon door de vertaalwerk array van het bovenstaande JSON-document en werk de inhoud van de Tekstweergave widget met de waarden die horen bij de translatedText sleutels.

// Toegang tot de vertalingen array JSONArray translations = new JSONObject (data) .getJSONObject ("data") .getJSONArray ("translations"); // Doorloop de array en extraheer de vertaalde tekst // -sleutel voor elk item: String result = ""; voor (int i = 0; i

Als u de app nu uitvoert, labels voor een afbeelding genereert en op de tweede knop drukt, moet u de labels in het Duits kunnen zien.

Conclusie

In deze zelfstudie leer je hoe je de Cloud Vision- en Cloud Translation API's, die deel uitmaken van het Google Cloud Machine Learning-platform, in een Android-app gebruikt. Er zijn veel meer van dergelijke API's die door het platform worden aangeboden. U kunt meer over hen te weten komen door te verwijzen naar de officiële documentatie. 

Terwijl u hier bent, bekijkt u enkele van onze andere zelfstudies over hoe u machine learning en cloudservices in uw Android-apps kunt gebruiken!