Identifying folk med Qualcomm Snapdragon SDK
26
Del
9
Del
Dette Cyber mandag Envato Tuts + Kursene vil bli redusert til bare $ 3. Ikke gå glipp av.
Det var ikke så lenge siden at å ta bilder var ganske dyrt. Kameraer kreves film med begrenset kapasitet og se resultater også nødvendig ekstra tid og mer penger. Disse iboende begrensninger sørget for at vi var selektiv med bildene vi tok.
Spol frem til i dag, og disse begrensningene har blitt redusert takket være teknologi, men vi står nå overfor et nytt problem, filtrering, organisering og avdekke viktige bilder fra mange vi tar.
Det nye problemet er hva som inspirerte denne opplæringen. I det, vil jeg vise hvordan vi kan bruke nye verktøy for å bidra til å gjøre brukerens livet enklere ved å innføre nye måter å filtrere og organisere innholdet vårt.
1. Konsept
For dette prosjektet, skal vi se på en annen måte å filtrere gjennom din samling av bilder. Underveis vil du lære hvordan du kan integrere og bruke Qualcomm Snapdragon SDK for ansiktsbehandling og anerkjennelse.
Vi vil gjøre det mulig for brukeren å filtrere en samling av bilder av identitets /identiteter. Samlingen vil bli filtrert av identiteter fra et bilde brukeren kraner på, som demonstrert under.
2. Oversikt
Hovedfokuset i dette innlegget er innføring av ansiktsbehandling og anerkjennelse bruker Qualcomm Snapdragon SDK mens-forhåpentligvis-indirekte oppmuntrende nye måter å tenke og å bruke avledet metadata fra innhold.
For å unngå bli fiksert i VVS, har jeg lage en mal som gir grunnleggende tjeneste for skanning via brukerens samling av bilder og et rutenett for visning av bilder. Vårt mål er å forbedre dette med konseptet foreslått ovenfor.
I det følgende vil vi kort gjennomgå disse komponentene før han går videre innføre Qualcomm Snapdragon SDK.
3. Skeleton
Som nevnt ovenfor, er vårt mål å fokusere på Snapdragon SDK så jeg har laget et skjelett som har alle avløp implementert. Nedenfor er et diagram og en beskrivelse av prosjektet, som er tilgjengelig for nedlasting fra GitHub.
Våre data pakken inneholder en implementasjon av SQLiteOpenHelper (IdentityGalleryDatabase) ansvarlig for å opprette og administrere vår database. Databasen vil bestå av tre bord, en til å fungere som en peker til media record (bildet), en annen for oppdagede identiteter (identitet), og til slutt forholdet tabellen koble identiteter med sine bilder (identity_photo).
Vi vil bruke identiteten tabell for å lagre attributtene levert av Snapdragon SDK, detaljert i et senere avsnitt av denne opplæringen.
Også inkludert i datapakken er en leverandør (IdentityGalleryProvider) og Contract (IdentityGalleryContract) klasse, som er noe mer enn en standard Provider fungerer som en wrapper av SQLiteOpenHelper klassen.
For å gi deg en følelse av hvordan de skal samhandle med Provider klassen, følgende kode er hentet fra TestProvider klassen. Som navnet antyder, er det brukt for å teste Provider klassen.
//... Query for alle bilder Pekeren peker = mContext.getContentResolver () spørring (IdentityGalleryContract.PhotoEntity.CONTENT_URI, null, null, null, null);. //... Query for alle bilder som inkluderer noen av identiteter innenfor den refererte bildet Pekeren peker = mContext.getContentResolver spørring (IdentityGalleryContract.PhotoEntity.buildUriWithReferencePhoto (photoid), null, null, null, null) ();. //... Query samtale identiteter Pekeren peker = mContext.getContentResolver () spørring (IdentityGalleryContract. .IdentityEntity.CONTENT_URI, null, null, null, null); //... Query for alle Pekeren peker = mContext.getContentResolver () spørring (IdentityGalleryContract.PhotoEntity.CONTENT_URI, null, null, null, null);.
servicepakke er ansvarlig for gjentakelse gjennom en, katalogisering, og til slutt behandle bildene tilgjengelige via Media. Tjenesten i seg selv forlenger IntentService som en enkel måte å utføre behandlingen på sin egen tråd. Selve arbeidet er delegert til GalleryScanner, som er den klassen vi skal utvide for ansiktsbehandling og anerkjennelse
Dette GalleryScannerIntentService er instansiert hver gang MainActivity opprettes med følgende samtale:.
Override beskyttet void onCreate (Bundle savedInstanceState) {... GalleryScannerIntentService.startActionScan (this.getApplicationContext ()); ...}
Når begynte, GalleryScannerIntentService henter siste skanning dato og sender dette til konstruktøren av GalleryScanner. Det kaller deretter skanningen metoden for å starte itera gjennom innholdet i MediaItem innholdsleverandøren-for varer etter siste skanningen dato.
Hvis du inspisere skanningen metoden i GalleryScanner klassen, vil du se at det er ganske ordrik-ingenting komplisert som skjer her. Metoden må spørre for mediefiler som er lagret internt (MediaStore.Images.Media.INTERNAL_CONTENT_URI) og eksternt (MediaStore.Images.Media.EXTERNAL_CONTENT_URI). Hvert element blir så ført til en krok metode, som er der vi vil plassere vår kode for ansiktsbehandling og anerkjennelse.
Private void processImage (ContentValues contentValues, Uri contentUri) {kaste nytt UnsupportedOperationException ("Hook metoden er ikke implementert" );.}
En annen to krok metoder i GalleryScanner klassen er tilgjengelig for oss (som metodenavn foreslå) til å initial og de-initialisere FacialProcessing eksempel
private void initFacialProcessing () kaster UnsupportedOperationException {kaste nytt UnsupportedOperationException ( "Hook metoden ikke er implementert");} private void deinitFacialProcessing () {kaste nytt UnsupportedOperationException ("er Hook metoden ikke implementert");}
Den endelige pakken er presentasjonspakke. Som navnet antyder, er vertskap for aktiviteten klassen ansvarlig for å gjengi vårt galleri. Galleriet er en Gridview festet til en CursorAdapter. Som forklart ovenfor, vil peke på et element søke i databasen for noen bilder som inneholder en av identiteten til det valgte bildet. For eksempel, hvis du trykker på et bilde av din venn Lisa og hennes kjæreste Justin, vil søket filtrere alle bilder som inneholder en eller begge Lisa og Justin.
4. Qualcomm Snapdragon SDK
For å hjelpe utviklere lage sine hardware ser flott ut og gjøre det rettferdighet, har Qualcomm gitt ut en fantastisk sett med SDK, en blir Snapdragon SDK. Snapdragon SDK eksponerer en optimalisert sett av funksjoner for ansiktsbehandling.
SDK er grovt delt inn i to deler, ansiktsbehandling og ansiktsgjenkjenning. Gitt at ikke alle enheter støtter både-eller-av disse funksjonene, som er trolig grunnen til å ha disse funksjonene skilt, gir SDK en enkel måte å sjekke hvilke funksjoner støtter enheten. Vi vil dekke dette i mer detalj senere
Ansikts behandling gir en måte å utvinne funksjoner fra et bilde (av et ansikt) inkludert.
Gaze Tracking:. Vurdere der motivet er ute
Smil Verdi:.. Beregn graden av smilet
Face Orientering:. Spor yaw, pitch og roll av hodet
Facial gjenkjennelse, som navnet antyder, gir mulighet til å identifisere personer i et bilde. Det er verdt å merke seg at all behandling er gjort lokalt i motsetning til nettskyen.
Disse funksjonene kan brukes sanntid (video /kamera) eller offline (galleri). I vår øvelse, vil vi bruke disse funksjonene offline, men det er minimale forskjeller mellom de to tilnærmingene.
Consult den elektroniske dokumentasjonen for støttede enheter for å lære mer om ansiktsbehandling og ansiktsgjenkjenning.
5. Legge Facial Behandling og Recognition
I denne delen vil vi fylle disse hook metoder-med overraskende få linjer med kode å gi vår søknad evnen til å trekke ansikt egenskaper og identifisere personer. Å arbeide sammen, laste ned kilde fra GitHub og åpne prosjektet i Android Studio. Alternativt kan du laste ned ferdige prosjektet
Trinn 1:. Installere Snapdragon SDK
Det første vi må gjøre er å ta tak i SDK fra Qualcomm hjemmeside. Merk at du må registrere /logge inn og er enig med Qualcomm vilkår og betingelser.
Når lastet ned, dearkiver innholdet og navigere til /Snapdragon_sdk_2.3.1/java/libs/libs_facial_processing/. Kopier sd-SDK-ansikts-processing.jar filen til prosjektets /app /libs /mappe som vist nedenfor.
Etter å kopiere Snapdragon SDK, høyreklikker du på sd-SDK-ansikts-processing.jar .. og velg Legg til som Library ... fra listen over alternativer
Dette vil legge biblioteket som en avhengighet i build.gradle fil som vist nedenfor
avhengig {kompilere fileTree (dir: 'libs ', blant annet: [' * .jar ']) kompilere filer (' libs /sd-SDK-ansikts-processing.jar ') kompilere' com.android.support:support-v13:20.0.0'}
The siste trinnet er å legge til lokale bibliotek. For å gjøre dette ved å opprette en mappe kalt jniLibs i /app /src /main /mappe og kopiere armeabi mappen (fra SDK nedlasting) og innholdet i den.
Vi er nå klar til å implementere logikk for å identifisere mennesker ved hjelp av funksjonaliteten til API. Følgende kodesnutter hører hjemme i GalleryScanner klassen
Trinn 2:. Initialisering
La oss først takle initialisering kroken metoden.
private void initFacialProcessing () kaster UnsupportedOperationException {if (! FacialProcessing.isFeatureSupported (FacialProcessing.FEATURE_LIST.FEATURE_FACIAL_PROCESSING) ||! FacialProcessing.isFeatureSupported (FacialProcessing.FEATURE_LIST.FEATURE_FACIAL_RECOGNITION)) {kaste nytt UnsupportedOperationException ("Facial Processing eller Recognition er ikke støttes på denne enheten "); } MFacialProcessing = FacialProcessing.getInstance (); if (mFacialProcessing = null) {mFacialProcessing.setRecognitionConfidence (mConfidenceThreshold); mFacialProcessing.setProcessingMode (FacialProcessing.FP_MODES.FP_MODE_STILL); loadAlbum (); } Else {kaste nytt UnsupportedOperationException ("En forekomst er allerede i bruk");}}
Vi må først sjekke at enheten støtter både ansiktsbehandling og ansiktsgjenkjenning Hvis den ikke gjør det, kaster vi en UnsupportedOperationException unntak..
Etter at vi tilordner vår lokale referanse av FacialProcessing klassen, mFacialProcessing, til en ny forekomst ved hjelp av fabrikken metoden getInstance. Dette vil returnere null hvis en forekomst er allerede i bruk, og i så fall forbrukeren er nødvendig å kalle utgivelse på at referansen.
Hvis vi har lykkes oppnådd en forekomst av en FacialProcessing objekt, vi konfigurere den ved først å sette tillit. Vi gjør dette ved hjelp av en lokal variabel, som er 57 i dette tilfellet fra en området 0 til 100. tillit er en terskel når du prøver å løse identiteter. vil Eventuelle kampene under denne terskelen anses som egne identiteter.
Når det gjelder fastsettelse av verdien, så vidt jeg kan fortelle, dette er en prøving og feiling prosess. Tydeligvis høyere terskel, jo mer nøyaktig anerkjennelse, med avveining av å øke antall falske positiver.
Vi setter FacialProcessing modus til FP_MODE_STILL. Alternativene her er enten FP_MODE_STILL eller FP_MODE_VIDEO. Som navnene antyder, en er optimalisert for stillbilder mens den andre for kontinuerlige bilder, begge har åpenbruksmåter.
P_MODE_STILL, som du kanskje mistenker, gir mer nøyaktige resultater. Men som du vil se senere, er FP_MODE_STILL implisert av metoden vi bruker for å behandle bildet slik at denne linjen kan utelates. Jeg bare lagt det for fullstendighet.
Vi kaller loadAlbum (metoden i GalleryScanner klasse), som er det vi skal se på neste.
Private void loadAlbum () {SharedPreferences sharedPreferences = mContext.getSharedPreferences (TAG, 0); String arrayOfString = sharedPreferences.getString (KEY_IDENTITY_ALBUM, null); byte [] albumArray = null; if (! arrayOfString = null) {String [] splitStringArray = arrayOfString.substring (1, arrayOfString.length () - 1) .split (","); albumArray = new byte [splitStringArray.length]; for (int i = 0; i < splitStringArray.length; i ++) {albumArray [i] = Byte.parseByte (splitStringArray [i]); } MFacialProcessing.deserializeRecognitionAlbum (albumArray); }}
Det eneste interessante linje her er:
mFacialProcessing.deserializeRecognitionAlbum (albumArray);
Det teller metoden er:
byte [] albumBuffer = mFacialProcessing.serializeRecogntionAlbum ();
En enkelt FacialProcessing eksempel kan være tenkt som en økt. Lagt personer (forklart nedenfor) er lagret lokalt (referert til som "anerkjennelse album") i løpet av forekomsten. Å tillate albumet ditt til å vedvare over flere økter, det vil si hver gang du får en ny forekomst, trenger du en måte å vedvare og laste dem.
serializeRecogntionAlbum metoden konverterer albumet til en byte array og omvendt den deserializeRecognitionAlbum vil laste inn og analysere et tidligere lagret album som en byte array
Trinn 3:. De-initialisering
Vi vet nå hvordan å initialisere FacialProcessing klassen for ansiktsbehandling og anerkjennelse. . La oss nå rette fokus til de-initialisere den ved å implementere den deinitFacialProcessing metoden
private void deinitFacialProcessing () {if (mFacialProcessing = null) {saveAlbum (); mFacialProcessing.release (); mFacialProcessing = null; }}
Som nevnt ovenfor, kan det bare være én forekomst av FacialProcessing klasse om gangen, så vi trenger for å sikre at vi slipper det før målstreken vår oppgave. Vi gjør dette via en utgivelse metode. Men først gjør vi anerkjennelse album vedvarer, slik at vi kan bruke resultater over flere økter. I dette tilfellet, når brukeren tar eller mottar nye bilder, ønsker vi å sikre at vi bruker tidligere bokførte identiteter for de samme menneskene
private void saveAlbum () {byte [] albumBuffer = mFacialProcessing.serializeRecogntionAlbum (.); SharedPreferences sharedPreferences = mContext.getSharedPreferences (TAG, 0); SharedPreferences.Editor redaktør = sharedPreferences.edit (); editor.putString (KEY_IDENTITY_ALBUM, Arrays.toString (albumBuffer)); editor.commit ();}
Trinn 4: Behandling av bilde
Vi er endelig klar til kjøttet ut den endelige kroken metode og bruke FacialProcessing klassen. De følgende kodeblokker tilhører processImage metoden. Jeg har delt dem opp for klarhet
private void processImage (ContentValues contentValues, Uri contentUri) {lang photoRowId = ContentUris.parseId (contentUri.); String uriAsString = contentValues.getAsString (GalleryContract.PhotoEntity.COLUMN_URI); Uri uri = Uri.parse (uriAsString); Bitmap bitmap = null; try {bitmap = ImageUtils.getImage (mContext, uri); } Catch (IOException e) {return; } If (bitmap! = Null) {//fortsatte under (1)}}
Metoden tar en referanse til en forekomst av ContentValues klassen, som holder metadata for dette bildet, sammen med URI peker til bilde . Vi bruker denne til å laste bildet inn i minnet
Følgende kodebiten er å erstatte den ovennevnte kommentar //fortsatte under (1)
hvis {return.. (MFacialProcessing.setBitmap (bitmap)!); } int numFaces = mFacialProcessing.getNumFaces (); if (numFaces > 0) {FaceData [] faceDataArray = mFacialProcessing.getFaceData (); if (faceDataArray == null) {Log.w (TAG, contentUri.toString () + "har blitt returnert en NULL FaceDataArray"); komme tilbake; } For (int i = 0; i < faceDataArray.length; i ++) {FaceData faceData = faceDataArray [i]; if (faceData == null) {fortsette; } //Fortsatte nedenfor (2)}}
Som nevnt ovenfor, må vi først passere statisk bilde til FacialProcessing eksempel via SetBitmap metoden. Ved hjelp av denne metoden bruker implisitt FP_MODE_STILL modus. Denne metoden returnerer True hvis bildet ble vellykket behandlet og False hvis behandlingen mislyktes
Den alternative metoden for behandling av streaming-bilder (typisk for kamera forhåndsvisning frames) er:.
Public boolean setFrame (byte [] yuvData , int frameWidth, int frameHeight, boolean isMirrored, FacialProcessing.PREVIEW_ROTATION_ANGLE rotationAngle)
De fleste av parametrene er åpenbare. Du trenger ikke å passere i om rammen er snudd (dette er vanligvis nødvendig for front-mot kamera), og hvis noen rotasjon har blitt brukt (vanligvis satt via setDisplayOrientation metoden for et kamera eksempel).
deretter spørre etter antall ansikter og bare fortsette hvis minst én er funnet. Den getFaceData metoden returnerer detaljene for hvert oppdaget ansiktet som en matrise av FaceData objekter, der hvert FaceData objekt innkapsler ansiktstrekk inkludert:
ansikt grense (FACE_RECT)
ansikt, munn, og øye steder (FACE_COORDINATES)
konturen av ansiktet (FACE_CONTOUR)
grad av smil (FACE_SMILE)
retning av øynene (FACE_GAZE)
flagg som angir om enten øye (eller begge øyne) blinker (FACE_BLINK)
yaw, pitch og roll i ansiktet (FACE_ORIENTATION)
generert eller avledet identifikasjon (FACE_IDENTIFICATION)
Det er en overbelastning på denne metoden som tar et sett med enums (som beskrevet ovenfor) for trekkpunkter for å bli inkludert, fjerne /minimere overflødige beregninger.
offentlige FaceData [] getFaceData (java.util.EnumSet < FacialProcessing.FP_DATA > settet) kaster java.lang.IllegalArgumentException
Vi har nå gå videre til inspisere FaceData objekt å trekke ut identiteten og funksjoner. La oss først se hvordan ansiktsgjenkjenning gjøres
Følgende kodebiten er å erstatte den ovennevnte kommentar //fortsatte nedenfor (2)
int personId = faceData.getPersonId ();.. If ( personId == FacialProcessingConstants.FP_PERSON_NOT_REGISTERED) {personId = mFacialProcessing.addPerson (i);} else {! if (mFacialProcessing.updatePerson (personId, i) = FacialProcessingConstants.FP_SUCCESS) {//TODO håndtaket error}} lang identityRowId = getOrInsertPerson (personId ); //fortsetter under (3)
Vi først be tildelt person id via getPersonId metoden. Dette vil returnere -111 (FP_PERSON_NOT_REGISTERED) hvis ingen identitet eksisterer i øyeblikket ligger albumet, ellers returnerer id av en matchende person fra lastet album.
Hvis ingen identitet finnes, så vi legger den til addPerson metode av FacialProcessing objekt, passerer den indeksen for FaceData element vi for tiden inspisere. Metoden returnerer tildelt person id hvis det lykkes, ellers returnerer en feil. Dette skjer når du prøver å legge til en identitet som allerede eksisterer.
Alternativt når personen ble matchet med en identitet som er lagret i vår ladd album, kaller vi det FacialProcessing objektets updatePerson metode, passerer det eksisterende id og indeks over den FaceData elementet. Legge til en person flere ganger øker anerkjennelse ytelse. Du kan legge til opptil ti ansikter for en enkelt person.
Den siste linjen bare returnerer den tilhørende identitet id fra vår database, setter det hvis personen id ikke allerede eksisterer.
Det er ikke er vist ovenfor, men FaceData forekomsten eksponerer getRecognitionConfidence metode for å returnere den erkjennelse tillit (0 til 100). Avhengig av dine behov, kan du bruke denne til å påvirke flyten.
Den endelige biten demonstrerer hvordan å spørre hver av de andre funksjonene fra FaceData eksempel. I denne demoen, kan vi ikke gjøre bruk av dem, men med litt fantasi jeg er sikker på at du kan tenke på måter å sette dem til god bruk.
Følgende kodebiten er å erstatte den ovennevnte kommentar //fortsetter under (3)
int smileValue = faceData.getSmileValue ();. int leftEyeBlink = faceData.getLeftEyeBlink (); int rightEyeBlink = faceData.getRightEyeBlink (); int roll = faceData.getRoll (); PointF gazePointValue = faceData.getEyeGazePoint (); int banen = faceData.getPitch (); int yaw = faceData.getYaw (); int horizontalGaze = faceData. getEyeHorizontalGazeAngle (); int verticalGaze = faceData.getEyeVerticalGazeAngle (); Rect faceRect = faceData.rect; insertNewPhotoIdentityRecord (photoRowId, identityRowId, gazePointValue, horizontalGaze, verticalGaze, leftEyeBlink, rightEyeBlink, pitch, yaw, roll, smileValue, faceRect);
som fullfører behandlingen koden. Hvis du går tilbake til galleriet, og trykk på et bilde, bør du se det filtrere ut noen bilder som ikke inneholder noen mennesker som er identifisert i det valgte bildet.
Konklusjon
Vi startet denne opplæringen snakker om hvordan teknologi kan brukes til å organisere brukerens innhold. I sammenheng oppmerksom computing, hvis målet er å bruke kontekst som en implisitt kø for å berike den fattige interaksjon fra mennesker til datamaskiner, noe som gjør det lettere å kommunisere med datamaskiner, er dette kjent som automatisk merking. Ved å markere opp innholdet med mer meningsfylt og nyttig data for både datamaskinen og oss-vi tillate mer intelligent filtrering og behandling.
Vi har sett denne brukes ofte med tekstlig innhold, den mest åpenbare eksempelet er spam filtre og nå nylig, nyhetslesere, men i mindre grad med rikt medieinnhold, for eksempel bilder, musikk og video. Verktøy som Snapdragon SDK gir oss en mulighet til å trekke meningsfulle funksjoner fra rike medier, utsette sine egenskaper til brukeren og datamaskinen.
Det er ikke vanskelig å forestille seg hvordan du kan utvide vår søknad for å tillate filtrering basert på følelser ved hjelp av et smil som hovedfunksjon eller sosiale aktiviteter ved å telle antallet flater. En slik gjennomføring kan sees i denne Smart Gallery funksjonen.