/* ĠCopyright Ġ 2 0 1 7 ĠThe ĠTensorFlow ĠAuthors . ĠAll ĠRights ĠReserved . Ċ Ċ Licensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ you Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ You Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat ĊĊĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ċ Unless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ distributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ WITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ See Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ limitations Ġunder Ġthe ĠLicense . Ċ ================================================================ ============== */ Ċ Ċ package Ġcom . ed vard . pose est imation Ċ Ċ import Ġandroid . app . Activity Ċ import Ġandroid . graphics . Bitmap Ċ import Ġandroid . os . System Clock Ċ import Ġandroid . util . Log Ċ import Ġorg . tensorflow . lite . Interpreter Ċ import Ġjava . io . BufferedReader Ċ import Ġjava . io . FileInputStream Ċ import Ġjava . io . IOException Ċ import Ġjava . io . InputStream Reader Ċ import Ġjava . lang . Long Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . Byte Order Ċ import Ġjava . nio . Mapped ByteBuffer Ċ import Ġjava . nio . channels . File Channel . Map Mode Ċ import Ġjava . util . Abstract Map . Simple Entry Ċ import Ġjava . util . ArrayList Ċ import Ġjava . util . Comparator Ċ import Ġjava . util . Priority Queue Ċ Ċ /** Ċ Ġ* ĠClass ifies Ġimages Ġwith ĠTensor flow ĠLite . Ċ Ġ*/ Ċ abstract Ġclass ĠImage Classifier Ċ /** ĠInitializes Ġan Ġ` Image Classifier `. Ġ Ġ*/ Ċ @ Throws ( IOException :: class ) Ċ internal Ġconstructor ( ĊĠ Ġactivity : ĠActivity , ĊĠ Ġval Ġimage Size X : ĠInt , Ġ// ĠGet Ġthe Ġimage Ġsize Ġalong Ġthe Ġx Ġaxis . ĊĠ Ġval Ġimage Size Y : ĠInt , Ġ// ĠGet Ġthe Ġimage Ġsize Ġalong Ġthe Ġy Ġaxis . ĊĠ Ġprivate Ġval Ġmodel Path : ĠString , Ġ// ĠGet Ġthe Ġname Ġof Ġthe Ġmodel Ġfile Ġstored Ġin ĠAssets . ĊĠ Ġ// ĠGet Ġthe Ġnumber Ġof Ġbytes Ġthat Ġis Ġused Ġto Ġstore Ġa Ġsingle Ġcolor Ġchannel Ġvalue . ĊĠ Ġnum Bytes Per Channel : ĠInt Ċ ) Ġ{ ĊĊĠ Ġ/* ĠPre allocated Ġbuffers Ġfor Ġstoring Ġimage Ġdata Ġin . Ġ*/ ĊĠ Ġprivate Ġval Ġint Values Ġ= ĠInt Array ( image Size X Ġ* Ġimage Size Y ) ĊĊĠ Ġ/** ĠAn Ġinstance Ġof Ġthe Ġdriver Ġclass Ġto Ġrun Ġmodel Ġinference Ġwith ĠTensor flow ĠLite . Ġ Ġ*/ ĊĠ Ġprotected Ġvar Ġt flite : ĠInterpreter ? Ġ= Ġnull ĊĊĠ Ġ/** ĠA ĠByteBuffer Ġto Ġhold Ġimage Ġdata , Ġto Ġbe Ġfeed Ġinto ĠTensor flow ĠLite Ġas Ġinputs . Ġ Ġ*/ ĊĠ Ġprotected Ġvar Ġimg Data : ĠByteBuffer ? Ġ= Ġnull ĊĊĠ Ġ/** Ġmulti - stage Ġlow Ġpass Ġfilter Ġ* Ġ Ġ*/ ĊĠ Ġprivate Ġvar Ġfilter Label Prob Array : ĠArray < Float Array >? Ġ= Ġnull ĊĊĠ Ġvar Ġm Print Point Array : ĠArray < Float Array >? Ġ= Ġnull ĊĊĠ Ġprivate Ġval Ġsorted Labels Ġ= ĠPriority Queue < Map . Entry < String , ĠFloat >>( ĊĠĠĠĠĠ ĠRESULT S _ TO _ SHOW , ĊĠĠĠĠĠ ĠComparator < Map . Entry < String , ĠFloat >> Ġ{ Ġo 1 , Ġo 2 Ġ-> Ġo 1 . value . compareTo ( o 2 . value ) Ġ}) ĊĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġt flite Ġ= ĠInterpreter ( load Model File ( activity )) ĊĠĠĠ Ġimg Data Ġ= ĠByteBuffer . allocate Direct ( ĊĠĠĠĠĠĠĠ ĠDIM _ BATCH _ SIZE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġimage Size X ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġimage Size Y ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ* ĠDIM _ PIXEL _ SIZE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ* Ġnum Bytes Per Channel ĊĠĠĠ Ġ) ĊĠĠĠ Ġimg Data !!. order ( Byte Order . native Order ()) ĊĠĠĠ ĠLog . d ( TAG , Ġ" Created Ġa ĠTensor flow ĠLite ĠImage ĠClass ifier .") ĊĠ Ġ} ĊĊĠ Ġ/** ĠClass ifies Ġa Ġframe Ġfrom Ġthe Ġpreview Ġstream . Ġ Ġ*/ ĊĠ Ġpublic Ġfun Ġclassify Frame ( bitmap : ĠBitmap ): ĠString Ġ{ ĊĠĠĠ Ġif Ġ( t flite Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Image Ġclassifier Ġhas Ġnot Ġbeen Ġinitialized ; ĠSk ipped .") ĊĠĠĠĠĠ Ġreturn Ġ" Un initialized ĠClass ifier ." ĊĠĠĠ Ġ} ĊĠĠĠ Ġconvert Bitmap To ByteBuffer ( bitmap ) ĊĠĠĠ Ġ// ĠHere 's Ġwhere Ġthe Ġmagic Ġhappens !!! ĊĠĠĠ Ġval ĠstartTime Ġ= ĠSystem Clock . uptime Millis () ĊĠĠĠ Ġrun Inference () ĊĠĠĠ Ġval ĠendTime Ġ= ĠSystem Clock . uptime Millis () ĊĠĠĠ ĠLog . d ( TAG , Ġ" Time cost Ġto Ġrun Ġmodel Ġinference : Ġ" Ġ+ ĠLong . toString ( endTime Ġ- ĠstartTime )) ĊĊĊĠĠĠ Ġ// ĠPrint Ġthe Ġresults . ĊĠĠĠ Ġ// ĠĠĠ ĠString Ġtext To Show Ġ= Ġprint Top K Labels (); ĊĠĠĠ Ġreturn ĠLong . toString ( endTime Ġ- ĠstartTime ) Ġ+ Ġ" ms " ĊĠ Ġ} ĊĊĊĠ Ġ/** ĠCloses Ġt flite Ġto Ġrelease Ġresources . Ġ Ġ*/ ĊĠ Ġfun Ġclose () Ġ{ ĊĠĠĠ Ġt flite !!. close () ĊĠĠĠ Ġt flite Ġ= Ġnull ĊĠ Ġ} ĊĊĠ Ġ/** ĠMemory - map Ġthe Ġmodel Ġfile Ġin ĠAssets . Ġ Ġ*/ ĊĠ Ġ@ Throws ( IOException :: class ) ĊĠ Ġprivate Ġfun Ġload Model File ( activity : ĠActivity ): ĠM apped ByteBuffer Ġ{ ĊĠĠĠ Ġval ĠfileDescriptor Ġ= Ġactivity . assets . open Fd ( model Path ) ĊĠĠĠ Ġval ĠinputStream Ġ= ĠFileInputStream ( file Descriptor . file Descriptor ) ĊĠĠĠ Ġval Ġfile Channel Ġ= ĠinputStream . channel ĊĠĠĠ Ġval Ġstart Offset Ġ= ĠfileDescriptor . start Offset ĊĠĠĠ Ġval Ġdeclared Length Ġ= ĠfileDescriptor . declared Length ĊĠĠĠ Ġreturn Ġfile Channel . map ( Map Mode . READ _ ONLY , Ġstart Offset , Ġdeclared Length ) ĊĠ Ġ} ĊĊĠ Ġ/** ĠWrites ĠImage Ġdata Ġinto Ġa Ġ` ByteBuffer `. Ġ Ġ*/ ĊĠ Ġprivate Ġfun Ġconvert Bitmap To ByteBuffer ( bitmap : ĠBitmap ) Ġ{ ĊĠĠĠ Ġif Ġ( img Data Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĠĠĠ Ġimg Data !!. rewind () ĊĠĠĠ Ġbitmap . get Pixels ( int Values , Ġ 0 , Ġbitmap . width , Ġ 0 , Ġ 0 , Ġbitmap . width , Ġbitmap . height ) ĊĠĠĠ Ġ// ĠConvert Ġthe Ġimage Ġto Ġfloating Ġpoint . ĊĠĠĠ Ġvar Ġpixel Ġ= Ġ 0 ĊĠĠĠ Ġval ĠstartTime Ġ= ĠSystem Clock . uptime Millis () ĊĠĠĠ Ġfor Ġ( i Ġin Ġ 0 Ġuntil Ġimage Size X ) Ġ{ ĊĠĠĠĠĠ Ġfor Ġ( j Ġin Ġ 0 Ġuntil Ġimage Size Y ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġv Ġ= Ġint Values [ pixel ++] ĊĠĠĠĠĠĠĠ Ġadd Pixel Value ( v ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġval ĠendTime Ġ= ĠSystem Clock . uptime Millis () ĊĠĠĠ ĠLog . d ( ĊĠĠĠĠĠĠĠ ĠTAG , ĊĠĠĠĠĠĠĠ Ġ" Time cost Ġto Ġput Ġvalues Ġinto ĠByteBuffer : Ġ" Ġ+ ĠLong . toString ( endTime Ġ- ĠstartTime ) ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠAdd Ġpixel Value Ġto Ġbyte Buffer . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġpixel Value ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġabstract Ġfun Ġadd Pixel Value ( pixel Value : ĠInt ) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠRead Ġthe Ġprobability Ġvalue Ġfor Ġthe Ġspecified Ġlabel ĠThis Ġis Ġeither Ġthe Ġoriginal Ġvalue Ġas Ġit Ġwas ĊĠĠ Ġ* Ġread Ġfrom Ġthe Ġnet 's Ġoutput Ġor Ġthe Ġupdated Ġvalue Ġafter Ġthe Ġfilter Ġwas Ġapplied . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġlabel Index ĊĠĠ Ġ* Ġ@ return ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġabstract Ġfun Ġget Probability ( label Index : ĠInt ): ĠFloat ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠSet Ġthe Ġprobability Ġvalue Ġfor Ġthe Ġspecified Ġlabel . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ param Ġlabel Index ĊĠĠ Ġ* Ġ@ param Ġvalue ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġabstract Ġfun Ġset Probability ( ĊĠĠĠ Ġlabel Index : ĠInt , ĊĠĠĠ Ġvalue : ĠNumber ĊĠ Ġ) ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠGet Ġthe Ġnormalized Ġprobability Ġvalue Ġfor Ġthe Ġspecified Ġlabel . ĠThis Ġis Ġthe Ġfinal Ġvalue Ġas Ġit ĊĠĠ Ġ* Ġwill Ġbe Ġshown Ġto Ġthe Ġuser . ĊĠĠ Ġ* ĊĠĠ Ġ* Ġ@ return ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġabstract Ġfun Ġget Normalized Probability ( label Index : ĠInt ): ĠFloat ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠRun Ġinference Ġusing Ġthe Ġprepared Ġinput Ġin Ġ[. img Data ]. ĠAfter wards , Ġthe Ġresult Ġwill Ġbe ĊĠĠ Ġ* Ġprovided Ġby Ġget Probability (). ĊĠĠ Ġ* ĊĠĠ Ġ* ĊĠĠ Ġ* ĠThis Ġadditional Ġmethod Ġis Ġnecessary , Ġbecause Ġwe Ġdon 't Ġhave Ġa Ġcommon Ġbase Ġfor Ġdifferent ĊĠĠ Ġ* Ġprimitive Ġdata Ġtypes . ĊĠĠ Ġ*/ ĊĠ Ġprotected Ġabstract Ġfun Ġrun Inference () ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠ Ġ/** ĠTag Ġfor Ġthe Ġ[ Log ]. Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġconst Ġval ĠTAG Ġ= Ġ" Tf Lite Camera Demo " ĊĊĠĠĠ Ġ/** ĠNumber Ġof Ġresults Ġto Ġshow Ġin Ġthe ĠUI . Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġconst Ġval ĠRESULT S _ TO _ SHOW Ġ= Ġ 3 ĊĊĠĠĠ Ġ/** ĠDimensions Ġof Ġinputs . Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġconst Ġval ĠDIM _ BATCH _ SIZE Ġ= Ġ 1 ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠDIM _ PIXEL _ SIZE Ġ= Ġ 3 ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠFILTER _ ST AGES Ġ= Ġ 3 ĊĠĠĠ Ġprivate Ġconst Ġval ĠFILTER _ FACTOR Ġ= Ġ 0 . 4 f ĊĠ Ġ} Ċ } Ċ