Nyheter i disse dager er fulle av buzzwords som automatisering, kunstig intelligens og maskinlæring. Det er sannsynligvis hvorfor flere og flere smarttelefonbrukere begynner å lete etter smartere apper. Som en vanlig Android-apputvikler mangler du sannsynligvis ressursene som trengs for å lage slike programmer fra bunnen av.
Heldigvis lanserte Google nylig en Cloud Machine Learning-plattform, som tilbyr nevrale nettverk som har blitt opplært til å utføre en rekke oppgaver. De fleste modellene er ikke bare svært nøyaktige, men også stadig bedre. Og gjett hva? Du kan bruke dem ved ganske enkelt å lage noen REST API-anrop!
I denne opplæringen vil jeg introdusere deg til Cloud Machine Learning-plattformen og vise deg hvordan du bruker den til å lage en smart Android-app som kan gjenkjenne virkelige objekter og navngi dem på flere språk.
For å få mest mulig ut av denne opplæringen, er alt du trenger:
For å kunne bruke Googles maskinlæringstjenester i Android-appen din, trenger du en API-nøkkel. Du kan få en ved å opprette et nytt prosjekt i Google Cloud Platform-konsollen.
Start med å logge inn på konsollen og trykke på Opprett nytt prosjekt knapp. I dialogboksen som dukker opp, gi et meningsfylt navn til prosjektet.
Når prosjektet er opprettet, gå til API Manager> Dashboard og trykk på Aktiver API knapp.
I neste skjermbilde, under Google Cloud Machine Learning overskrift, vil du kunne se alle de forskjellige maskinlærings-APIene som er tilgjengelige for deg. I denne opplæringen bruker vi bare visjons- og oversettelses-APIer.
For å aktivere Vision API, klikk på lenken og trykk på Aktiver knapp.
På samme måte, for å aktivere oversettelses-API, klikker du på linken og trykker på Aktiver knapp.
Du trenger bare én nøkkel for å bruke begge APIene. For å få det, gå til legitimasjon fanen, trykk på Opprett legitimasjon knappen, og velg API-nøkkel.
Du bør nå se en popup som inneholder din hemmelige API-nøkkel.
Brann opp Android Studio og opprett et nytt prosjekt med en tom aktivitet. Jeg foreslår at du velger minst API-nivå 19 for det minste støttede SDK-kortet.
Selv om du ikke trenger det, er det alltid en god idé å bruke et robust nettverksbibliotek for å kommunisere med Google Cloud Machine Learning-plattformen. I denne opplæringen bruker vi et slikt bibliotek som heter Fuel. Legg det som en kompilere
avhengighet i app
modulens build.gradle fil:
kompilere 'com.github.kittinunf.fuel: fuel-android: 1.5.0'
trykk Synkroniser nå å oppdatere prosjektet ditt.
Deretter trenger vår app den INTERNETT
Tillatelse til å kommunisere med Googles servere. Legg derfor til følgende linje i prosjektets manifestfil:
Til slutt legger du til API-nøkkelen til Verdiene / strings.xml fil:
ABCDEF12345-abcdef12345-123
Visjons-API hjelper deg å lage apper som kan se og gi mening om brukerens miljø. Ansiktsgjenkjenning, følelsesdeteksjon, optisk tegngjenkjenning og bildeannonsering er noen av de mange funksjonene. For tiden vil vi bare fokusere på den kraftige bildeanmerkingsfunksjonen, også kalt etikettdeteksjon, som etter min mening er veldig nyttig.
Som du forventer, forventer API et bilde som en av dens innganger. Derfor la oss nå opprette en skjerm hvor brukeren kan ta bilder ved hjelp av enhetens kamera.
Skjermens layout skal ha en Knapp
widget brukeren kan trykke for å ta et bilde, en Imageview
widget for å vise bildet, og a TextView
widget for å vise etikettene, eller merknader, generert av API. Følgelig legg til følgende kode i aktivitetsens layout XML-fil:
Legg merke til at vi har tilknyttet en ved trykk
håndterer med knappen. Vi definerer det i neste trinn.
Ved å skape en ny hensikt med ACTION_IMAGE_CAPTURE
handling og passerer den til startActivityForResult ()
Metode, du kan spørre standardkameraappen til brukerens enhet for å ta bilder og sende dem videre til appen din. Derfor legger du til følgende kode i din Aktivitet
klasse:
offentlig endelig statisk int MY_REQUEST_CODE = 1; Offentlig ugyldig takePicture (View view) Intent Intent = Ny Intent (MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult (intensjon, MY_REQUEST_CODE);
For å motta bildene som er tatt av standard kameraapp, må du overstyre onActivityResult ()
metode for din Aktivitet
klasse. Inne i metoden har du tilgang til a Bunt
objekt som inneholder alle bildedataene. Du kan gjengi bildedataene ved å bare konvertere den til en bitmap
og passerer den til Imageview
widget.
@Override protected void onActivityResult (int requestCode, int resultCode, Intent data) hvis (requestCode == MY_REQUEST_CODE && resultCode == RESULT_OK) // Konverter bildedata til bitmap Bitmap picture = (Bitmap) data.getExtras (). Get "data"); // Sett bitmapet som kilde til ImageView ((ImageView) findViewById (R.id.previewImage)) .setImageBitmap (bilde); // Mer kode går her
Hvis du kjører appen nå og tar et bilde, vil du se at størrelsen på bildet er ganske lite. Det er greit, skjønt-Cloud Vision API er veldig nøyaktig, selv med bildeminiatyr.
Visjons-API kan ikke bruke bitmap
objekter direkte. I stedet forventer den en Base64-kodet streng med komprimerte bildedata.
For å komprimere bildedataene kan du bruke komprimere()
metode av bitmap
klasse. Som argumenter forventer metoden at kompresjonsformatet skal brukes, ønsket utskriftskvalitet, og a ByteArrayOutputStream
gjenstand. Følgende kode komprimerer bitmappen ved hjelp av JPEG-formatet og sørger også for at kvaliteten på det resulterende bildet er tilstrekkelig høyt:
ByteArrayOutputStream byteStream = ny ByteArrayOutputStream (); picture.compress (Bitmap.CompressFormat.JPEG, 90, byteStream);
Du kan nå generere Base64-strengen ved hjelp av encodeToString ()
metode av Base64
klasse.
String base64Data = Base64.encodeToString (byteStream.toByteArray (), Base64.URL_SAFE);
Etter alt det harde arbeidet har du alt du trenger for å samhandle med Vision API. Begynn med å lage en streng som inneholder både nettadressen til API og API-nøkkelen:
String requestURL = "https://vision.googleapis.com/v1/images:annotate?key=" + getResources (). GetString (R.string.mykey);
For å sende data til API, må du opprette en HTTP POST-forespørsel. Kroppen av forespørselen må være et JSON-dokument som inneholder Base64-kodede bildedata. For etikettdeteksjon må dokumentet også ha a egenskaper
array som inneholder verdien LABEL_DETECTION
. Her er formatet til JSON-dokumentet:
"forespørsler": ["image": "content":, "features": ["type": "LABEL_DETECTION"]]
Selv om det er mulig å håndkode JSON-dokumentet, er det mindre feilaktig å lage det programmatisk. Følgende kode viser hvordan du gjør det ved å bruke JSONObject
og JSONArray
klasser:
// Opprett en matrise som inneholder // LABEL_DETECTION funksjonen JSONArray features = new JSONArray (); JSONObject feature = nytt JSONObject (); feature.put ("type", "LABEL_DETECTION"); features.put (funksjon); // Opprett et objekt som inneholder // de Base64-kodede bildedataene JSONObject imageContent = nytt JSONObject (); imageContent.put ("content", base64Data); // Sett array og objekt inn i en enkelt forespørsel // og legg deretter forespørselen inn i en rekke forespørsler JSONArray requests = new JSONArray (); JSONObject request = nytt JSONObject (); request.put ("image", imageContent); request.put ("funksjoner", funksjoner); requests.put (forespørsel); JSONObject postData = nytt JSONObject (); postData.put ("forespørsler", forespørsler); // Konverter JSON til en // streng String body = postData.toString ();
På dette punktet kan vi bruke post()
metode av Brensel
klasse for å gjøre HTTP POST-forespørselen. Som eneste argument forventer metoden nettadressen til API-en. Du må også inkludere innholdslengde
og innholdstype
overskrifter i forespørselen. For å gjøre det, bruk Overskrift()
metode. På samme måte, for å legge til JSON-dokumentet i kroppen til POST-forespørselen, bruker du post()
metode.
Til slutt, ved å ringe responseString ()
metode og passerer en ny forekomst av handler
klasse til det, kan du asynkront få svaret på forespørselen som en streng. Følg derfor følgende kode:
Fuel.post (requestURL) .header (nytt par("innholdslengde", body.length ()), nytt par ("content-type", "application / json")) .body (body.getBytes ()) .responseString (new Handler () @Overgå offentlig tomgangssuksess (@NotNull-forespørselsforespørsel, @NotNull Response Response, Stringdata) // Mer kode går her @Overgå offentlig tomgangssvikt (@NotNull-forespørselsforespørsel, @NotNull Response response, @NotNullNullFuelError fuelError ) );
Når du bruker etikettgjenkjenningsfunksjonen, returnerer Vision API et JSON-dokument som inneholder etiketter. Sammen med hver etikett får du også en score som angir hvor nøyaktig etiketten er. Dokumentet ser slik ut:
"label": "[m" id = "" , "beskrivelse": "label2", "score": 0.90, ...]
For nå, la oss bare gå gjennom alle gjenstandene i labelAnnotations
array og legg til verdien av hver beskrivelse
nøkkel til TextView
widget av vårt layout. Slik kan du gjøre det inni suksess()
metode av handler
klasse:
// Få tilgang til labelAnnotations arrays JSONArray labels = nye JSONObject (data) .getJSONArray ("responses") .getJSONObject (0) .getJSONArray ("labelAnnotations"); Stringresultater = ""; // Gå gjennom arrayet og trekk ut // beskrivelseskoden for hvert element for (int i = 0; iDu kan nå kjøre appen, ta et bilde av et objekt i nærheten, og se etikettene Vision API genererer for det.
4. Bruk oversettelse API
Cloud Translation API, som navnet antyder, kan oversette tekst til og fra over 100 språk. Ved å bruke det effektivt kan du opprette smarte programmer som kan kommunisere med brukerne på sine egne språk.
I det forrige trinnet så du at etikettene vår app genererer, er på engelsk. La oss nå legge til en knapp for å oversette disse etikettene til tysk.
Trinn 1: Oppdater oppsettet
Legg til en
Knapp
widget mot slutten av aktiviteten din layout ved hjelp av følgende kode:Legg merke til at denne knappen også har en
ved trykk
Event Handler som må defineres i dinAktivitet
klasse.Trinn 2: Oversett etikettene
Bruk av oversettelses-API er langt enklere enn å bruke Vision API, først og fremst fordi du ikke trenger å opprette et JSON-dokument for å definere forespørselen din. I stedet kan du bare sende parametere til det i en spørringsstreng.
Opprett
translateToGerman ()
metode og, inne i det, lag en streng som inneholder nettadressen til oversettelses-API.public void translateToGerman (Se visning) String requestURL = "https://translation.googleapis.com/language/translate/v2"; // Mer kode går herHvis du vil legge til felt i spørringsstrengen av nettadressen ovenfor, kan vi bruke en
Liste
avPar
objekter. Følgende felt er viktige:
nøkkel
, angir din hemmelige API-nøkkelkilde
, Angi språket du vil oversette framål
, Angi språket du vil oversette tilq
, Angir teksten du vil oversetteFølgende kode viser hvordan du konfigurerer API-en for å oversette fra engelsk til tysk:
Liste> params = ny ArrayList <> (); // Legg til API-tasten params.add (nytt par ("nøkkel", getResources (). getString (R.string.mykey))); // Angi kilde og målspråk params.add (nytt par ("kilde", "no")); params.add (nytt par ("mål", "de")); Fordi spørringsstrengen kan inneholde flere
q
felt, vi legger til en for hver etikett som er tilstede i vårt layoutsTextView
widget. Dette er hvordan:String [] queries = ((TextView) findViewById (R.id.resultsText)) .getText (). ToString (). Split ("\ n"); for (streng forespørsel: spørringer) params.add (nytt par("q", spørring)); Til slutt kan du ringe
få()
metode avBrensel
klassen for å gjøre en HTTP GET-forespørsel til oversettelses-API. Denne gangen kan du også brukeresponseString ()
metode for asynkront å få svaret som en streng.Fuel.get (requestURL, params) .responseString (new Handler() @Override offentlig tomgangssuksess (@NotNull Response-svar, @NotNull Response Response, String data) // Mer kode her @Override public void failure (@NotNull Request-forespørsel, @NotNull Response response, @NotNullNullFuelError fuelError) ); Responsen til oversettelses-API er et JSON-dokument som inneholder en rekke oversettelser. Den har følgende format:
"data": "translations": ["translatedText": "...", "translatedText": "...", ...]For nå, inne i
suksess()
metode avhandler
klasse, la oss bare gå gjennomoversettelser
utvalg av det ovennevnte JSON-dokumentet, og oppdater innholdet iTextView
widget ved hjelp av verdiene knyttet tiltranslatedText
nøkler.// Få tilgang til oversettelsestallet JSONArray translations = new JSONObject (data) .getJSONObject ("data") .getJSONArray ("translations"); // Gå gjennom arrayet og trekk ut translatedText // -tasten for hvert element Stringsresultat = ""; for (int i = 0; iHvis du kjører appen nå, genererer du etiketter for et bilde, og trykk på den andre knappen, du bør kunne se etikettene på tysk.
Konklusjon
I denne opplæringen har du lært hvordan du bruker API-ene for Cloud Vision and Cloud Translation, som er en del av Google Cloud Machine Learning-plattformen, i en Android-app. Det er mange flere slike APIer som tilbys av plattformen. Du kan lære mer om dem ved å referere til den offisielle dokumentasjonen.
Mens du er her, sjekk ut noen av våre andre veiledninger om hvordan du bruker maskinlæring og skygtjenester i Android-appene dine!