Pubblicato da Eileen Mao e Tanjin Prity, Engineering Practicum Intern di Google, estate 2019
Siamo entusiasti di rilasciare un'applicazione di esempio di TensorFlow Lite per la stima delle pose del corpo umano su Android utilizzando il modello PoseNet. PoseNet è un modello di visione che stima la posa di una persona in un'immagine o un video rilevando le posizioni delle parti principali del corpo. Ad esempio, il modello può stimare la posizione del gomito e/o del ginocchio di una persona in un'immagine. Il modello di stima della posa non identifica la persona presente in un'immagine, ma solo le posizioni delle parti principali del corpo.
TensorFlow Lite mette a disposizione un'applicazione di esempio Android che utilizza la fotocamera del dispositivo per rilevare e visualizzare parti del corpo chiave di una singola persona in tempo reale. Dai un'occhiata al codice sorgente!
Perché è entusiasmante?
La stima delle pose del corpo umano offre enormi possibilità. Per citarne alcune, gli sviluppatori possono aumentare la realtà sulla base delle immagini del corpo, animare personaggi di grafica computerizzata e analizzare l'andatura di atleti in vari sport. In occasione del Google I/O '19, TensorFlow Lite ha presentato Dance Like, un'app che aiuta gli utenti a imparare a ballare usando il modello PoseNet.
Questa applicazione di esempio semplificherà per gli sviluppatori di app e gli esperti di machine learning l'esplorazione delle possibilità di un modello leggero per dispositivi mobili.
Applicazione di esempio PoseNet
Contrariamente agli esempi Android esistenti scritti in Java, l'app di esempio PoseNet è stata sviluppata in Kotlin. L'obiettivo dello sviluppo dell'app era consentire a chiunque di utilizzare il modello PoseNet con semplicità e con operazioni minime. L'app di esempio include una libreria PoseNet che astrae le complessità del modello. Il diagramma seguente mostra il flusso di lavoro tra l'applicazione, la libreria PoseNet e la libreria TensorFlow Lite.
Flusso di lavoro dell'app PoseNet
La libreria PoseNet
La libreria PoseNet fornisce un'interfaccia che acquisisce un'immagine della fotocamera elaborata e restituisce informazioni su dove si trovano le parti del corpo chiave della persona. Questa funzionalità è fornita da estimSinglePose(), un metodo che esegue l'interprete TensorFlow Lite su una bitmap RGB elaborata e restituisce un oggetto Person. Questa pagina spiega come interpretare gli input e gli output di PoseNet.
// Estimate the body part positions of a single person.
// Pass in a Bitmap and obtain a Person object.
estimateSinglePose(bitmap: Bitmap): Person {...}
La classe Person contiene le posizioni delle parti principali del corpo con i relativi punteggi di confidenza. Il punteggio di confidenza di una persona è la media dei punteggi di confidenza di ciascun punto chiave, che indica la probabilità che esista un punto chiave in quella posizione.
// Person class holds a list of key points and an associated confidence score.
class Person {
var keyPoints: List<KeyPoint> = listOf<KeyPoint>()
var score: Float = 0.0f
}
Ogni KeyPointcontiene informazioni sulla Position di una determinata BodyParte il punteggio di confidenza di quel punto chiave. È possibile accedere a un elenco di tutti i punti chiave definiti qui.
// KeyPoint class holds information about each bodyPart, position, and score.
class KeyPoint {
var bodyPart: BodyPart = BodyPart.NOSE
var position: Position = Position()
var score: Float() = 0.0f
}
// Position class contains the x and y coordinates of a key point on the bitmap.
class Position {
var x: Int = 0
var y: Int = 0
}
// BodyPart class holds the names of seventeen body parts.
enum class BodyPart {
NOSE,
LEFT_EYE,
RIGHT_EYE,
...
RIGHT_ANKLE
}
App di esempio PoseNet
L'app di esempio PoseNet è un'app per fotocamera on-device che cattura i frame dalla fotocamera e sovrappone i punti chiave delle immagini in tempo reale.
L'applicazione esegue i seguenti passaggi per ciascuna immagine in ingresso dalla fotocamera:
Cattura i dati dell'immagine dall'anteprima della fotocamera e li converte dal formato YUV_420_888 al formato ARGB_888.
Crea un oggetto Bitmap per contenere i pixel dai dati dei frame in formato RGB. Ritaglia e ridimensiona la Bitmap in base alle dimensioni di input del modello in modo che possa essere passata al modello.
Chiama la funzione stimSinglePose() dalla libreria PoseNet per ottenere l'oggettoPerson.
Ridimensiona la Bitmap in base alle dimensioni dello schermo. Disegna la nuova Bitmap su un oggetto Canvas.
Usa la posizione dei punti chiave ottenuti dall'oggetto Person per disegnare uno scheletro sulla canvas. Visualizza i punti chiave con un punteggio di confidenza sopra una determinata soglia, che per impostazione predefinita è 0,5.
Per sincronizzare il rendering delle pose con il frame della fotocamera, è stato utilizzato un singolo SurfaceView per la visualizzazione di output anziché istanze View separate per la posa e la fotocamera. SurfaceView si occupa di posizionare prontamente la superficie sullo schermo ottenendo, bloccando e dipingendo nella canvas View.
In esecuzione sul dispositivo
Ti invitiamo a provare l'app scaricando il codice sorgente da GitHub e consultando il file READMEper istruzioni su come eseguirlo.
Roadmap
In futuro, speriamo di esplorare ulteriori applicazioni per questa app di esempio, tra cui:
Stima di pose multiple
Accelerazione GPU con il delegato GPU
Accelerazione NNAPI con il delegato NNAPI
Quantizzazione post-addestramento del modello per ridurre la latenza
Opzioni aggiuntive del modello, come il modello ResNet PoseNet
È stato un piacere sviluppare questa app di esempio PoseNet quest'estate! Speriamo che questa app renda più accessibile il machine learning on-device. Se usi l'app, condividila con noi usando #TFLite, #TensorFlow e #PoweredByTF
Ringraziamenti
Un particolare ringraziamento a Nupur Garg e Pulkit Bhuwalka, i nostri host e software engineer Tensorflow Lite, Tyler Zhu, ideatore del modello PoseNet, Pavel Senchanka, collega stagista, Clément Julliard, software engineer Pixel Camera e tutto il team TensorFlow Lite.