Giocare con il time lapse


La tecnica fotografica del time-lapse consente di creare filmati in cui ogni fotogramma è acquisito in tempi molto distanti rispetto a quanto avviene durante la riproduzione del video. A causa di questa diversità il tempo nel filmato scorre più velocemente del normale, il che consente di rappresentare eventi della durata di ore nel giro di qualche secondo. Lo scorrere delle nuvole nel cielo, l'apertura di un fiore, addirittura la costruzione di un edificio possono essere accelerati fino a compiersi nel tempo di una clip video. In campo professionale vengono utilizzate video/fotocamere espressamente impostate per questa funzione; in campo amatoriale si rende necessario, ad esempio, modificare il firmware della fotocamera o collegarvi un intervallometro che in tempi opportunamente intervallati (da cui il nome) aziona lo shutter della macchina. E in ambito casalingo? Possono bastare un telefono e una app, anche se in questo modo viene mortificato lo spirito dell'autocostruzione.
Oppure...
Occorre trovare il modo di mettere d'accordo una fotocamera e un dispositivo che la azioni a intervalli cadenzati a piacimento. Per il primo approccio mi sono imposto un basso profilo, quindi la "fotocamera" è in realtà un lettore mp3/mp4 modello "vorreiessereunaipod" con la possibilità di acquisire foto a 2 megapixels. Nientemeno..

L'apparecchio, oltre ad un firmware piuttosto rozzo, ha qualche limite meccanico, dovuto per lo più ai pulsantini di comando che a distanza di anni fanno i capricci. Sono costituiti da una cupolina metallica appoggiata al circuito stampato che si deforma sotto pressione e mette in contatto due piazzole sottostanti. Non è un grosso peccato saldarci due fili e portare il comando di scatto della fotocamera all'esterno del dispositivo. Sono perfino riuscito a rimontare la scocca esterna, lasciando funzionanti i rimanenti pulsanti che servono a navigare nei menu.

Il circuito di azionamento
Il circuito elettronico di azionamento deve provocare lo scatto della fotocamera a intervalli impostabili. Il tempo che deve intercorrere fra un fotogramma e l'altro dipende dalla durata dell'evento da riprendere e da quella desiderata del video. Ad esempio, se vogliamo che ad ogni ora reale corrispondano due secondi di filmato a 30 fotogrammi al secondo, dovremo acquisire 60 fotogrammi ogni 3600 secondi, cioè uno ogni 60 secondi. Ad ogni scadenza del tempo impostato, il timer/intervallometro deve chiudere il contatto di azionamento della fotocamera per qualche frazione di secondo, come farebbe manualmente l'operatore. Un circuito del genere si può realizzare in vari modi, ad esempio collegado in cascata un oscillatore, un divisore di frequenza e un monostabile. Questa è la prima soluzione che ho vagliato, con un CD4060 seguito da un NE555; poi per pigrizia ho dirottato su uno schema con meno componenti:


Il PIC 12F675 ha il suo oscillatore interno e viene istruito per fornire un impulso di mezzo secondo allo scadere del ritardo prefissato. Per impostare il tempo a piacimento, senza riprogrammare il chip, ho utilizzato un ingresso analogico e il relativo convertitore analogico/digitale interno a 10 bit, al quale applico una tensione variabile mediante un potenziometro. In pratica, all'ingresso viene applicata una tensione che, convertita in un valore numerico variabile da 0 a 1023, imposta un ritardo in secondi di pari valore fra uno scatto e l'altro. Il codice necessario si riassume in poche righe:

//_______sorgente per compilatore CCS C__________________
#include <12F675.h> // Seleziona file header del PIC
#device ADC=10 // Seleziona conversione A/D a 10 bit
#fuses INTRC_IO,NOWDT,NOPROTECT,NOMCLR // Imposta i fuses
#use delay(clock=4000000) // Frequenza di clock per il calcolo dei ritardi
void main()
{
unsigned int16 count, dly_sec; // Dichiara le variabili
setup_comparator(NC_NC_NC_NC); // Disattiva i comparatori
setup_adc_ports(sAN1); // Dichiara il pin AN1 per la lettura del canale A/D
setup_adc(ADC_CLOCK_INTERNAL); // Usa il clock interno per la conversione A/D
set_adc_channel(1); // Imposta il canale A/D
while(true)
{
dly_sec = read_adc(); // Legge il valore analogico
output_high (PIN_A0); //
delay_ms(500); // Aziona il relè per mezzo secondo
output_low (PIN_A0); //
delay_ms(500); //
for(count = 0; count < dly_sec; count++)
{
delay_ms(1000); // Ritardo in secondi pari alla lettura del potenziometro (0..1023 sec)
}
}
}

Rudimentale, ma funzionante e sufficiente ad effettuare qualche prova. Ho preferito mantenere un isolamento galvanico fra il circuito e la fotocamera, quindi ho utilizzato un piccolo relè reed per chiudere il circuito di scatto. Inoltre, vista la notevole escursione dei valori di ritardo ottenibili, ho utilizzato un potenziometro multigiri recuperato dal cassetto dei miracoli. Sarebbe bastato un (molto) più economico trimmer, ma almeno non serve il cacciavite per cambiare impostazioni. Il circuito necessita di una alimentazione a 5 volt fornita -ad esempio- da una power bank anche di scarsa qualità visto il consumo esiguo: una decina di mA a relè eccitato, un paio fra uno scatto e l'altro. Volendo alimentare anche la fotocamera e superare il limite della batteria interna, occorre prevedere un apposito circuito.

Realizzare il filmato
Scelto il soggetto, piazzato il treppiede, collegati fra loro i vari apparecchietti e lasciato il tutto in funzione un paio d'ore... salvo imprevisti, potremo scaricare sul pc qualche decina / centinaia di immagini. Fra le varie possibilità per assemblarle in un filmato, ho scelto di utilizzare un programma poco convenzionale: ffmpeg. Fra i motivi della scelta: è open source, cioè sono disponibili i sorgenti (per chi sa cosa farsene) e cross-platform, cioè disponibile per sistemi windows, linux, mac os. La principale contropartita è costituita dalla mancanza di una interfaccia grafica. Tutto avviene dalla linea di comando: una modalità di interazione col pc un po' anacronistica ma a suo modo affascinante, che fa sentire un po' nerd e che, con qualche trucchetto, diventa perfino più immediata del clicca-trascina-rilascia a cui oramai siamo abituati.Prima di "dare in pasto" le immagini a ffmpeg è necessario che vengano rinominate in modo da contenere un indice numerico progressivo. Ho previsto una sottocartella "foto_in" dove memorizzare i fotogrammi e una "video_out" dove salvare il filmato risultante. Della rinomina dei file si occupa uno script batch (in ambiente win) o shell (in linux):

rem RENA.BAT
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set /a cont=0
cd foto
echo > log.txt
for /f "delims=" %%a in ('dir /b /o:n *.jpg') DO (
set /a cont=cont+1
set "C=00000000!cont!"
echo renaming %%a to !C:~-8!.jpg
echo renaming %%a to !C:~-8!.jpg >>log.txt
ren "%%a" !C:~-8!.jpg
)
endlocal
echo done.

Processati dal batch, nella cartella foto_in saranno presenti i file rinominati in 00000001.jpg, 00000002.jpg eccetera. E' il momento di procedere alla codifica del filmato; dopo aver lanciato la console di ffmpeg lanciamo il comando:

ffmpeg -y -framerate 30 -i ../foto_in/%08d.jpg -vf scale=800:600 -vcodec libx264 -r 30 ../video_out/TL_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%.mp4

Questo comando genera un filmato mp4 denominato TL_AAAAGGMM_HHmm.mp4, contenente quindi data e ora di creazione. Riconosco che la sintassi è un tantino complessa, ma considerando che normalmente non è necessario modificare i parametri si tratta solo di copia- incollare la riga di comando sul prompt della console. Giocando con i parametri è possibile modificare tutti i parametri del video, dal formato (mpeg, flv, mp4, gif animate...) alla risoluzione (vf scale=...), correggere luminosità, contrasto, gamma, aggiungere una colonna sonora, zoomare su una regione specifica dei frames... insomma non ho ancora trovato una funzione che non possa essere attivata da qualche parametro passano al programma. Sul sito ffmpeg.org è presente la documentazione completa; in rete si trovano facilmente esempi e tutorial che permettono di arrivare al risultato sperato senza impazzire.
Per quanto riguarda l'ambiente linux la rinomina dei file è affidata ad uno script tipo questo:

#!/bin/bash
# basic file renamer
prog=0
echo > log.txt
for i in $( ls foto_in/*.* );
do
tgt=$(echo $prog | sed -e "s/[0-9]\{1,\}/0000000&/g;s/0*\([0-9]\{8,\}\)/\1/g").jpg
echo $i video_out/$tgt >> log.txt
echo $i video_out/$tgt
cp $i video_out/$tgt
let prog+=1
done
echo Conversione frames completata, creo il video....
echo Indica il frame rate in ingresso, es 1/5, 30....
read frate
echo Indica la risoluzione desiderata,es 640:480...
read res
echo Nome del video?
read nome
ffmpeg -f image2 -framerate $frate -i video_out/%08d.JPG -vcodec libx264 -vf scale=$res -r 30 video_out/$nome.mp4
rm video_out/*.jpg
echo Tutto fatto.

In questo caso ho riunito in un unico script le funzioni di rinomina dei file e di codifica del video.


I primi risultati... Non ho ancora individuato un soggetto adeguato, ma approfittando di un bel pomeriggio di novembre ho puntato l'obiettivo -quasi- a caso e acquisito qualche centinaio di frames e documentato "l'incombere delle tenebre":

In una ulteriore elaborazione ho voluto evidenziare una piccola parte dell'inquadratura originale con il filtro"-vf crop www:xxx:yyy:zzz". Dopo qualche tentativo ecco il risultato:

Risoluzione e definizione delle immagini al minimo sindacale, ma quanto basta a far comprendere in concetto. Infine, nelle ultime fasi di messa a punto del file batch che rinomina le foto, ho pensato di provare un ordinamento inverso, col risultato di (eresia!) invertire la freccia del tempo:

praz2004 chiocciola libero punto it