Files
Titano/Titano
Alby96andClaude Opus 5 db21a31e56 Scheda Archivio, ottimizzazione per sezione e spiegazioni a comparsa
Aggiunge l'importazione da scheda di memoria e riordina l'interfaccia attorno
a quello che ciascuna sezione serve a fare.

L'importazione riconosce i supporti collegati, cerca nelle sottocartelle e
prima di toccare il disco mostra il piano: quali cartelle nasceranno e che nome
avranno i primi file. Un'importazione sbagliata su mille file non si annulla, e
guardare prima costa un istante. Fa poi tre cose che a mano si sbagliano
sempre: separa le sessioni sulla pausa fra due scatti, invece di lasciare piu'
riprese mescolate in una cartella sola; costruisce i nomi da modelli con
segnaposto, perche' un archivio si consulta anni dopo e il nome e' l'unica cosa
leggibile senza aprire nulla; e rilegge quello che ha scritto confrontandone
l'impronta, perche' una scheda che si scollega a meta' copia produce file della
dimensione giusta e del contenuto troncato, e il danno si scopre mesi dopo.

Sulla conversione in DNG va detto con precisione cosa si puo' e non si puo'
fare. Un DNG vero contiene i valori del sensore prima dell'interpolazione
cromatica; ottenerlo da un formato proprietario richiede la libreria del
produttore, che il vincolo sulle dipendenze esclude. Quello che si ottiene
in-house e' un DNG lineare - la specifica lo prevede, i pixel sono gia'
interpolati, il file e' valido e apribile ovunque ma non restituisce la
liberta' del grezzo. La copia resta quindi la scelta predefinita, e l'interfaccia
lo dice invece di lasciarlo intuire. Il contenitore TIFF/DNG e' scritto a mano
come il multiplexer MP4, e la verifica lo rilegge con il parser di questo stesso
programma: due implementazioni indipendenti dello stesso formato, e al primo
confronto e' saltato fuori un errore di dodici byte per voce nel calcolo degli
scostamenti - la directory Exif finiva oltre il puntatore che la indicava.

Le spiegazioni passano dalle note stampate ai suggerimenti a comparsa. Una nota
sotto un cursore occupa spazio a chi la conosce gia', quindi deve restare corta;
un suggerimento che appare solo quando serve non ha quel vincolo e puo' dire
l'unica cosa che conta - perche' quel parametro esiste e cosa succede a
spostarlo nel verso sbagliato.

Ogni sezione guadagna un comando Ottimizza che rileva le impostazioni migliori
per quella sola parte e riferisce cosa ha cambiato e perche'. Si distingue dal
pilota automatico, che lavora di continuo sui parametri deducibili senza
ambiguita': l'ottimizzazione si chiede a mano perche' accende e spegne interi
moduli, e sostituire quelle scelte in silenzio sarebbe peggio che lasciarle
sbagliate. Dove il dato manca non tira a indovinare: lo dice.

L'uscita guadagna rapporto e ritaglio. Cambiare rapporto non deforma piu'
l'immagine: il ritaglio viene preso con il nuovo rapporto dentro il fotogramma,
il che ha anche corretto un difetto latente dello stadio geometrico, che con
rapporti diversi fra sorgente e uscita stirava invece di tagliare. La zona da
tenere si sceglie trascinandola.

I comandi seguono la sezione: importazione e analisi compaiono solo dove
servono. Un pulsante che non ha senso dove ci si trova non va disabilitato ma
tolto, perche' disabilitato resta un ingombro che chiede perche' non funziona.
Le preferenze dell'applicazione non mostrano piu' anteprima, riepilogo della
sequenza ne' riga di stato che ne parli: non riguardano la sequenza caricata, e
tenerle accanto confondeva due piani diversi.

Via anche le descrizioni inutili: la finestra si chiama Titano e basta.

Due difetti trovati durante la verifica a video. La barra di navigazione nasceva
sulla prima voce, che ora e' Archivio, quindi il selettore usciva subito perche'
l'indice coincideva e la sezione non veniva mai mostrata: barra su una voce,
contenuto su un'altra. E il posizionamento dei pulsanti leggeva Visible, che in
WinForms resta falso finche' la finestra non e' stata mostrata perche' riporta
la visibilita' dell'intera catena: alla costruzione nessun pulsante veniva
collocato e restavano tutti impilati sull'angolo.

Verifica: da 54 a 60 controlli. I nuovi coprono i modelli di percorso, la
sostituzione dei caratteri illegali, il rifiuto dei segnaposto inventati, il
riconoscimento delle sessioni e la rilettura del DNG scritto - sia dal parser
interno sia dal decodificatore di sistema.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 23:09:54 +02:00
..

Titano

Applicazione desktop per la creazione e l'ottimizzazione di time-lapse di livello professionale, sviluppata interamente in-house.

Il vincolo che definisce il progetto

Zero librerie di terze parti. Il file di progetto non contiene alcun <PackageReference>: tutto ciò che non è la libreria standard di .NET è scritto qui dentro oppure ottenuto tramite P/Invoke diretto verso componenti del sistema operativo.

Ambito Come è risolto
Parsing EXIF / XMP Parser binario proprietario (Metadata/)
Analisi fotometrica e deflicker Algoritmi proprietari (Analysis/)
Campo vettoriale e motion blur Schema differenziale piramidale proprietario (Motion/)
Trasformata di Fourier CooleyTukey a base due, in loco (Motion/Fourier.cs)
Segmentazione e stabilizzazione Otsu, gradiente e correlazione di fase proprietarie
Interpolazione di curve Spline monotona e Bézier proprietarie (Core/Spline.cs)
Contenitore MP4 Multiplexer ISO-BMFF proprietario (Video/Mp4Muxer.cs)
Decodifica immagini WIC, componente di Windows, via COM interop scritto a mano
Codifica video Media Foundation Transform, encoder hardware di sistema
Interfaccia grafica WinForms + GDI+, ogni controllo disegnato a mano (UI/)

Non viene invocato nessun processo esterno: niente FFmpeg, niente ExifTool.

Principi architetturali

Il video è l'unico file che sopravvive. Il flusso compresso viene prodotto in streaming: ftyp e l'header mdat all'apertura, i pacchetti dell'encoder direttamente nel file, moov in chiusura. L'elaborazione può creare un solo altro file — il parcheggio temporaneo dei fotogrammi descritto più sotto — che nasce con la cancellazione automatica alla chiusura e non contiene nulla di riutilizzabile.

Impronta di memoria governata, non incidentale. I fotogrammi vivono in array float presi da un pool (Imaging/ImageBuffer.cs) e passano da una finestra scorrevole (Pipeline/FrameWindow.cs). L'occupazione dipende dall'ampiezza della finestra — che l'utente sceglie — e mai dalla lunghezza della sequenza: la verifica automatica lo misura esplicitamente.

Interfaccia reattiva. Ingestion, analisi e render girano su thread di lavoro; il thread dell'interfaccia riceve solo aggiornamenti di stato immutabili tramite IProgress<T>.

Struttura

Metadata/    parser binario TIFF/Exif, scanner XMP, riconoscimento contenitori
Core/        sequenza, cadenza, shutter angle, spline monotona e Bézier
Imaging/     buffer poolati, spazio colore lineare, decodifica WIC, geometria, scrittura TIFF/DNG
Analysis/    luminanza, deflicker, segmentazione in regioni, transizioni giorno-notte
Motion/      Fourier, correlazione di fase, stabilizzazione, optical flow, blur, stacking
Video/       conversione NV12, encoder Media Foundation, multiplexer MP4
Pipeline/    piano di rendering, finestra scorrevole, direttore automatico, importazione
UI/          tema scuro, navigazione, strumenti di misura, editor di curve e keyframe
Diagnostics/ sequenze sintetiche, verifica end-to-end, ispettore MP4

L'interfaccia

La navigazione è una barra verticale sul fianco sinistro, e governa insieme il contenuto principale e la colonna delle impostazioni: una sezione, una vista, i suoi comandi. In verticale ci sta il nome per esteso, e la sezione scelta resta leggibile mentre si lavora — cosa che in una fila di schede in cima si perde appena l'occhio scende sul contenuto. Accanto a ciascuna voce compare il numero di avvisi che la riguardano.

L'anteprima invece resta sempre in alto, qualunque sezione sia scelta, perché in un programma che tratta immagini l'immagine non è il contenuto di una scheda fra le altre. Ha quattro strumenti che la rendono utilizzabile per giudicare e non solo per guardare:

  • zoom e trascinamento, perché una stabilizzazione sotto il pixel o il bordo di una scia non si vedono su un'immagine rimpicciolita per stare in un riquadro; da scala uno a uno in su i pixel si mostrano come sono, senza interpolazione che nasconda proprio ciò che si vuole controllare;
  • confronto a tendina fra originale e corretto, trascinabile, perché l'unico modo di capire cosa una correzione stia facendo è vedere accanto ciò che c'era prima;
  • campo vettoriale sovrapposto, che il motore calcola comunque, e che spiega in un colpo d'occhio perché la sfocatura viene come viene — soprattutto quando è sbagliata;
  • confine delle regioni, campionato attraverso la stessa mappatura del ritaglio, così la linea resta al suo posto anche quando l'anteprima mostra una panoramica virtuale.

Le sezioni portano ciascuna lo strumento di misura che le riguarda: la striscia dei provini e gli avvisi sulla sequenza, istogramma e forma d'onda sull'esposizione, il percorso ricostruito della stabilizzazione sul movimento, il piano temporale sul tempo. Tutte grandezze che il motore già calcolava e che finivano in due numeri in fondo a una riga di stato.

Archivio e importazione

La scheda Archivio scarica una scheda di memoria e la mette a posto. Riconosce i supporti collegati — quelli rimovibili e quelli che contengono una cartella DCIM — cerca nelle sottocartelle, e prima di toccare il disco mostra il piano: quali cartelle verranno create e che nome avranno i primi file. Un'importazione sbagliata su mille file non si annulla, e vedere prima costa un istante.

Fa tre cose che a mano si sbagliano sempre.

Riconosce le sessioni. Una scheda contiene di norma più riprese; separarle sulla pausa fra due scatti evita di doverle distinguere dopo guardando gli orari. I gruppi troppo piccoli confluiscono nel precedente invece di generare una cartella propria: quasi sempre sono gli scatti di prova fatti prima di cominciare.

Costruisce i nomi da una regola. Cartelle e file nascono da modelli con segnaposto — {anno}/{data} {fotocamera} e {data}_{ora}_{n:0000} — perché un archivio si consulta anni dopo e il nome è l'unica cosa leggibile senza aprire nulla. I caratteri che il file system rifiuta vengono sostituiti, mai lasciati passare.

Verifica quello che ha scritto. Dopo la copia rilegge entrambi i file e ne confronta l'impronta. Non è zelo: una scheda che si scollega a metà copia produce file della dimensione giusta e del contenuto troncato, e il danno si scopre mesi dopo, quando l'originale non c'è più.

Sulla conversione in DNG

La copia resta l'impostazione predefinita, ed è quasi sempre la scelta giusta: conserva il grezzo, quindi la libertà di rifare lo sviluppo.

Va detto con precisione cosa il programma può e non può fare. Un DNG vero contiene i valori del sensore prima dell'interpolazione cromatica, ed è quello che permette di rifare da capo bilanciamento del bianco e demosaicizzazione. Ottenerlo da un formato proprietario richiede di interpretare quel sensore modello per modello, cioè la libreria del produttore — che il vincolo sulle dipendenze esclude.

Quello che si può fare in-house è un DNG lineare: la specifica lo prevede (PhotometricInterpretation 34892), contiene pixel già interpolati a 16 bit in luce lineare, ed è un file valido e apribile ovunque. Non restituisce però la libertà del grezzo. Insieme a TIFF 16 bit e JPEG serve a consegnare qualcosa a un altro programma, non ad archiviare.

Il contenitore è scritto a mano, come il multiplexer MP4. La verifica automatica lo rilegge con il parser TIFF di questo stesso programma: sono due implementazioni indipendenti dello stesso formato, e alla prima esecuzione il confronto ha trovato un errore di dodici byte per voce nel calcolo degli scostamenti.

Il pilota automatico

I parametri che si possono dedurre dalle misure non si chiedono. Un cursore con l'indicatore auto mostra il valore che il programma ha scelto e il motivo per cui l'ha scelto; toccarlo passa il comando all'utente, e l'indicatore lo restituisce. È lo stesso modello che il menu dell'orientamento usava da solo, esteso a tutti i parametri deducibili.

Parametro Da cosa viene dedotto
Larghezza della passata di analisi metà della risoluzione nativa, entro i limiti utili
Finestra del deflicker quattro periodi dello sfarfallio, misurati sull'autocorrelazione
Lunghezza della transizione metà della distanza tipica fra i cambi di esposizione
Finestra della stabilizzazione la più corta che rende liscio il percorso
Tetto di memoria 45% di quanto il sistema dichiara disponibile

Vale una regola sopra tutte: dove il valore giusto non si può misurare, il direttore non inventa — restituisce meno decisioni e lascia il cursore dov'è.

Ogni sezione ha inoltre un comando Ottimizza che rileva le impostazioni migliori per quella sola parte e dice cosa ha cambiato e perché. Si distingue dal pilota automatico, che lavora di continuo sui parametri deducibili senza ambiguità: l'ottimizzazione si chiede a mano perché prende decisioni più impegnative, comprese quelle di accendere o spegnere interi moduli, e sostituirle senza dirlo sarebbe peggio che lasciarle sbagliate. Dove il dato manca — la sequenza non è ancora stata analizzata — non tira a indovinare: lo dice.

Le spiegazioni non stanno sotto ai controlli ma nei suggerimenti che compaiono passandoci sopra. Una nota stampata occupa spazio a chi la conosce già, e per questo deve restare corta; un suggerimento che compare solo quando serve può dire l'unica cosa che conta davvero — perché quel parametro esiste, e cosa succede a spostarlo nella direzione sbagliata.

Il riquadro sponsor

La codifica di una sequenza lunga sono minuti o decine di minuti in cui non c'è niente da fare. È l'unico momento in cui uno spazio pubblicitario non toglie niente a nessuno, ed è per questo che compare soltanto nella scheda Esportazione: accanto a un cursore che si sta regolando sarebbe un ostacolo, accanto a una barra di avanzamento è qualcosa da guardare.

Gli annunci si leggono da una cartella locale, con un elenco chiamato campagne.txt nello stesso formato delle preferenze. Il programma non contatta alcun servizio, non invia identificativi e non registra i clic. È una scelta, non una mancanza: un circuito pubblicitario vero richiederebbe di integrarne l'SDK, che il vincolo sulle dipendenze esclude, e comunque significherebbe far uscire dati dalla macchina di chi sta soltanto montando un time-lapse. Le campagne si aggiornano copiando file in una cartella. Quando il listino è vuoto compaiono note interne sul funzionamento del programma, e l'intero riquadro si spegne dalle preferenze.

Il piano di rendering

Il motore non percorre la sequenza sorgente: percorre un elenco di fotogrammi d'uscita, ognuno con la propria posizione — anche frazionaria — e la propria durata. Durata costante, durata proporzionale all'intervallo, cadenza uniformata e rimappatura non lineare producono tutte quella stessa forma, quindi il ciclo di rendering è uno solo e non contiene un ramo per ciascuna modalità.

Una posizione frazionaria significa un fotogramma che non esiste e va sintetizzato dal campo vettoriale. Da qui discende anche la sfocatura: se un fotogramma d'uscita copre v scatti, l'angolo di otturatore effettivo è quello di ripresa diviso v, e la scia da sintetizzare si scala della stessa quantità. Accelerare e rallentare restano quindi coerenti con la fisica dell'esposizione invece di essere un semplice salto di indici.

Note sugli algoritmi

Deflicker. Per ogni fotogramma si esegue una regressione lineare locale pesata sulla finestra mobile. I pesi combinano una gaussiana sulla distanza temporale e, in seconda passata, un peso di robustezza di Tukey che neutralizza i fotogrammi anomali. La componente lineare segue senza ritardo le rampe reali di luce (alba, tramonto) e rimuove solo la componente ad alta frequenza dovuta alle micro-variazioni del diaframma. La misura è la media logaritmica troncata: invariante alla scala, insensibile a cieli bruciati e ombre chiuse.

Motion blur. Lo shutter angle reale è 360 × posa / intervallo. La scia già incisa nel fotogramma e quella sintetica si compongono in quadratura, quindi per raggiungere l'apertura obiettivo serve una scia di √(obiettivo² reale²) volte lo spostamento: sommare linearmente produrrebbe un'immagine sistematicamente troppo morbida. Il filtro di ricostruzione è di tipo gather: un campione contribuisce al pixel centrale solo se la propria scia lo raggiunge davvero, così lo sfondo fermo non viene trascinato nei soggetti in movimento.

Optical flow. Schema differenziale piramidale: su ogni nodo di una griglia rada si risolve iterativamente il sistema normale 2×2 costruito dai gradienti spaziali e dalla differenza temporale. Un filtro mediano fra un livello e l'altro elimina i vettori spuri delle zone piatte. L'analisi avviene a risoluzione ridotta e i vettori vengono riportati in scala piena: il costo non dipende dalla dimensione dei file sorgente. Il campo si calcola solo quando serve davvero: se la posa copre già più dell'apertura obiettivo — il caso delle riprese notturne, con pose da trenta secondi su intervalli da trentaquattro — non c'è sfocatura da sintetizzare e la voce di spesa più pesante della pipeline viene saltata.

Moduli avanzati

Stabilizzazione sub-pixel. Lo spostamento fra fotogrammi adiacenti si misura con la correlazione di fase: una traslazione nello spazio è uno sfasamento lineare in frequenza, e normalizzando lo spettro incrociato al modulo unitario resta solo la fase, la cui antitrasformata è un impulso posto sullo spostamento. Il metodo ignora quindi per costruzione le differenze di luminosità fra due scatti — che in un time-lapse ci sono sempre — e reagisce alla sola geometria. Sotto il pixel la superficie di correlazione viene ricostruita a passo fine valutando direttamente la somma di Fourier sulle posizioni intermedie, invece di interpolare con una parabola tre campioni di una cresta che parabola non è: l'errore misurato scende da 0,14 a 0,08 px. Nove riquadri per coppia danno nove misure indipendenti, da cui si stima ai minimi quadrati una similitudine — traslazione, rotazione e scala — scartando i riquadri occupati da nuvole o fronde, che si muovono per conto loro. Il percorso assoluto viene infine lisciato: ciò che resta fra percorso vero e percorso liscio è il tremolio, e la sua inversa è la correzione. Una panoramica voluta sopravvive perché è già liscia.

Deflicker per regioni. Una nuvola densa che attraversa il cielo abbassa la luminanza media del fotogramma; il deflicker legge un calo di luce e schiarisce tutto, paesaggio compreso, che invece non era cambiato. Titano divide il fotogramma in due regioni e dà a ciascuna la propria curva. La maschera nasce una volta sola dalla mediana temporale di un campione di fotogrammi — la mediana toglie di mezzo proprio ciò che passa e non resta.

La linea d'orizzonte è il gradino più marcato del profilo di luminanza per riga, e viene poi agganciata colonna per colonna al massimo del gradiente verticale. Il verso del gradino non conta: cercare invece "la prima riga sotto soglia scendendo dall'alto" presuppone un cielo chiaro e sgombro sopra la testa, e su una ripresa notturna fatta da sotto un pergolato quella regola aggancia il bordo del tetto e chiama cielo le travi. Quando sopra la linea finisce comunque un primo piano, la divisione lo dichiara e indica quella per luminanza, che non fa ipotesi sulla forma.

Sulla sequenza reale della cometa il paesaggio passa da 0,156 a 0,020 stop di oscillazione: l'87% dello sfarfallio che la curva globale gli avrebbe trasmesso non lo raggiunge.

Transizioni giorno-notte. Attraversando il tramonto la macchina deve cambiare tempo, ISO o diaframma, e ogni cambio è quantizzato: nel filmato si vede uno scalino netto. Il deflicker ordinario non aiuta, perché un gradino non è rumore da mediare e la finestra mobile lo trasforma in una rampa con due spigoli. Titano legge invece l'ampiezza esatta nei metadati — il valore di esposizione vale log2(N²/t) log2(ISO/100) — e la ridistribuisce su una transizione a derivata nulla agli estremi, lunga a piacere. Il deflicker lavora poi sulla serie già priva di gradini. Il bilanciamento del bianco riceve un trattamento parallelo: si liscia il rapporto fra i canali invece della loro luminanza, così sparisce il tremolio del bilanciamento automatico e resta il viaggio verso il caldo del tramonto.

La temperatura di colore si ricava con l'approssimazione di McCamy, ma solo dove ha senso: fuori dall'intorno del luogo di Planck il polinomio diverge, e su un cielo notturno — dove il colore medio non somiglia a nessun corpo nero — restituiva decine di migliaia di kelvin. Adesso in quel caso si dichiara inapplicabile invece di produrre un numero dall'aria plausibile. Quello che resta sempre definito, e che il motore corregge davvero, è la deviazione verde-magenta in stop.

Movimento di macchina virtuale. Un sensore da dodici megapixel contiene un 4K con abbondante margine di ritaglio: da lì si ricava una panoramica che in ripresa avrebbe richiesto una slitta motorizzata, decisa dopo, guardando il materiale. Fra un nodo e il successivo il tempo passa per una curva di Bézier con estremi fissi — senza, il movimento partirebbe e si fermerebbe di colpo, e a velocità di time-lapse lo scatto si vede benissimo. Ritaglio e correzione di stabilizzazione sono entrambi affini e vengono composti in una sola trasformazione: il fotogramma viene interpolato una volta sola, con una cubica di Catmull-Rom.

Rimappatura non lineare del tempo. Una curva di velocità dice quanti scatti vengono consumati per ogni fotogramma d'uscita: sopra 1 la sequenza accelera saltando scatti, sotto 1 rallenta e i mancanti vengono sintetizzati. La velocità del filmato resta fissa. La spline è monotona per costruzione (schema di FritschCarlson): una Catmull-Rom ordinaria sovraelongerebbe fra due nodi molto diversi, e una velocità negativa farebbe tornare indietro la sequenza.

Accumulo temporale. La mediana su una finestra di fotogrammi dà a ogni pixel il valore centrale della propria serie: la scena stabile resta se stessa, chi attraversa l'inquadratura una volta sola sparisce. Una media lascerebbe un fantasma tanto più visibile quanto più l'intruso era contrastato. Il massimo progressivo conserva invece il valore più alto incontrato e trasforma le stelle in archi continui; con una lunghezza di scia finita l'accumulo decade e le scie hanno una coda invece di riempire il cielo. Se la stabilizzazione è attiva i fotogrammi vengono sovrapposti dopo averli raddrizzati, altrimenti la mediana scambierebbe per intruso il tremolio stesso.

Memoria e parcheggio su disco

I moduli avanzati hanno rotto l'assunto su cui la pipeline originale era costruita: che bastassero due fotogrammi vivi alla volta. La mediana ne vuole un'intera finestra simultaneamente, la rimappatura può chiedere lo stesso scatto per molti fotogrammi d'uscita consecutivi.

La regola di residenza è una sola e non produce mai andirivieni: la finestra attiva sta sempre in memoria, perché chi la usa ha bisogno di tutti i suoi fotogrammi insieme; i fotogrammi letti in anticipo — che servono a tenere occupati tutti i processori sulla decodifica dei RAW, la parte più lenta della pipeline — finiscono su disco quando il tetto di memoria è raggiunto, e vengono ripresi una volta sola, quando entrano nella finestra. Non esiste un caso in cui lo stesso fotogramma vada e torni dal disco più volte. Il file di parcheggio nasce con l'opzione di cancellazione alla chiusura: se il programma termina male, lo rimuove il sistema.

Sorgenti RAW e limiti dei codec

I file RAW e DNG non espongono l'immagine principale nella prima directory: quella è una miniatura, e le dimensioni vere vivono in una SubIFD marcata come non ridotta. Titano sceglie la directory dell'immagine principale invece di fidarsi della prima, e legge i metadati con una finestra che si estende su richiesta: di un DNG da 15 MiB ne tocca 128 KiB.

Orientamento. Il tag Exif dice come raddrizzare l'immagine, ma non basta leggerlo: alcuni decodificatori di sistema lo applicano già per conto proprio e altri no. Applicarlo una seconda volta ribalta il fotogramma, non applicarlo mai lo lascia coricato. In modalità automatica Titano confronta le dimensioni che il decodificatore restituisce con quelle che il file dichiara di contenere e decide di conseguenza; la sezione Generale mostra cosa ha dedotto e permette di imporre una trasformazione diversa, con riscontro immediato nell'anteprima.

Qualità. Il profilo di elaborazione governa finezza della griglia del campo vettoriale, livelli della piramide, iterazioni per livello, campioni per pixel della scia e risoluzione della passata fotometrica. Il valore predefinito è "Massima": costa circa tre volte il tempo di "Standard" e si vede nei bordi dei soggetti in movimento.

La risoluzione di lavoro viene infine ricondotta ai limiti del codec. Un encoder hardware accetta volentieri un fotogramma 4000×3000 e dichiara un livello alto: il flusso è formalmente valido ma supera il Livello 5.2 di H.264, e i decodificatori comuni si rifiutano di aprirlo. Il video uscirebbe, peserebbe, e non si riprodurrebbe. Titano riduce quindi il fotogramma al massimo riproducibile conservando le proporzioni, e lo dichiara in interfaccia. Le sorgenti 16:9 fino al 4K UHD non vengono toccate.

Cosa ha insegnato il materiale vero

I moduli avanzati sono stati provati su quattro sequenze reali — da 554 a 1005 scatti in DNG, riprese notturne di comete e aurore con una GoPro HERO8 — dopo essere già passati da cinquantaquattro controlli su scene sintetiche. Le scene sintetiche sono costruite perché la risposta sia nota, e per questo non possono sorprendere: tutto ciò che segue è emerso solo dai file veri, e ha portato a correzioni nel motore.

La ricerca dell'orizzonte agganciava la tettoia. Una delle riprese è fatta da sotto un pergolato: travi scure in cima, cielo nel mezzo, alberi e case in fondo. Sul tratto notturno di quella sequenza la vecchia regola — "la prima riga sotto soglia scendendo dall'alto" — trovava il bordo del tetto e chiamava cielo le travi, il 7% dell'inquadratura e per giunta più scuro del resto. Sulla ripresa di sedici ore l'errore si vedeva sull'intera sequenza: cielo al 29% e separazione nulla fra le due regioni, cioè una divisione che non portava alcuna informazione. Sostituita con il gradino più marcato del profilo di luminanza per riga, che non presuppone un cielo chiaro in cima e funziona anche quando il cielo è il più scuro dei due: 91% dell'inquadratura e 1,9 EV di separazione, con lo sfarfallio trasmesso al paesaggio ridotto del 79% invece che del 57%.

La temperatura di colore inventava numeri. Su un cielo stellato il colore medio non somiglia a nessun corpo nero, l'approssimazione di McCamy diverge e usciva un intervallo da 1000 a 40000 K, troncato agli estremi. Ora fuori dall'intorno del luogo di Planck la misura si dichiara inapplicabile. Il controllo che verifica la nuova regola ha subito trovato un buco nel primo tentativo di filtro: un riquadro sulle coordinate cromatiche lascia passare un rosso saturo, perché sa dire in quale zona si è ma non quanto si è vicini a una curva.

La correlazione di fase inseguiva spostamenti inventati. Una ripresa attraversa sedici ore con pose da trenta secondi, quindi di giorno esce completamente bruciata. Su un riquadro uniforme la normalizzazione al modulo unitario amplifica il solo rumore numerico e l'antitrasformata dà un picco qualunque: la stabilizzazione misurava 9,8 px di tremolio medio, 181 px di punta, e chiedeva di ritagliare il 15% dell'inquadratura. Con un controllo di tessitura sul riquadro il tremolio scende a 0,07 px e il ritaglio a 0,1%.

I gradini dichiarati non sempre si vedono. Se il fotogramma è già saturo, dimezzare la sensibilità non lo scurisce: sopra il bianco non c'è niente da togliere. Sottrarre comunque il gradino letto nei metadati introduceva nel segnale un salto che nell'immagine non esisteva. Ora ogni gradino viene ridotto alla quota che la luminanza ha davvero recepito; su quella sequenza 7 cambi su 17 risultano non recepiti e vengono lasciati stare.

La curva obiettivo poteva essere più a scatti del segnale che lisciava. È il difetto più serio, e stava nel nucleo del deflicker, non nei moduli nuovi. La robustezza di Tukey presuppone anomalie sparse; dove invece un tratto contiguo si discosta — il crollo di luce del crepuscolo — azzera l'intera finestra, e la stima commutava fra "uso i soli sopravvissuti" e "uso tutto" aprendo uno scalino di 2,3 stop proprio dove serviva la massima continuità. Adesso le due stime si mescolano con continuità secondo quanta finestra è sopravvissuta. Sulla ripresa di sedici ore la riduzione dello sfarfallio passa dal 17% al 67%, e il salto massimo della curva obiettivo da 1,73 a 0,21 stop.

Le scie stellari sono state verificate sull'uscita vera con la proprietà che le definisce: la luminanza non può calare, perché ogni pixel trattiene il valore più alto incontrato. Su 150 fotogrammi cresce di 1,6 volte ed è non decrescente sul 99,3% dei passi — il resto è il rumore della compressione.

Sul costo: con stabilizzazione, mediana, movimento virtuale e rimappatura tutti attivi insieme, al profilo Massima e a 1920×1440, il rendering va a 0,7 fotogrammi al secondo. È il baratto che il profilo dichiara, e si sceglie dal pannello Generale.

Compilazione ed esecuzione

dotnet build -c Release
dotnet run  -c Release

Richiede .NET 10 SDK su Windows x64.

Verifica automatica

Titano.exe --selftest [cartella]

Genera sequenze sintetiche dalle proprietà note e le fa attraversare l'intera pipeline, confrontando 60 grandezze misurate con i valori attesi. Nessuna soglia è scelta a posteriori: la scena è costruita perché il valore atteso sia la conseguenza aritmetica di come è stata generata — il tremolio ha un percorso noto, il gradino di esposizione un'ampiezza dichiarata nei metadati e visibile nei pixel, la nuvola attraversa il solo cielo.

Copre campi Exif, cadenza e shutter angle; riduzione dello sfarfallio e conservazione della rampa di luce; invarianza della luminanza alla scala di decodifica; correlazione di fase sotto il pixel; misura e rimozione del tremolio con la panoramica voluta che sopravvive; copertura della maschera delle regioni; riconoscimento e ridistribuzione dei cambi di esposizione; lisciatura cromatica con la deriva del tramonto conservata; monotonia e simmetria delle curve di accelerazione; trasparenza e ritaglio dello stadio geometrico; monotonia della rimappatura temporale; rimozione dell'intruso da parte della mediana e conservazione dei passaggi da parte del massimo; la garanzia che la curva lisciata non sia mai più a scatti del segnale che liscia, nemmeno quando un tratto contiguo di fotogrammi si discosta; il rifiuto di dichiarare una temperatura di colore dove non ne esiste una; allineamento delle NAL dentro ogni campione del contenitore; e — prova conclusiva — un rendering con tutti i moduli attivi insieme, con tetto di memoria volutamente stretto per esercitare il parcheggio su disco, riletto poi dal lettore di sistema.

Titano.exe --diagnose <cartella> [uscita.mp4] [fotogrammi] [larghezza] [h264|hevc]
                      [avanzato] [luminanza] [camera] [mediana|scie] [analisi=N]

Riporta cosa il programma riesce davvero a leggere da una cartella reale: metadati file per file, dimensione dichiarata contro dimensione decodificata, coerenza della luminanza fra risoluzioni diverse, cadenza sull'intera sequenza. Indicando un file di uscita esegue anche un render di prova e ne riverifica il contenitore. È lo strumento con cui si distingue un difetto del motore da un formato che il sistema non sa aprire.

Le parole chiave finali, in qualunque ordine, accendono i moduli avanzati e aggiungono una sezione che riporta cosa ciascuno ha trovato: entità del tremolio e ritaglio necessario, forma della maschera e quanto la curva di regione stabilizza il paesaggio rispetto a quella globale, numero e ampiezza dei cambi di impostazione, escursione della tinta. luminanza divide per luminanza invece che per linea d'orizzonte, camera aggiunge movimento virtuale e rimappatura del tempo al render di prova, mediana e scie scelgono l'accumulo temporale, analisi=N limita l'analisi ai primi N fotogrammi — contigui, perché la stabilizzazione confronta ogni fotogramma con il precedente.

È lo strumento che ha fatto emergere i due difetti visibili solo su materiale vero: la ricerca dell'orizzonte che agganciava il bordo di una tettoia, e la temperatura di colore che su un cielo notturno restituiva decine di migliaia di kelvin invece di dichiararsi inapplicabile.

Titano.exe --capture <file.png> [cartella-sequenza] [scheda] [avanzato]

Cattura l'interfaccia in un'immagine, per verificarne la resa in modo riproducibile. Con avanzato i moduli opzionali vengono accesi prima del caricamento, così l'immagine mostra curve di regione, marcatori dei cambi di esposizione, percorso della macchina virtuale e contorno delle regioni con dati veri invece che a riposo.

Titano.exe --make-icon <file.ico>

Ridisegna l'icona dell'applicazione — scie stellari attorno al polo celeste, l'immagine in cui il tempo diventa visibile — e ne scrive il contenitore ICO a mano. I livelli sotto i venti pixel ricevono meno archi e più spessi: alla dimensione della barra delle applicazioni sette scie sottili diventerebbero una macchia.