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.
Om het beste uit deze tutorial te halen, is alles wat je nodig hebt:
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.
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
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.
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.
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.
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);
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; iU 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 uwActiviteit
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 hierOm velden aan de querystring van de bovenstaande URL toe te voegen, kunnen we een
Lijst
vanPaar
voorwerpen. De volgende velden zijn belangrijk:
sleutel
, het specificeren van uw geheime API-sleutelbron
, de taal specificeren van waaruit u wilt vertalendoelwit
, specificeren van de taal waarnaar u wilt vertalenq
, specificeren van de tekst die u wilt vertalenDe 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-outsTekstweergave
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 deBrandstof
klasse om een HTTP GET-verzoek naar de vertaal-API te maken. Ook deze keer kunt u deresponseString ()
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 dehandler
klas, laten we gewoon door devertaalwerk
array van het bovenstaande JSON-document en werk de inhoud van deTekstweergave
widget met de waarden die horen bij detranslatedText
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; iAls 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!