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 gli
22 stream motion-jpeg come input video.\\
23 La libreria è in grado di acquisire stream tramite i protocolli
24 \mbox{HTTP/HTTPS
} e dispone di alcune classi di aiuto per la
25 generazione di 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 utilizzabili 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 noti 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_isto
}.
149 L'algoritmo applicato allo stream di risoluzione
320x240 mostra un
150 utilizzo di CPU più pesante da parte di CaptureMJPEG in media del
151 11.7\% mentre con lo stream a risoluzione
640x480 l'utilizzo è più
152 pesante da parte della libreria Capture, con un distacco fisso del
154 Si deve considerare inoltre il fatto che CaptureMJPEG utilizza
155 connessioni HTTP remote mentre Capture utilizza il bus USB ad alta
156 velocità del sistema locale.\\
158 I test sono stati eseguiti su un iMac con la seguente configurazione:
160 \textbf{sistema operativo
} \= Mac OS X
10.4.11 \kill
162 \textbf{processore
} \>Intel Core Duo
2GHz (
32 bit, dual core)\\
163 \textbf{memoria RAM
} \>
1GB a
667MHz \\
164 \textbf{sistema operativo
} \> Mac OS X
10.4.11 \\
165 \textbf{processing
} \>
0135 beta \\
169 \subsection{Impressioni qualitative
}
170 \label{sec:impressioni
}
171 Dall'osservazione del comportamento della libreria nei test effettuati,
172 si evince che la modalit\`a di callback ha un comportamento ottimale per la
173 realizzazione di sketch con fine di monitoraggio o di visione delle immagini,
174 dato che tutti i frame provenienti dalla videocamera sono resi disponibili
175 al programmatore. Se invece si vuole applicare trasformazioni alle immagini,
176 mantenendo la sincronia con il flusso proveniente dalla videocamera, allora
177 si consiglia l'uso della modalit\`a senza callback, dato che gli eventuali
178 frame non estratti dal buffer durante le operazioni di processing,
179 sono automaticamente scartati dal sistema superata la soglia del
184 \subsection{Ottenere i sorgenti
}
186 Prima di scaricare i sorgenti è necessario installare
187 Mercurial
\footnote{Mercurial può essere scaricato dal sito
188 http://www.selenic.com/mercurial/
},
189 per la gestione delle versioni ed Ant
\footnote{Ant può essere scaricato
190 dal sito http://ant.apache.org
},
191 per la gestione della compilazione.
193 Per ottenere i sorgenti eseguire la clonazione del repository
194 mercurial disponibile all'indirizzo
195 \texttt{http://dev.abisso.org/capturemjpeg
}
196 dopodiché creare una copia del file
\texttt{user
\_pref.xml.template
}
197 con nome
\texttt{user
\_pref.xml
}.
199 Il file contiene la configurazione di ant per il progetto, tutti i
200 valori di default vanno bene ad eccezione della ``property''
201 \texttt{processing-core
} che deve essere corretta con la path completa
202 al file
\texttt{core.jar
} incluso nella propria installazione di Processing.
204 <property name="processing-core"
205 value="C:
\Programmi\processing-
0135-expert
\lib\core.jar" />
208 A questo punto è necessario eseguire il dowload delle librerie incluse
209 in CaptureMJPEG eseguendo il comando:
214 Quindi è possibile generare l'intera cartella di installazione con
221 \begin{boxedverbatim
}
223 hg clone http://dev.abisso.org/capturemjpeg capturemjpeg
225 cp user_pref.xml.template user_pref.xml
230 Esempio: ottenere i sorgenti da terminale
233 \subsection{Classi utilizzate
}
235 Forniamo ora una descrizione sommaria delle classi sviluppate per la
236 libreria, per una trattazione più approfondita si rimanda alla
237 documentazione JavaDoc disponibile online all'indirizzo
238 http://capturemjpeg.lilik.it/doc/.
239 In
\reffigura{fig:class_diagram1
} e in
\reffigura{fig:class_diagram2
}
240 si pu\`o visualizzare il diagramma delle classi della libreria.\\
241 Il metodo con cui vengono acquisite le immagini dalla videocamera \`e basato
242 sull'identificazione all'interno dello stream HTTP dell'elemento che
243 separa le singole immagini, ovvero il
\texttt{boundary
}.
244 La prima operazione eseguita all'inizializzazione della libreria \`e dunque
245 l'instaurazione di una connessione HTTP al server specificato, tramite le
246 classi
\texttt{HTTPClient
} di Apache. Una volta ottenuta la connessione,
247 l'operazione seguente \`e l'identificazione del boundary, che pu\`o variare
248 a seconda della marca e del modello della videocamera a cui siamo connessi.
249 Il boundary \`e comunque specificato nell'header della risposta HTTP della
250 videocamera, all'interno del campo
\texttt{Content-Type
}. Questo compito
251 \`e svolto dalla classe
\texttt{CaptureMJPEG
}, che implementa quanto illustrato
253 Una volta ottenuto il boundary, le immagini sono estratte dallo stream tramite
254 un meccanismo basato sulla rilevazione dell'identificativo di mime-type
255 proprio delle immagini JPEG. A tal proposito, abbiamo ritenuto
256 oppurtuno implementare una classe,
\texttt{MJPEGInputStream
}, che ereditasse
257 dalla classe
\texttt{java.io.FilteredInputStream
} e che ha il suo metodo
258 fondamentale in
\texttt{byte
[] readImage ()
}, che restituisce un array
259 contenente l'immagine in formato JPEG.\\
260 Dopo l'acquisizione di un'immagine, il codice valuta se sia presente o meno
261 una funzione di callback da invocare e in caso negativo, l'immagine
262 ottenuta viene salvata in un buffer circolare, implementato in
263 \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=
2.0]{img/istogrammi.png
}
309 \caption{Analisi algoritmo blur
}
310 \label{fig:blur_isto
}
314 % \includegraphics[scale=0.9]{scilab/isto_blur_640.png}
315 % \caption{Analisi algoritmo blur 640x480}
316 % \label{fig:blur_640}
320 % \includegraphics[scale=0.9]{scilab/isto_blur_320.png}
321 % \caption{Analisi algoritmo blur 320x240}
322 % \label{fig:blur_320}
327 \includegraphics[scale=
0.7,angle=
90]{img/capturemjpegclass.png
}
328 \caption{Diagramma delle classi di CaptureMJPEG
}
329 \label{fig:class_diagram1
}
333 \includegraphics[scale=
0.9]{img/uribuilders.png
}
334 \caption{Diagramma delle classi dei costruttori di URI
}
335 \label{fig:class_diagram2
}