Sei sulla pagina 1di 36

Riconoscimento Automatico della Gestualit` a del Direttore dOrchestra

Relatore: Prof. Goredo Haus Correlatore: Dott. Davide Andrea Mauro Correlatore: Dott. Stefano Baldan

Tesi di Laurea di Tommaso Matticchio Matricola n. 715751

Anno Accademico 2011/2012

Indice
Introduzione 1 Denizione del Progetto 1.1 Analisi degli obbiettivi . . . . . . 1.2 Denizione delle scelte progettuali 1.3 Architettura del sistema . . . . . 1.3.1 Protocollo OSC . . . . . . iii 1 1 2 3 4

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

2 Algoritmi utilizzati 7 2.1 Motiongram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2 Algoritmo di Otsu . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.3 beatDetection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 3 Analisi del software 3.1 Analisi delle Classi . . . . . . . . . . . . . . 3.1.1 FrameDi . . . . . . . . . . . . . . . 3.1.2 Classe MotiongramX e MotiongramY 3.1.3 Classe Gesture . . . . . . . . . . . . 3.2 Metodo draw() . . . . . . . . . . . . . . . . 3.3 Analisi della patch in Puredata . . . . . . . 3.4 Impostazione della patch Puredata . . . . . 3.5 Costruzione della patch Puredata . . . . . . 13 13 13 15 18 20 22 23 24

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

4 Considerazioni nali 27 4.1 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.2 Future works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.3 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Bibliograa 29

ii

INDICE

Introduzione
La motivazione che sta alla base di sviluppare un software per il riconoscimento dei gesti di un direttore dorchestra, per la produzione di una performance musicale conforme, ` e lo studio di sistemi di interfaccia uomo-macchina. Come un computer pu` o elaborare e interpretare le complesse indicazioni di un direttore dorchestra, quali informazioni pu` o estrarre dal gesto direttivo. Sin dal primo momento che ci si ` e interessati a queste problematiche era chiaro che un computer non pu` o, allo stato attuale delle tecnologie, sostituire una vera orchestra; la variet` a di signicati che si possono attribuire ad alcuni gesti possono essere talmente emozionali e estemporanee da non poter essere modellate da algoritmi. Inoltre, le riproduzioni musicali sono frutto non solo dellinterpretazione estemporanea di un gesto, ma di prove e perfezionamenti ricercati nel tempo. Si vuole citare, a titolo di esempio, quello che Alessandro Carbonare, clarinettista di fama mondiale e di aermata bravura, dice in un documentario per Sky Classica riguardo la sua esperienza con il M Claudio Abbado: [. . . ]Abbado non ` e un direttore che ferma molto lorchestra e che dice tante cose, ne dice pochissime. Ti guida ma non ti impone mai quello che vuoi fare. C` e un dimenuendo nel solo di clarinetto del IV movimento[. . . ], qui lui mi ha fatto un cenno di andre gi` u, come se da l` volesse far partire unaltra frase per` o senza interromperla. Mozart in realt` a non ha scritto nessun diminuendo.1 Appare dunque evidente come la gestualit` a del direttore dorchestra sia fortemente personalizzata sia dal direttore stesso, che da chi esterna quello che il direttore chiede. Proprio questa mancanza di standard nelluso del gesto rappresenta il pi` u
1

A. Carbonare a Sky Classica

iii

iv

INTRODUZIONE

grande ostacolo alla buona riuscita di un software che pretenda di interpretare correttamente tutti i gesti che rendono unesecuzione musicale umana. Per questo motivo la scelta progettuale ` e stata verso un sistema che riconosca le tre componenti pi` u facilmente calcolabili: tempo, volume e attacco del suono (vedi paragrafo 1.1).

Capitolo 1 Denizione del Progetto


1.1 Analisi degli obbiettivi

Poich e lo sviluppo di un software completo, che risolvesse tutti i problemi che possono concernere un progetto cos` complesso, ` e ben al di sopra delle aspettative (e tempistiche) di un elaborato nale di questo tipo, si ` e scelto di produrre un software che riuscisse a riconoscere i due principali aspetti della direzione musicale. Gli obbiettivi ssati per questo progetto sono dunque: riconoscimento del gesto relativo alla velocit` a dellesecuzione (pensata come bpm, beats per minute ), nel movimento che rappresenta i 2/4 (battere+levare); riconoscimento del gesto relativo allintensit` a richiesta dal direttore; produzione di un usso audio che sia conforme alla gestualit` a. Si ` e scelto di riconoscere il movimento di 2/4 poich e rappresenta il movimento base della direzione dorchestra, poich e tutte le indicazioni di tipo temporali hanno un battere, che corrisponde al punto pi` u basso che raggiunge la mano, e un levare, che corrisponde al punto pi` u alto. Questo non pone dei limiti, ` e infatti auspicabile che si arrivi a riconoscere tutte le tipologie di gesto; questo aspetto trova infatti posto nella sezione riguardo ai lavori futuri (vedi 4.2). Nonostante non esistano degli standard che deniscono come un direttore chieda maggiore o minore intensit` a ai propri esecutori, si ` e scelto di far corrispondere questo tipo di richiesta alla grandezza del gesto, dove per grandezza si intende 1

CAPITOLO 1. DEFINIZIONE DEL PROGETTO

un valore calcolato come distanza tra beat successivi. Questa scelta ` e stata fatta perch e si ritiene che, nella maggior parte dei casi, la grandezza del gesto trasmetta allesecutore lintensit` a richiesta. Per quanto concerne la produzione di una performance musicale attinente si ` e scelto di modicare, in tempo reale, la riproduzione di un le MIDI; si ` e scelto di non considerare un formato audio (es. le wav, mp3, etc) perch e il risultato sarebbe un usso audio che, dovendo operare sulla velocit` a di riproduzione, produrrebbe anche una variazione del pitch. Inoltre si creerebbero problematiche pi` u losoche e giuridiche, poich e il materiale creato potrebbe apparire come la semplice distorsione di un lavoro altrui.

1.2

Denizione delle scelte progettuali

Per lo sviluppo del progetto legato allelaborato nale le scelte fatte possono essere divise in due categorie: 1. Estrazione dei dati da una webcam; 2. Produzione della performance a partire dai dati estratti al punto precedente. Per la parte relativa allestrazione dei dati a partire dalla webcam la scelta ` e stata quella di partire da un algoritmo per il riconoscimento della gestualit` a che non corrisponde agli algoritmi spesso usati per tracciare il movimento di un oggetto in una sequenza di frame, ma atto a riconoscere il movimento presente nella sequenza di frame, indipendente dagli oggetti in essa contenuti. Il risultato di un algoritmo di questo tipo ` e chiamato motiongram, ed ` e stato sviluppato da Jensenius per riconoscere e interpretare quei movimenti extra musicali che ogni musicista produce durante unesecuzione. A tale scopo la scelta ` e stata quella di usare una libreria per la gestione del usso video di una webcam, mentre limplementazione dellalgoritmo ` e stata fatta ex-novo. Le classi che riguardano lapplicazione di queste metodologie sono: FrameDi, MotiongramX e MotiongramY. Per una descrizione pi` u dettagliata di questo algoritmo si rimanda alla sezione 2.1. Per la generazione di dati conformi alle scelte progettuali ` e stata implementata una classe, denita Gesture , che partendo dai dati prodotti attraverso lalgoritmo

1.3. ARCHITETTURA DEL SISTEMA

di motiongram, restituisce i valori richiesti. Riguardo a questo aspetto ` e stato scelto di usare dei parametri che deniscono le tipologie di gestualit` a che lalgoritmo riconosce; nello specico si ` e scelto di riconoscere la gestualit` a riguardo il tempo 2/4 (un battere e un levare) e di interpretare lampiezza del gesto (distanza tra un beat e il precedente) come richiesta di intensit` a sonora. Per una descrizione pi` u dettagliata si rimanda alla sezione 3.1.3 Per la produzione di una performance, che fosse coerente con i dati generati a partire dalla webcam, la scelta ` e stata quella di inviare i dati a una patch sviluppata nellambiente di programmazione dedicato alle multimedialit` a Puredata, e di gestire in tempo reale la riproduzione di un le in formato MIDI. La descrizione di questa patch ` e trattata nella sezione 3.3.

1.3

Architettura del sistema

Si vuole dare in questa sezione una descrizione del sistema che implementa il software sviluppato per lelaborato nale. Larchitettura di questo sistema ha, come elementi iniziali, un computer a cui ` e collegata una webcam, elemento fondamentale per poter elaborare informazioni in tempo reale. La parte software ` e stata invece divisa in due parti: una legata al video e una legata allaudio; troviamo quindi che la webcam, e i dati che invia al computer, sono elaborati da Processing, un ambiente di sviluppo (con un linguaggio di programmazione basato su Java) per le multimedialit` a (immagini, animazioni e interazione). I dati generati ed elaborati dal software sviluppato in Processing, sono quindi inviati tramite il protocollo OSC (Open Sound Control), creato per permettere la comunicazione tra computer, sintetizzatori e dispositivi che supportino le moderne tecnologie di rete. I dati vengono quindi spediti allultimo anello dellarchitettura del sistema: la patch creata in Puredata. Questo ambiente di programmazione visuale, pensato per laudio, ` e stato sviluppato da Miller Puckette negli anni 90, come versione opensource del progetto sviluppato presso lIRCAM di Parigi chiamato Max e poi sviluppato come software commerciale con il nome Max/MSP. In questa patch, descritta dettagliatamente nella sezione 3.3, i dati generati vengono utilizzati per produrre una performance audio, a partire da un le MIDI presente nella memoria del computer.

CAPITOLO 1. DEFINIZIONE DEL PROGETTO

1.3.1

Protocollo OSC

Open Sound Control (OSC) ` e un protocollo, inventato nel 1997 da Adrian Freed e Matt Wright presso il Centre for New Music and Audio Technologies (CNMAT) per controllare gli algoritmi di sintesi sonora del sistema CAST, attraverso messaggi sulla rete [WF97]. Ha poi trovato applicazione nel gestire in tempo reale i ussi di messaggi di controllo audio. Per controllo audio si intende qualsiasi informazione temporizzata riguardo a un usso audio, oltre che la componente audio stessa. Inoltre, questo formato pu` o avere applicazione anche in applicazioni non legate unicamente allaudio, e ha infatti trovato impiego in settori come la robotica o show control. ` da specicare che OSC non ` E e uno standard, e non c` e la necessit` a di test per certicare la conformit` a. Il protocollo ` e open nel signicato che non ha licenze di utilizzo, non richiede lutilizzo di algoritmi registrati o di materiale protetto dal diritto dautore e non fa forti assunzioni su come il formato debba essere usato nelle applicazioni [SFW10]. Limplementazione del protocollo OSC nel progetto avviene in due fase: prima si crea il messaggio OSC e si invia a un indirizzo (ip:porta), mentre per secondo si deve impostare la patch puredata per ricevere il messaggio e riuscire a leggerlo. Nel codice sviluppato in Porcessing questo avviene importando la libreria oscP5 . Si da un esempio minimale dellapplicazione di tale protocollo: Listing 1.1: Esempio OSC in Processing
1

import oscP5 .*; import netP5 .*; OscP5 oscP5 ; NetAddress m y R e m o t e L o c a t i o n ; void setup () { size (400 ,400); oscP5 = new OscP5 ( this ,8000); m yR e m o t e L o c a t i on = new NetAddress ( " localhost " ,8001); } void draw () { }

11

13

15

17

1.3. ARCHITETTURA DEL SISTEMA


void mousePressed () { OscMessage myMessage = new OscMessage ( " / test " ); myMessage . add ( " bang " ); oscP5 . send ( myMessage , m y R e m o t e L o c a t i o n ); } void oscEvent ( OscMessage theOscMessage ) { String thirdValue = theOscMessage . get (2). stringValue (); }

19

21

23

25

27

Si pu` o osservare come il codice implementato sia molto semplice, costituito di pochi passi fondamentali, come la creazione del messaggio (riga 19 del listato 1.1), linserimento del valore desiderato (riga 20) e linvio del messaggio attraverso il metodo send (riga 21). Risulta semplice, inviare un beat attraverso la rete, per farlo giungere alla patch sviluppata in puredata, che attraverso la libreria mrpeach , utilizza oggetti come [udpreceive numero porta ] per mettersi in ascolto dei messaggi, e [unpackOSC] per leggerli secondo il protocollo OSC. La gura 1.1 mostra un esempio base di come creare una patch in grado di ricevere messaggi sulla porta 8001, e ne stampi il valore a video.

Figura 1.1: Esempio di apllicazione protocollo OSC in patch puredata

CAPITOLO 1. DEFINIZIONE DEL PROGETTO

Capitolo 2 Algoritmi utilizzati


2.1 Motiongram

Jensenius scrive[Jen06] che uno dei modi conosciuti per visualizzare il movimento ` e quello di calcolare la dierenza tra due frame in un usso video. Uno degli approcci alla creazione di un motiongram ` e quello di calcolare la quantit` a di moto sommando i pixel attivi in una motion image e stampando questo valore nel tempo. Questi graci restituiscono unidea del tipo di movimento, ma rimuovono completamente tutte le informazioni di tipo spaziale riguardanti la posizione, nellimmagine, dove ha luogo il movimento. Si ricorda che il graco generato corrisponde solo a una dimensione/direzione del movimento. Nel lavoro svolto per lelaborato nale questo approccio ` e stato usato e implementato attraverso il software Processing 1.5.1, attraverso luso di una webcam e la libreria, contenente gli strumenti per utlizzare la webcam, GSVideo. Si ` e quindi implementato un algoritmo che confronta i pixel dellimmagine (frame) corrente con gli stessi pixel dellimmagine precedente, e restituisce unimmagine dove, per i pixel che sono riscontrati come attivi si imposta un pixel bianco mentre per il caso opposto si imposta un pixel nero. Dopo aver generato questa immagine a sogliatura di moto si ` e proceduti a generare i motiongram (che altro non sono che graci del moto), calcolando la media del moto colonna colonna, per ottenere un graco del moto orizzontale, e riga riga, per avere un graco del moto verticale. Dopo aver implementato questa parte il risultato ottenuto ` e la visualizzazione 7

CAPITOLO 2. ALGORITMI UTILIZZATI

di due motiongram, uno che descrive il moto orizzontale della sequenza di frame analizzata, mentre il secondo motiongram descirve il moto verticale. Poich e la scelta progettuale richiede il riconoscimento del movimento di entrambe le mani ` e stato implementato un algoritmo per la separazione delle due tracce, corrispondenti al movimento delle due mani. Inizialmente ` e stato scelto di applicare lalgoritmo di Otsu, che risulta adeguato allo scopo, poich e separa al meglio distribuzioni di probabilit` a bimodali, metodo poi scartato perch e, nonostante gli ottimi risultati, non ` e possibile assumere che ci siano sempre distribuzioni di probabilit` a bimodali, poich e il direttore potrebbe scegliere di muovere una sola mano. Il metodo di Otsu, nonostante sia stato scartato, ` e ugualmente implementato nel codice, perch e in un lavoro futuro potr` a essere implementato un metodo che permetta di usare lalgoritmo di Otsu in presenza di due distribuzioni di probabilit` a, o di utilizzare altre metodologie nel caso di presenza di una sola distribuzione di probabilit` a; la classe ` e OtsuStat e una descrizione dellalgoritmo si pu` o trovare in 2.2.

2.2

Algoritmo di Otsu

Lalgoritmo di Otsu ` e un metodo usato per la sogliatura automatica di istogrammi nelle immagini digitali. Esso considera la presenza di due sole classi (sfondo e primo piano) e determina quale valore di soglia sia la migliore per la separazione delle due classi, minimizzando la varianza intra-classe. La varianza intra-classe viene quindi denita come somma pesata delle varianze delle due classi:
2 2 2 (t) = 1 (t) 1 (t) + 2 (t) 2 (t)

(2.1)

Otsu dimostra inoltre che minimizzare la varianza intra-classe (2.1) equivale a massimizzare la varianza inter-classe:
2 2 (t) = 2 + (t) = 1 (t) 2 (t) 1 (t) 2 (t) . b 2

(2.2)

la quale (2.2) ` e espressa in base ai pesi i e alle medie i . Questo aspetto rende

2.2. ALGORITMO DI OTSU

migliore la sua applicazione a livello informatico poich e cercare il valore massimo ` e un compito facilmente eseguibile da un elaboratore, data la sua natura iterativa e, pi` u importante, incrementale. Il peso della classe 1 (t) ` e ottenuta dallistogramma come t:
t

1 (t) =
0

p(i)

(2.3)

mentre la media della classe i (t) ` e calcolata:


t

i (t) =
0

p(i)x(i)

(2.4)

dove x(i) ` e il valore al centro del iesimo istogramma binario. Allo stesso modo, si pu` o calcolare il peso della 2 (t) e la media t della parte destra dellistogramma per valori pi` u grandi di t. Poich e sia i pesi delle classi che le medie possono essere calcolati in modo incrementale, si pu` o ottenere un algoritmo. Questo algoritmo pu` o essere quindi eseguito seguendo i passi: 1. calcolare gli istogrammi e i pesi per tutti i livelli di intensit` a; 2. inizializzare i (0) e i (0); 3. scorrere tutte le possibili soglie t = 1...valore massimo; (a) aggiornare i e i ; 2 (t); (b) calcolare b
2 4. la soglia desiderata corrisponde al valore massimo di b (t).

Per il lavoro svolto, questo algoritmo si ` e dimostrato ecace nel separare le tracce corrispondenti alle due mani, poich e considerate come due distribuzioni di probabilit` a; sostituendo i dati in ingresso allalgoritmo, usando quindi le righe del motiongram orizzontale e non listogramma delle intensit` a, si ottiene il pixel che separa il semi-quadrato destro dal semi-quadrato sinistro. Come gi` a indicato questo metodo ` e stato scartato poich e` e possibile che il direttore muova una sola mano, e quindi il motiongram generato non sia modellabile come una distribuzione di probabilit` a bimodale.

10

CAPITOLO 2. ALGORITMI UTILIZZATI

2.3

beatDetection

Dopo aver separato i tracciati delle due mani, e avendo sviluppato un metodo per la restituzione del valore del pixel corrispondente alla posizione della mano, ` e stato implementato un algoritmo che fosse in grado di riconoscere automaticamente i due momenti, di battere e levare, corrispondenti al beat. Questo algoritmo ` e stato sviluppato ex-novo, anche perch e alcune degli algoritmi per la ricerca del beat nel movimento usavano parametri diversi, come ad esempio in [MAJ04], dove lalgoritmo considerava anche il le audio per eettuare una predizione di dove si trovasse il beat. Lalgoritmo implementato utilizza come parametri solo il valore di y delle due mani (si ricorda che lalgoritmo funziona in presenza di un gesto da 2/4, quindi solo verticale), e considera come beat gli istanti in cui la funzione ha un picco, verso ` apparso quindi che la condizione da porre allalgoritmo lalto o verso il basso. E fosse legata alla derivata prima del movimento. Questa soluzione presenta delle problematiche, date anche dalla poca linearit` a dei dati in ingresso. Infatti i dati in ingresso allalgoritmo, essendo la posizione del valore medio istante per istante, non risultano come una sequenza lineare di numeri, e anche se calcolati con media esponenziale rispetto al valore precedente, secondo la formula 2.5: pixcurr = ( pixprev ) + pixcurr (1 ) (2.5)

dove determina il peso del valore precedente, e che varia da 0 (quando non si vuole tenere in considerazione i valori precedenti) a 1 (dove il peso ` e talmente alto che pxcurr = pixprev ), lalgoritmo restituisce troppi falsi beat, rendendolo non utilizzabile. La scelta ` e quindi stata quella di creare un algoritmo pi` u sosticato che utilizzasse come parametro, oltre alla derivata prima, anche la derivata seconda. Il modo di calcolare queste due derivate, in questo frangente, ` e quello di calcolare la derivata prima come dierenza del valore corrente e di quello precedente, e di calcolare la derivata seconda come la dierenza tra la derivata prima del valore corrente e la derivata prima del valore precedente. Lalgoritmo deve quindi memo-

2.3. BEATDETECTION

11

rizzare, a ogni ciclo, i valori correnti, per poter utilizzarli al ciclo successivo come valori precedenti. Per cercare di ottenere un risultato il pi` u possibile consono agli scopi sono stati ` aggiunte delle veriche di controllo. E stato aggiunto un valore che determina se la direzione del movimento ` e verso il basso, o viceversa, cos` da impostare lalgoritmo a cercare un cambiamento di verso in relazione a tale dato; ` e stato anche aggiunto un valore temporale che calcola la dierenza in millisecondi tra il beat riscontrato e quello precedente, e in caso questo valore sia inferiore ai 200 millisecondi (vale a dire a un tempo metronomico di 300bpm, valore che ` e sensato pensare fuori scala) considera il beat ottenuto come un falso beat, scartandolo. Lalgoritmo cos` ottenuto ` e stato implementato nella classe Gesture , descritta nella sezione 3.1.3.

12

CAPITOLO 2. ALGORITMI UTILIZZATI

Capitolo 3 Analisi del software


3.1 Analisi delle Classi

Nella seguente sezione vengono descritte in modo pi` u approfondito le classi del codice prodotto durante lo sviluppo del progetto. Sono state scelte le classi considerate pi` u pertinenti alle problematiche occorse durante il lavoro di sviluppo. Si ` e scelto di descrivere le seguenti classi: FrameDi, MotiongramX e Gesture, ritenute parte fondamentale del lavoro svolto, mentre tralasciamo la descrizione delle classi che non apportano originalit` a o forte dipendenza dal lavoro svolto.

3.1.1

FrameDi

La classe denominata FrameDi consente di svolgere loperazione preliminare alla creazione di un motiongram. Come descritto in 2.1, si deve elaborare (partendo dai frame restituiti dalla webcam) unimmagine a sogliatura di moto, per poter procedere con lalgoritmo. Di seguito ` e mostrato il codice prodotto, relativo al metodo principale della classe: Listing 3.1: Classe FrameDi
1

public class FrameDiff { public PImage process ( PImage curr ) { PImage result = createImage ( prev . width , prev . height , RGB ); for ( int x = 0; x < prev . width ; x ++) { for ( int y = 0; y < prev . height ; y ++) { int curPix = curr . get (x , y ); int prevPix = prev . get (x , y );

13

14

CAPITOLO 3. ANALISI DEL SOFTWARE


float err = abs ( red ( curPix ) - red ( prevPix )) + abs ( green ( curPix ) - green ( prevPix )) + abs ( blue ( curPix ) - blue ( prevPix )); if ( err > thresh ) result . set (x , y , color (255)); prev . set (x ,y , curPix ); } } return result ;

11

13

15

}
17

Le variabili prev (di tipo PImage) e tresh (di tipo intero e impostato a 60) vengono denite nella classe; il metodo process confronta quindi il pixel appartenente al frame corrente col corrispettivo pixel nel frame precedente, e se la somma delle dierenze assolute dei valori dei pixel supera la soglia (thres ), viene considerato come pixel attivo e impostando, nellimmagine result, il relativo pixel come bianco (color(255), riga 11 del listato 3.1). Il risultato nale ` e mostrato in gura:

Figura 3.1: Risultato applicazione classe FrameDi

Come ` e possibile osservare in gura 3.1, le parti in movimento (mani e volto) risultano attive e quindi bianche, mentre lo sfondo, che non si muove e non cambia, non viene visualizzato. Dal risultato di questo primo algoritmo ` e possibile calcolare i motiongram.

3.1. ANALISI DELLE CLASSI

15

3.1.2

Classe MotiongramX e MotiongramY

Abbiamo denito, nella sezione 2.1, un motiongram come una rappresentazione del moto nel tempo, e per questo motivo si devono considerare le due direzioni indipendenti tra di loro. Il risultato dellapplicazione di un motiongram ` e quindi unimmagine che descrive il movimento scelto (orizzontale o verticale) e che ne disegna la funzione. Vengono mostrati due esempi di motiongram, uno orizzontale e uno verticale:

Figura 3.2: Visualizzazione motiongram per il movimento orizzontale

Figura 3.3: Visualizzazione motiongram per il movimento verticale

Nelle gure 3.2 e 3.3 il motiongram corrispondente viene visualizzato alla destra dellimmagine elaborata tramite la classe FrameDi (vedi sezione 3.1.1). Si deve specicare che il motiongram per il movimento orizzontale viene disegnato dallalto verso il basso, mentre per quello relativo al movimento verticale landamento ` e da sinistra a destra.

16

CAPITOLO 3. ANALISI DEL SOFTWARE

Viene ora mostrato il codice che applica lalgoritmo per la generazione dei motiongram (viene illustrato solo il codice relativo al motiongram per il movimento orizzontale, poich e le modalit` a sono le stesse anche per il motiongram verticale): Listing 3.2: Classe MotiongramX
1

public class MotiongramX { private PImage frame ; private int currY ; public MotiongramX ( int w , int h ) { this . frame = createImage (w , h , RGB ); this . currY = 0; } public float [] process ( PImage img ) { float [] result = new float [ img . width ]; currY = ( currY + 1) % frame . height ; for ( int x = 0; x < img . width ; x ++) { for ( int y = 0; y < img . height ; y ++) { result [ x ] += brightness ( img . get (x , y )); } result [ x ] /= cam . width ; frame . set (x , currY , color ( result [ x ])); } return result ; } public void display ( int x , int y ) { image ( frame ,x , y ); } }

11

13

15

17

19

21

23

25

Il metodo principale della classe ` e process, un metodo che accetta come ingresso una PImage e restituisce un array di oat (numeri in virgola mobile). Il metodo opera cos` : creazione di result, array di lunghezza pari alla lunghezza della PImage img, creazione di un valore che sposta lindicatore colonna dopo colonna, viene calcolata la media dei valori di luminosit` a di tutti i pixel appartenenti alla colonna, viene aggiornato frame secondo i valori ottenuti; Il procedimento risulta essere simile per il motiongramY, che inverte il ciclo for e cambia lindicatore currY in currX per aggiornare colonna dopo colonna.

3.1. ANALISI DELLE CLASSI

17

Come gi` a indicato ` e stato necessario avere la possibilit` a di separare le due tracce delle mani, per poter avere due tracce distinte anche nel motiongram per il movimento verticale. Si pu` o notare, dalle gure 3.2 e 3.3, che se per il movimento orizzontale ` e possibile visualizzare due tracce, lo stesso non avviene per il movimento verticale (o meglio, sono presenti due tracce quasi sovrapposte). I metodi per separare le due tracce che sono stati sviluppati sono due: considerando le due mani come distribuzioni di probabilit` a bimodali ` e possibile applicare lalgoritmo di Otsu (descritto in sezione 2.2) oppure scegliere di dividere limmagine in due semi-quadrati e dividere cos` le tracce. Entrambe le scelte portano dei problemi, lalgoritmo di Otsu obbliga a considerare sempre due mani, mentre dividere limmagine obbliga il direttore a non spostare troppo le mani in orizzontale, per non invadere laltro semi-quadrato. La seconda opzione ` e stata considerata la migliore, per la possibilit` a di muovere una mano sola. Viene mostrato ora come viene modicato il metodo process, della classe MotiongramY, per la produzione di due motiongram con le tracce corrispondenti alle due mani separate: Listing 3.3: Metodo process nella classe MotiongramY
2

10

12

14

16

18

public float [] process ( PImage img , int thresh ) { float [] result = new float [2* img . width ]; currX = ( currX + 1) % frameL . width ; for ( int y = 0; y < img . height ; y ++) { int j = img . height + y ; for ( int x = 0; x < thresh ; x ++) { result [ y ] += brightness ( img . get (x , y )); } for ( int x = thresh ; x < img . width ; x ++) { result [ j ] += brightness ( img . get (x , y )); } result [ y ] /= img . width ; result [ j ] /= img . width ; frameL . set ( currX , y , color ( result [ y ])); frameR . set ( currX , y , color ( result [ j ])); } return result ; }

Si pu` o osservare come due PImage vengano prodotte da questo metodo, frameL e frameR (entrambe variabili della classe), e di come il metodo usi due cicli for,

18

CAPITOLO 3. ANALISI DEL SOFTWARE

uno per il valore di x che varia da 0 alla soglia 1 mentre il secondo dalla soglia no alla larghezza dellimmagine.

3.1.3

Classe Gesture

La classe Gesture rappresenta il cuore del progetto, riceve in entrata i valori del movimento delle due mani e restituisce linterpretazione di questi valori per gli obbiettivi deniti in questo elaborato. Il lavoro svolto dalla classe e dai suoi metodi consiste quindi nel interpretare come gestualit` a inerente alla direzione musicale il movimento delle mani, secondo i parametri deniti negli obbiettivi (vedi sezione 1.2). Viene di seguito riportata la classe, nella sua interezza, a cui seguir` a la descrizione delle sue parti fondamentali: Listing 3.4: Classe Gesture
2

public class Gesture { float [] prevCoords ; float prevRightY , prevDer ; long prevMills ; int minBeat , beatDirection ; public Gesture ( int minBeat ) { prevCoords = new float [4]; beatDirection = 1; setMinBeat ( minBeat ); } public Gesture () { this (140); } public void setMinBeat ( int minBeat ) { this . minBeat = minBeat ; } public float process ( float leftX , float leftY , float rightX , float rightY ) { float result = 0; float firstDer = rightY - prevRightY ; long mills = millis (); if ( beatRule ( firstDer , mills )) { beatDirection = - beatDirection ; float [] currCoords = new float [4]; currCoords [0] = leftX ; currCoords [1] = leftY ;

10

12

14

16

18

20

22

24

26

28

30

3.1. ANALISI DELLE CLASSI


currCoords [2] = rightX ; currCoords [3] = rightY ; float vol = 0; for ( int i = 0; i < currCoords . length ; i ++) { vol += abs ( currCoords [ i ] - prevCoords [ i ]); } result = beatDirection * vol ; prevMills = mills ; prevCoords = currCoords ; } prevRightY = rightY ; prevDer = firstDer ; return result ; } private boolean beatRule ( float firstDer , long mills ) { if ( beatDirection > 0) { return firstDer >= 0 && prevDer < 0 && mills - prevMills >= minBeat ; } return firstDer <= 0 && prevDer > 0 && mills - prevMills >= minBeat ; } }

19

32

34

36

38

40

42

44

46

48

50

52

Come si osserva nel listato 3.4, la classe Gesture ` e formata dal metodo principale process, che esegue le operazioni richieste, e da attributi interni alla classe e metodi per impostare valori, come la variabile minBeat. I principi sui quali si basa lo sviluppo di questa classe sono stati descritti nella sezione 2.3, e descrivono le modalit` a con cui si ` e deciso di interpretare la gestualit` a riscontrata dalle classi MotiongramX e MotiongramY. Lidea ` e quindi quella di calcolare la derivata prima e seconda del movimento e in base alla condizione che se la derivata prima ` e maggiore o uguale di 0 e la derivata seconda minore di 0 (o viceversa derivata prima ` e minore o uguale di 0 e la derivata seconda maggiore di 0) vericare la presenza di un beat. Per la rumorosit` a dei dati ` e stato necessario aggiungere un ranamento, una miglioria nellalgoritmo e quindi nel codice. Questa miglioria ` e stato implementata nel metodo privato beatrule (riga 46 del listato 3.4. Questo metodo ha il compito di decidere come impostare le due condizioni di ricerca in base alla forma del precedente beat. Attraverso la variabile beatDirection si tiene memoria della direzione del movimento che ha generato il precedente beat; cio` e, se il beat precedente aveva direzione verso il basso allora per ottenere un beat valido la sua direzione deve essere verso lalto. In questo modo si diminuiscono

20

CAPITOLO 3. ANALISI DEL SOFTWARE

sensibilmente i falsi beat dovuti alla rumorosit` a dei dati in ingresso al metodo. La modalit` a con cui viene impiegato questo metodo allinterno della classe, nel metodo process, ` e osservabile a riga 26 del listato 3.4. Inoltre attraverso il metodo process ` e possibile ricavare anche il valore di in` stata tensit` a interpretata a partire dai dati dellalgoritmo di computer vision. E infatti denita come intensit` a (richiesta dal direttore dorchestra) il risultato del calcolo della distanza del beat corrente a quello precedente (pi` u grande ` e la distanza pi` u` e richiesta intensit` a). Ecco che quindi, da riga 28 a 36 (listato 3.4) possiamo osservare come, attraverso un arrray di numeri in virgola mobile, si operi una somma di dierenze assolute tra il valore corrente e il valore precedente, per entrambe le posizioni delle due mani (posizione orizzontale e verticale) determinando cos` il valore di intensit` a. Si pu` o inoltre osservare come il risultato del metodo sia il risultato della moltiplicazione tra lintensit` a (il oat vol ) e la direzione del beat (lintero beatDirection, compreso tra 1 e +1), che permette di ottenere due informazioni con un solo valore; si pu` o constatare infatti che se result = 0 non siamo in presenza di beat, mentre per result = 0 sar` a presente un beat, e allintensit` a corrispondente a |result|.

3.2

Metodo draw()

Nellambiente di sviluppo Processing il metodo draw() rappresenta uno dei metodi fondamentali nellesecuzione di un programma. Bench e java-based Prcessing utilizza delle strutture che la lo rendono diverso dallo standard Java. Non esiste ` doveroso osservare che in infatti nessun metodo main che viene utilizzato. E realt` a il metodo main viene utilizzato, solo che non ` e reso esplicito dallambiente; se infatti si procede a esportare un progetto sviluppato in Processing e si va a e possibile vericare la presenza del metodo vericare il le nome progetto.java ` alla ne del codice. Nellesportare il nostro progetto infatti possiamo notare che come ultime righe di codice il le eyeDirector.java presenta le seguenti righe:
2

static public void main ( String args []) { PApplet . main ( new String [] { " -- present " , " -- bgcolor =#666666 " , " -- hide - stop " , " eyeDirector " }); }

3.2. METODO DRAW()

21

dove ` e osservabile che il metodo main() viene in realt` a usato (essendo lapplicazione esportata in Java). Il metodo draw() in Processing ` e un metodo che viene chiamato subito dopo il metodo setup() (usato per le impostazioni iniziali dellapplicazione) e che esegue ciclicamente le righe di codice al suo interno, no a che lapplicazione non viene fermata, o non viene richiamato un metodo noloop(). Questo metodo ` e chiamato automaticamente dallambiente ed ` e necessario per lutilizzo di alcuni metodi (come mousePressed(), e deve comparire una volta sola nel codice. Viene quindi esposto il codice allinterno del metodo draw(), per vericare come lapplicazione chiama i metodi delle classi sopra descritte (vengono tralasciate le dichiarazioni delle variabili globali dellapplicazione):
2

10

12

14

16

18

20

22

24

public void draw () { if ( cam . available () == true ) { cam . read (); PImage diff = frameDiff . process ( cam ); float [] movX = motiongramX . process ( diff ); splitX . process ( movX ); int thresh = splitX . getThresh (); float [] movY = motiongramY . process ( diff , splitX . getThresh ()); splitY . process ( movY ); if ( splitY . getWeightL () > minMotion ) { leftX = leftX * motionV + splitX . getMeanL () * motionW ; leftY = leftY * motionV + splitY . getMeanL () * motionW ; } if ( splitY . getWeightR () > minMotion ) { rightX = rightX * motionV + splitX . getMeanR () * motionW ; rightY = rightY * motionV + ( splitY . getMeanR () - h ) * motionW ; } float bang = gesture . process ( leftX , leftY , rightX , rightY ); if ( bang != 0) { OscMessage myMessage = new OscMessage ( " / test " ); myMessage . add ( " bang " ); oscP5 . send ( myMessage , m y R e m o t e L o c a t i o n ); } // OUTPUT ON SCREEN image ( diff , 0 , h ); motiongramX . setMarks ( thresh , leftX , rightX ); motiongramX . display (0 , 0); motiongramY . setMarks ( leftY , rightY ); motiongramY . displayL (w , 0); motiongramY . displayR (w , h ); pushMatrix ();

26

28

30

32

22
34

CAPITOLO 3. ANALISI DEL SOFTWARE


translate (0 , h ); // punto grosso dopo un battere , punto piccolo dopo un levare if ( bang > 0) strokeWeight (50); if ( bang < 0) strokeWeight (10); stroke (255 , 0 , 0); point ( leftX , leftY ); stroke (0 , 0 , 255); point ( rightX , rightY ); popMatrix ();

36

38

40

42

}
44

A riga 4 del listato 3.2 si pu` o osservare come venga richiamato il metodo process della classe frameDi (descritta in 3.1.1). In questo modo si avr` a una PImage contenente limmagine a sogliatura di moto. Alle righe 5 e 8 si trova il richiamo del metodo process della classe motiongramX (a riga 5) e della classe motiongramY (a riga 8), con le diverse variabili in ingresso (si veda 3.1.2). Si pu` o anche osservare che a riga 18 viene richiamata il metodo process della classe gesture (si faccia riferimento alla descrizione in 3.1.3), che restituri` a i dati da mandare, tramite protocollo OSC, alla patch in Puredata. Con la descrizione del metodo draw() che racchiude tutti i riferimenti alle classi descritte nel capitolo, viene ora data la descrizione della patch, a cui vengono inviati i dati.

3.3

Analisi della patch in Puredata

In questa parte dellelaborato viene descritta la patch progettata in Puredata, quali sono state le scelte operate per la realizzazione degli obbiettivi posti nella sezione 1.1. Viene prima data una descrizione dellambiente di sviluppo denominato Puredata. Puredata Dal sito uciale del progetto Puredata 1 leggiamo che esso ` e un ambiente di sviluppo, graco ed in tempo reale, per lelaborazione di audio, video e graca. Puredata ` e open source, ed ha una grande numero di sviluppatori che ` stato sviluppato da Miller Puckette lavorano per aggiungere nuove estensioni. E
1

http://puredata.info/

3.4. IMPOSTAZIONE DELLA PATCH PUREDATA

23

negli anni 90, e appare molto simile (sia per gli obbiettivi, che per il design) al progetto sviluppato (sempre da M. Puckette) presso lIRCAM (Institut de Recherche et Coordination Acoustique/Musique ) di Parigi, conosciuto col nome commerciale di Max/MSP. Il forte legame col progetto Max/MSP si denota dalla possibilit` a di sviluppare estensioni che funzionino anche con Max/MSP, e dallobbiettivo di migliorare il paradigma di Max, favorendo un trattamento pi` u aperto ai dati, e alla possibilit` a di estendere le sue applicazioni oltre al mondo dellaudio e del video 2 . Si segnala inoltre che le applicazioni sviluppate in questo ambiente di sviluppo sono chiamate patch, che non ` e compito di questo elaborato nale la spiegazione dettagliata del funzionamento dellambiente (per la qual cosa si rimanda alla numerosa documentazione online), e che per convenzione, poich e si parla di oggetti, gracamente visualizzatti come rettangoli, si utilizzer` a la scrittura [nome delloggetto ] per la descrizione di questi ultimi.

3.4

Impostazione della patch Puredata

` opportuno fornire una descrizione degli oggetti utilizzati, al ne di avere una E visione pi` u precisa del funzionamento della patch. Sono stati usati i seguenti oggetti, di uso non comune in Puredata : [import] Loggetto [import] permette di importare librerie esterne, poich e Puredata non fornisce di base tutte le estensioni possibili, ma lascia libert` a allo sviluppatore di importare quelle pi` u consone per il proprio progetto. Di base Puredata non fornisce oggetti per il supporto al protocollo OSC (descritto nella sottosezione 1.3.1), e neanche uno strumento per la riproduzione di le midi che soddis i requisiti richiesti. La libreria esterna mrpeach ` e risultata essere la pi` u conforme ai requisiti poich e fornisce oggetti sia per lutilizzo del protocollo OSC che per la riproduzione di le midi. [midile] Loggetto [midile] ` e loggetto che permette la riproduzione ed un ` presente nella libreria esterna mrpeach e si dovr` controllo sulla stessa. E a curare di importarla prima di procedere. Loggetto ammette come ingresso una serie
2

ibidem.

24

CAPITOLO 3. ANALISI DEL SOFTWARE

di possibilit` a (riguardo alla riproduzione, poich e attraverso loggetto [midile] ` e possibile anche registrare un le midi): il percorso specico ad un le midi, un [bang] che aumenta di 1 il tick corrente (quindi inserendo un oggetto [metro] ` e possibile riprodurre il le ad una data velocit` a), una message box che sposta il contatore di tick allindirizzo numerico inserito; mentre genera un gran numero di uscite che, opportunamente ltrate tramite loggetto [route], restituiscono valori come il numero di tick al quarto, un [bang] alla ne del le, il numero di traccia, il formato, i microsecondi al quarto, e le singole note on e note o. [udpreceive] Questo oggetto ha la funzione di mettersi in ascolto su una porta scelta, per la ricezione di pacchetti attraverso il protocollo udp, si scrive [udpreceive e un oggetto senza entrate, e come uscita il pacchetto udp ricevuto numero porta ; ` in formato raw byte. [unpackOSC] Lutilizzo di questo oggetto ` e di fondamentale importanza per la traduzione dei pacchetti udp in formato raw byte, in protocollo OSC. Lingresso accetta quindi un messaggio non tradotto e ne fornisce la traduzione.

3.5

Costruzione della patch Puredata

Dopo questa breve introduzione sullutilizzo di Puredata, viene ora descritta la patch; data la grande estensione della stessa, verranno descritti i vari blocchi che presiedono ognuno allo svoglimento di determinati compiti. Si ricorda che loggetto cardine della patch ` e [midile] e che viene importata la libreria mrpeach. La prima parte della descrizione riguarda come ` e stata sviluppata una moda` lit` a per aprire il le midi che si vorr` a riprodurre. E stato accennato che [midile] accetta come ingresso una message box contenente il percorso del le. Per rendere pi` u facile la possibilit` a di cambiare le midi, sfogliando tra le cartelle del proprio disco sso si ` e scelto di operare nel seguente modo: viene usato loggetto [openpanel], che apre una nestra che permette di scegliere un le, nel cui ingresso viene

3.5. COSTRUZIONE DELLA PATCH PUREDATA

25

mandato un [bang] e che in uscita produce la path del le. Viene quindi inserita una message box al cui interno sta listruzione read $1, che mandata in input a [midile] permette il caricamento del midi da riprodurre. Viene mostrata una gura sulla realizzazione graca in Puredata :

Figura 3.4: Premere su Apri File per scegliere il le da aprire. Per modicare le propriet` a di riproduzione del le midi, dobbiamo estrarre da questo alcune informazioni. Una delle soluzioni adottate consiste nel calcolare la distanza, in millisecondi, tra due [bang] e dividendo questo valore per il numero di tick al quarto otteniamo ogni quanti millisecondi deve esserci un tick per andare alla velocit` a impostata. Questo approccio non consente il controllo che ` e presente nel gesto di un direttore dorchestra, perch e elimina le informazioni che riguardano il fatto che ad ogni [bang] corrisponda un quarto. Anche per questa parte viene mostrata la gura della realizzazione in Puredata : Viene inoltre illustrato il procedimento per la riproduzione del le midi, resa possibile dagli oggetti [noteout], poich e il procedimento ` e lungo ma ripetitivo, si da una descrizione del funzionamento base, e verr` a poi mostrata la gura che rappresenta una patch in grado di riprodurre tutte le note a partire da [midile]. Ecco la gura:

26

CAPITOLO 3. ANALISI DEL SOFTWARE

Figura 3.5: Come ricavare quanti millisecondi per tick ci sono dati due quarti

Figura 3.6: Patch per la riproduzione di le midi.

Capitolo 4 Considerazioni nali


4.1 Testing

Qui descrizioni di come il software funziona e reagisce.

4.2

Future works

Qui le migliorie al lavoro.

4.3

Conclusioni

Qui boh.

27

28

CAPITOLO 4. CONSIDERAZIONI FINALI

Bibliograa
[Bor+04] Jan Borchers et al. Personal Orchestra: A real-time audio/video system for interactive conducting. In: ACM Multimedia Systems Journal Special Issue on Multimedia Software Engineering 9.5 (2004), pp. 458 465. url: http : / / media . informatik . rwth - aachen . de / papers . html.

[Bru+07] Bernd Bruegge et al. Pinocchio: conducting a virtual symphony orchestra. In: Proceedings of the international conference on Advances in computer entertainment technology. Salzburg, Austria: ACM, 2007, pp. 294295. isbn: 978-1-59593-640-0. url: http://doi.acm.org/10. 1145/1255047.1255132. [Jen06] Alexander Refsum Jensenius. Using Motiongrams in the Study of Musical Gestures. In: Proceedings of the 2006 International Computer Music Conference. New Orleans, LA: Tulane University, 2006, pp. 499 502. url: http://urn.nb.no/URN:NBN:no-21798. Paul Kolesnik e W. Marcelo. Recognition, Analysis and Performance with Expressive Conducting Gestures. In: In Proceedings of the International Computer Music Conference. 2004. Eric Lee, Thorsten Karrer e Jan Borchers. Toward a Framework for Interactive Systems to Conduct Digital Audio and Video Streams. In: Comput. Music J. 30.1 (mar. 2006), pp. 2136. issn: 0148-9267. doi: 10.1162/014892606776021317. url: http://dx.doi.org/10.1162/ 014892606776021317.

[KM04]

[LKB06]

29

30 [MAJ04]

BIBLIOGRAFIA D. Murphy, T. H. Andersen e K. Jensen. Conducting Audio Files via Computer Vision. In: Gesture-Based Communication in HumanComputer Interaction. Springer Berlin / Heidelberg, 2004, pp. 529 540.

[MHO91] Hideyuki Morita, Shuji Hashimoto e Sadamu Ohteru. A Computer Music System that Follows a Human Conductor. In: Computer 24.7 (lug. 1991), pp. 4453. issn: 0018-9162. doi: 10.1109/2.84835. url: http://dx.doi.org/10.1109/2.84835. [MN00] Teresa Marrin Nakra. Inside the conductors jacket: analysis, interpretation and musical synthesis of expressive gesture. AAI0801701. Tesi di dott. 2000. N. Otsu. A threshold selection method from gray-level histograms. In: IEEE Transactions on Systems, Man and Cybernetics 9.1 (gen. 1979), pp. 6266. Andrew Schmeder, Adrian Freed e David Wessel. Best Practices for Open Sound Control. In: Linux Audio Conference. Utrecht, NL, 2010. Matthew Wright e Adrian Freed. Open Sound Control: A New Protocol for Communicating with Sound Synthesizers. In: International Computer Music Conference. Thessaloniki, Hellas: International Computer Music Association, 1997, pp. 101104. url: http : / / cnmat . berkeley.edu/publications/open_sound_control_new_protocol_ communicating_sound_synthesizers.

[Ots79]

[SFW10]

[WF97]