martedì 25 novembre 2008

Java Media Framework eqepa tutorial 2: input da webcam

Introduzione
In questo tutorial vedremo come sia possibile accedere tramite il Java Media Framework all'input proveniente da webcam.
Consigliamo di leggere prima il primo tutorial che eqepa ha scritto sull'utilizzo del framework, lì sono presenti tutte le informazioni e i download necessari per iniziare ad usare il JMF.
Il codice di questo esempio è scaricabile da qui, consiglio di leggere il tutorial insieme al codice, spiegherò passo per passo il funzionamento del programma.


Iniziamo...
Caricate il progetto in NetBeans, possiamo vedere che il programma è composto da tre classi il cui funzionamento dovrebbe essere già chiaro a chi ha capito il primo tutorial presentato da eqepa:
- Main.java: contiene il cuore dell'applicazione.
- MyControllerListener.java: necessaria per il corretto import delle componenti grafiche del player.
- ContenitoreManiglie.java: necessaria per la comunicazione tra Main e MyControllerListener.

Apriamo Main.java ed analizziamola: innanzitutto vediamo che estende la classe JFrame quindi avrà una controparte grafica, inoltre essa ha come attributi un Player, un MediaLocator, un Component e un oggetto di tipo MyControllerListener.
Partiamo dal costruttore Main(): in questo metodo vengono chiamati settaggioInterfaccia(), settaggioPlayer() e poi viene chiamato il metodo setDefaultCloseOperation che associa la pressione del tasto "X" della finestra alla chiusura del programma.
Il metodo settaggioInterfaccia() registra l'oggetto di tipo Main appena istanziato (se stesso) nel contenitoreManiglie tramite il metodo statico setMain e associa un borderLayout al frame.
Passiamo ora al metodo settaggioPlayer(): innanzitutto istanziamo il mediaLocator relativo all'input della webcam tramite la funzione setMediaLocator.
Il mediaLocator descrive la posizione del contenuto multimediale che verrà poi "trattato" dal Player; per quanto riguarda la webcam come input multimediale ho trovato vari metodi per ottenerne la posizione:
uno di tali metodi, trovato qui e implementato nella funzione autoDetect() consiste nel farsi restituire una lista dei device riconosciuti nel sistema dal metodo getDeviceList del CaptureDeviceManager.
A partire da questa lista si selezionano solo i device il cui nome inizia per "vfw" (video for windows, per quanto riguarda linux la sigla da utilizzare è "v4l"). Ho provato a reimplementare tale metodo per costruire questo tutorial ma ho riscontrato molta lentezza dell'applicazione (che ancora non riesco a spiegarmi) e il fatto che il metodo getDeviceList() su menzionato non restituisce alcun elemento.
La soluzione trovata (che potrebbe essere poco professionale in quanto non generale) è stata quella di utilizzare uno dei programmini utili che l'istallazione del JMF include: jmfregistry.exe (ritrovabile nella sottocartella bin della cartella di istallazione di JMF).
Questo programma contiene tutte le informazioni dei device presenti nel sistema, quindi, anche il locator del "video device" che nel mio caso è "vfw://0". Al momento non ho controllato il funzionamento di tale programma su altri computer con webcam diversa dalla mia o con più webcam installate (a breve per un aggiornamento).
Tornando quindi al nostro codice istanziamo il nostro bel mediaLocator passando al suo costruttore la stringa del device video "vfw://0". Se il mediaLocator è stato istanziato procediamo con la creazione del Player tramite il metodo setPlayer() e associamo a quest'ultimo il ControllerListener da noi implementato.
A questo punto il player partirà e, quando sarà realizzato, chiamerà il metodo realizeComplete del ControllerListener associato ad esso, metodo che noi abbiamo prontamente ridefinito (ovverride) per chiamare la funzione setComponentiVisuali() di Main.
Infine la funzione setComponentiVisuali prende la visualComponent del player e la aggiunge al Frame.
Facciamo il run ed ecco il risultato (ovvero uno scorcio del disordine nella camera mia e di emilio):

A questo punto vi prego di riportarci bug nel codice. A presto per il prossimo tutorial dove "grabberemo" e memorizzeremo un'immagine jpeg a partire dalla webcam, punto di lancio per poter manipolare i frame provenienti dalla webcam per implementare motion e color detection.

7 commenti:

Anonimo ha detto...

questa guida ha potenzialità enormi!! ottimo lavoro ragazzi!!

Sant'Ennio ha detto...

Grazie mille Riccardo, mi raccomando, se trovi errori comunicaceli!

Enry ha detto...

se dovessi svilupparelo per mac??? Come dovrei modificare il detector ??

Sant'Ennio ha detto...

Ciao Enry, non ho esperienza con Mac ma se l'installazione del framework non cambia quest'ultima dovrebbe aver istallato anche un programmino che si chiama JMStudio. In tal caso andando su file->preferences si apre JMF Registry Editor. Nella tab Capture Devices si trovano tutte le periferiche riconosciute dal Framework con i relativi Locator, sostituendo la stringa del locator dovrebbe funzionare. Su windows seguendo questa procedura funziona. Facci sapere in modo da poter aggiornare la guida anche per gli utenti mac. Grazie.

Enry ha detto...

Eccomi, ho montato sul mio mac JMStudio ma anche questo non riesce a fare detection della mia cam, riesce solo su sistemi linux e window.
In alternativa se uno deve utilizzare solo l'audio puo tranquillamente utilizzarlo anche su mac.

Ho ripiegato su opencv che e' una libreria sviluppata da intel che da la possibilita' di far la stessa cosa anche in c e c++.

Macomani usate opencv.

Sant'Ennio ha detto...

Grazie mille del tuo contributo Enry!

Unknown ha detto...

ciao a tutti! è ancora possibile avere il codice del progetto? perchè il link non è più funzionante purtroppo... Comunque bellissimo progetto!!

Posta un commento