1 \documentclass[a4paper,
11pt
]{article
}
3 \usepackage[italian
]{babel
}
4 \usepackage[utf8
]{inputenc}
9 \author{Alessio Caiazza, Cosimo Cecchi
}
10 \title{CaptureMJPEG: a MotionJPEG library for Procesing
}
15 \newcommand{\reffigura}[1]{
20 CaptureMJPEG è una libreria per
21 Processing
\footnote{http://processing.org
} che consente di gestire uno
22 stream motion-jpeg come input video.\\
23 La libreria è in grado di acquisire lo stream tramite i protocolli
24 \mbox{HTTP/HTTPS
} e dispone di alcune classi di aiuto per la generazione di
25 URL per le videocamere di rete AXIS e Sony.
30 \section{Introduzione
}
31 \label{sec:introduzione
}
32 %Cosa è stato fatto, come e con quali obiettivi
33 %Presentazione del progetto e del sito
34 All'inizio dello sviluppo di CaptureMJPEG ci siamo chiesti quali
35 fossero le linee guida da seguire. Ci siamo trovati d'accordo sul
36 fatto che la libreria fosse rivolta ad una base di utenza non
37 avanzata, composta da grafici o programmatori alle prime armi. Abbiamo
38 optato quindi per una soluzione che privilegiasse la facilit\`a d'uso
39 rispetto alla complessit\`a e alla ricchezza dell'API offerta,
40 rimanendo in linea con la filosofia di Processing.\\
41 Un esempio di questa scelta si pu\`o rintracciare nella gestione delle
42 eccezioni, trasparente all'utente grazie alla rappresentazione di esse
43 tramite immagini, quindi usabili senza alcun codice aggiuntivo di
44 correzione dell'errore.\\
45 Per facilitare l'apprendimento, una particolare attenzione \`e stata
46 posta nel rispettare le convenzioni delle librerie del core di
47 Processing, prendendo esempio dal comportamento della classe
49 Per lo sviluppo, ci siamo avvalsi di strumenti open-source per la
50 gestione del versionamento e per la creazione di un sito del progetto
51 che fosse allo stesso tempo facile da consultare per gli utenti ma
52 anche ricco di funzionalit\`a rivolte agli sviluppatori. Da questa
53 esigenza \`e nata la scelta di Trac come motore per il sito del
54 progetto. Il VCS che abbiamo scelto per lo sviluppo \`e Mercurial, per
55 la facilit\`a di integrazione con Trac e per la possibilit\`a di
56 effettuare commit e visionare il log del progetto anche offline. Il
57 codice \`e stato sviluppato con Eclipse, grazie al quale abbiamo avuto
58 la possibilit\`a di sperimentare una programmazione task-oriented,
59 grazie all'utilizzo integrato di Mylyn.\\
60 Si \`e scelto infine di utilizzare la tecnica del peer-programming per
61 lo sviluppo, che consiste nello scambiarsi nel ruolo di scrittura e
62 revisione del codice, minimizzando gli errori dovuti a stanchezza e
63 distrazione e il tempo necessario alla revisione del codice e
64 all'apprendimento di gruppo.
68 Guida all'installazione ed utilizzo di CaptureMJPEG
69 \subsection{Installazione
}
70 \label{sec:installazione
}
71 %scopiazzare dal sito e tradurre in italiano
72 Per prima cosa scaricare l'ultima versione di CaptureMJPG dal sito
73 ufficiale http://capturemjpeg.lilik.it .\\
74 Una volta ottenuto l'archivio decomprimerlo all'interno della
75 sottocartella
\texttt{contributed
} del proprio sketchbook, su Linux
76 solitamente è
\texttt{$
\sim$/sketchbook
}, su Mac OS X e Windows
77 è la cartella
\texttt{Processing
} all'interno dei propri documenti.\\
78 Qualora la sottocartella
\texttt{contributed
} non esistesse è
80 A questo punto riavviare Processing.
81 \subsection{Guida all'utilizzo
}
83 %inserire un po' di esempi e spiegare le funzioni utilizzabili
84 La libreria si trova nel package
\texttt{it.lilik.capturemjpeg
}.\\
85 La classe fondamentale \`e
\texttt{CaptureMJPEG
}, che dispone dei metodi
86 necessari per la gestione dello stream e per l'integrazione con processing.
87 Per una documentazione completa sulle classi offerte dal package e i relativi
88 metodi disponibili si rimanda alla documentazione JavaDoc sul sito del
89 progetto.
\footnote{http://capturemjpeg.lilik.it/doc/
}\\
91 Per ottenere un oggetto di tipo
\texttt{CaptureMJPEG
} \`e necessario invocare
92 il suo costruttore con l'URI della videocamera come parametro. Per questa
93 finalit\`a, la libreria mette a disposizione delle classi per creare facilmente
94 gli URI a partire dalla marca della videocamera, correntemente sono
95 implementate solo quelle per le videocamere Sony e AXIS.\\
96 Una volta ottenuto l'oggetto
\texttt{CaptureMJPEG
} abbiamo a disposizione due
97 modalit\`a per gestire lo stream proveniente dalla videocamera. La prima,
98 chiamata modalit\`a di callback, prevede la definizione di un metodo
99 all'interno dello sketch, che verr\`a invocato dalla libreria ogni volta che
100 un nuovo fotogramma \`e pronto. La modalit\`a senza callback, invece, prevede
101 che i fotogrammi siano salvati, non appena disponibili, in un buffer circolare
102 interno alla libreria e accessibile tramite il metodo
\texttt{getImage ()
}.\\
103 Un programmatore che usa la libreria ha la garanzia che il flusso restituito
104 sar\`a sempre costituito da immagini. Infatti gli eventuali errori sono gestiti
105 internamente alla libreria, che provveder\`a a creare delle immagini con una
106 descrizione testuale dell'errore in caso di problemi.
107 \subsubsection{Esempi
}
108 \label{sec:utilizzo_esempi
}
109 Qui di seguito sono illustrati vari esempi di utilizzo della libreria.\\
111 L'esempio in
\reffigura{fig:basic_usage
} illustra l'utilizzo di base di CaptureMJPEG.
112 Si nota la funzione di callback
\texttt{captureMJPEGEvent
}, invocata dalla libreria quando
113 sono disonibili nuovi frame. In questo esempio \`e utilizzato il parser di
114 default per gli URI. Si noti che in questo caso \`e necessario specificare
115 l'URI completo di protocollo.\\
117 Il secondo esempio in
\reffigura{fig:vendor_specific
} illustra la modalit\`a
118 d'uso dei costruttori di URI specializzati. In questo caso \`e necessario
119 inserire solamente l'host come parametro del costruttore dell'URI.\\
121 Il terzo esempio in
\reffigura{fig:buffer_usage
} illustra l'utilizzo del buffer
122 interno alla libreria. Si noti l'utilizzo del metodo
\texttt{getImage ()
} per
123 ottenere il fotogramma successivo dello stream.\\
125 Infine, l'esempio in
\reffigura{fig:adaptive_fsize
} mostra come sia possibile
126 far s\`i che la dimensione dell'applet si adatti alla dimensione dello stream,
127 attraverso la chiamata al metodo
\texttt{setAdaptiveFrameSize ()
}.\\
132 \subsection{Comparazione dell'algoritmo blur fra CaptureMJPEG e Capture
}
133 \label{sec:comparazione
}
135 %Studio della libreria eseguito con il codice di prova
136 L'analisi è stata svolta applicando un filtro
\texttt{blur
} allo
137 stream ottenuto con CaptureMJPEG e con la videocamera locale
138 utilizzando la libreria Capture
\footnote{la libreria Capture è fornita
139 in bundle con Processing.
}.\\
140 I sorgenti utilizzati sono quelli in
\reffigura{fig:micc_blur
} per
141 CaptureMJPEG e in
\reffigura{fig:capture_blur
} per Capture.
142 Sono stati misurati l'utilizzo di memoria e di CPU al variare delle
143 dimensioni del filmato e del framerate richiesto allo sketch.\\
144 L'analisi ha riportato un utilizzo di memoria minore per la libreria
145 CaptureMJPEG,
30MB contro
40MB per il filmato a risoluzione
320x240 e
146 50MB contro
60MB per il filmato a risoluzione
640x480.\\
148 L'utilizzo di CPU è riportato in
\reffigura{fig:blur_640
} e in
149 \reffigura{fig:blur_320
}.
150 L'algoritmo applicato allo stream di risoluzione
320x240 mostra un
151 utilizzo di CPU più pesante da parte di CaptureMJPEG in media del
152 11.7\% mentre con lo stream a risoluzione
640x480 l'utilizzo è più
153 pesante da parte della libreria Capture, con un distacco fisso del
155 Si deve considerare inoltre il fatto che CaptureMJPEG utilizza
156 connessioni HTTP remote mentre Capture utilizza il bus USB ad alta
157 velocità del sistema locale.\\
159 I test sono stati eseguiti su un iMac con la seguente configurazione:
161 \textbf{sistema operativo
} \= Mac OS X
10.4.11 \kill
163 \textbf{processore
} \>Intel Core Duo
2GHz (
32 bit, dual core)\\
164 \textbf{memoria RAM
} \>
1GB a
667MHz \\
165 \textbf{sistema operativo
} \> Mac OS X
10.4.11 \\
166 \textbf{processing
} \>
0135 beta \\
170 \subsection{Impressioni qualitative
}
171 \label{sec:impressioni
}
172 Dall'osservazione del comportamento della libreria nei test effettuati,
173 si evince che la modalit\`a di callback ha un comportamento ottimale per la
174 realizzazione di sketch con fine di monitoraggio o di visione delle immagini,
175 dato che tutti i frame provenienti dalla videocamera sono resi disponibili
176 al programmatore. Se invece si vuole applicare trasformazioni alle immagini,
177 mantenendo la sincronia con il flusso proveniente dalla videocamera, allora
178 si consiglia l'uso della modalit\`a senza callback, dato che gli eventuali
179 frame non estratti dal buffer, perch\'e impegnati in operazioni di processing,
180 sono automaticamente scartati dal sistema.
184 Come continuare lo sviluppo
185 \subsection{Ottenere i sorgenti
}
187 Prima di scaricare i sorgenti è necessario installare
188 Mercurial
\footnote{Mercurial può essere scaricato dal sito
189 http://www.selenic.com/mercurial/
},
190 per la gestione dei sorgenti ed Ant
\footnote{Ant può essere scaricato
191 dal sito http://ant.apache.org
},
192 per la gestione della compilazione.
194 Per ottenere i sorgenti eseguire la clonazione del repository
195 mercurial disponibile all'indirizzo
196 \texttt{http://dev.abisso.org/capturemjpeg
}
197 dopodiché creare una copia del file
\texttt{user
\_pref.xml.template
}
198 con nome
\texttt{user
\_pref.xml
}.
200 Il file contiene la configurazione di ant per il progetto, tutti i
201 valori di default vanno bene ad eccezione della ``property''
202 \texttt{processing-core
} che deve essere corretta con la path completa
203 al file
\texttt{core.jar
} incluso nella propria installazione di Processing.
205 <property name="processing-core"
206 value="C:
\Programmi\processing-
0135-expert
\lib\core.jar" />
209 A questo punto è necessario eseguire il dowload delle librerie incluse
210 in CaptureMJPEG eseguendo il comando:
215 Quindi è possibile generare l'intera cartella di installazione con
222 \begin{boxedverbatim
}
224 hg clone http://dev.abisso.org/capturemjpeg capturemjpeg
226 cp user_pref.xml.template user_pref.xml
231 Esempio: ottenere i sorgenti da terminale
234 \subsection{Classi utilizzate
}
236 Forniamo ora una descrizione sommaria delle classi sviluppate per la
237 libreria, per una trattazione più approfondita si rimanda alla
238 documentazione JavaDoc disponibile online all'indirizzo
239 http://capturemjpeg.lilik.it/doc/.
240 In
\reffigura{fig:class_diagram1
} e in
\reffigura{fig:class_diagram2
}
241 si pu\`o visualizzare il diagramma delle classi della libreria.\\
242 Il metodo con cui vengono acquisite le immagini dalla videocamera \`e basato
243 sull'identificazione all'interno dello stream HTTP proveniente da essa,
244 dell'elemento che separa le singole immagini, ovvero il
\texttt{boundary
}.
245 La prima operazione eseguita all'inizializzazione della libreria \`e dunque
246 l'instaurazione di una connessione HTTP al server specificato, tramite le
247 classi
\texttt{HTTPClient
} di Apache. Una volta ottenuta la connessione,
248 l'operazione seguente \`e l'identificazione del boundary, che pu\`o variare
249 a seconda della marca e del modello della videocamera a cui siamo connessi.
250 Il boundary \`e comunque specificato nell'header della risposta HTTP della
251 videocamera, all'interno del campo
\texttt{Content-Type
}. Questo compito
252 \`e svolto dalla classe
\texttt{CaptureMJPEG
}, che implementa quanto illustrato
254 Una volta ottenuto il boundary, le immagini sono estratte dallo stream tramite
255 un meccanismo basato sulla rilevazione dell'identificativo di mime-type
256 proprio delle immagini JPEG. A tal proposito, abbiamo ritenuto
257 oppurtuno implementare una classe,
\texttt{MJPEGInputStream
}, che ereditasse
258 dalla classe
\texttt{java.io.FilteredInputStream
} e che ha il suo metodo
259 fondamentale in
\texttt{byte
[] readImage ()
}, che restituisce un array
260 contenente l'immagine in formato JPEG.\\
261 Dopo l'acquisizione di un'immagine, il codice valuta se sia presente o meno
262 il meccanismo di callback e in caso negativo, l'immagine ottenuta viene salvata
263 in un buffer circolare, implementato in
\texttt{CircularBuffer
}.\\
264 La classe
\texttt{ErrorImage
} si occupa di generare immagini rappresentanti
265 un'eventuale errore nel processo, mentre le classi
\texttt{AxisURL
} e
266 \texttt{SonyURL
} hanno il compito di costruire un URL a partire dai parametri
267 specifici supportati dalle videocamere della relativa marca.
271 \lstinputlisting[language=Java,numbers=left,frame=shadowbox
]{sources/basic_usage.pde
}
272 \caption{Esempio di utilizzo base
}
273 \label{fig:basic_usage
}
277 \lstinputlisting[language=Java,numbers=left,frame=shadowbox
]{sources/vendor_specific.pde
}
278 \caption{Utilizzo dei costruttori specializzati
}
279 \label{fig:vendor_specific
}
283 \lstinputlisting[language=Java,numbers=left,frame=shadowbox
]{sources/buffer_usage.pde
}
284 \caption{Esempio dell'utilizzo del buffer
}
285 \label{fig:buffer_usage
}
289 \lstinputlisting[language=Java,numbers=left,frame=shadowbox
]{sources/adaptive_fsize.pde
}
290 \caption{Utilizzo della dimensione adattiva
}
291 \label{fig:adaptive_fsize
}
295 \lstinputlisting[language=Java,numbers=left,frame=shadowbox
]{sources/micc_blur.pde
}
296 \caption{Sorgente di test CaptureMJPEG
}
297 \label{fig:micc_blur
}
301 \lstinputlisting[language=Java,numbers=left,frame=shadowbox
]{sources/capture_blur.pde
}
302 \caption{Sorgente di test Capture
}
303 \label{fig:capture_blur
}
308 \includegraphics[scale=
0.9]{scilab/isto_blur_640.png
}
309 \caption{Analisi algoritmo blur
640x480
}
314 \includegraphics[scale=
0.9]{scilab/isto_blur_320.png
}
315 \caption{Analisi algoritmo blur
320x240
}
321 \includegraphics[scale=
0.7,angle=
90]{img/capturemjpegclass.png
}
322 \caption{Diagramma delle classi di CaptureMJPEG
}
323 \label{fig:class_diagram1
}
327 \includegraphics[scale=
0.9]{img/uribuilders.png
}
328 \caption{Diagramma delle classi dei costruttori di URI
}
329 \label{fig:class_diagram2
}