Introduzione

Strumenti contro macchine, artigianato contro industria

Nel suo libro, La società tecnologica (1954), Jacques Ellul presenta la differenza tra l’epoca pre- e post-rivoluzione industriale nel modo seguente:

L’era preindustriale è il regno dello strumento e dell’artigianato. La proprietà principale degli strumenti è di essere generici, versatili e adattabili. Spetta all’artigiano sviluppare le proprie abilità per far seguire agli strumenti la sua intenzione, così che la mano compensi i limiti dello strumento. Questo concetto è ancora ben noto ai musicisti di oggi: bisogna esercitarsi, imparare, provare, fallire, riprovare… non ci sono scorciatoie. Ellul sottolinea l’idea di parsimonia che accompagna gli strumenti: le risorse sono limitate, quindi il tuo insieme di strumenti è praticamente definito da ciò che puoi permetterti, trasportare, padroneggiare e costruire localmente. Le tendenze cambiano lentamente e sono locali, perché usano risorse locali e si adattano a bisogni locali, e gli strumenti seguono lo stesso schema. Gli strumenti sono cimeli tramandati dal maestro all’apprendista, dal genitore al figlio. Non diventano incompatibili né obsoleti.

L’era industriale è il regno della macchina. Nasce da una cultura della standardizzazione e della massificazione. La macchina è molto più produttiva perché è specializzata per un solo compito, ma è inutile per tutto il resto e raramente può essere adattata a un altro uso. Quando i bisogni produttivi cambiano, la macchina viene sostituita da un’altra perché non serve a nulla. Questo non è più uno schema parsimonioso, ed è consentito perché le risorse sono molto più economiche e la produzione di massa permette economie di scala. Poi gli esseri umani diventano i servitori della macchina, e l’artigianato diventa un lusso.

Le produzioni che un tempo si facevano in casa o in piccole botteghe, in un contesto familiare, vengono spostate in grandi fabbriche, dove c’è spazio sufficiente per le macchine. Del resto, questo ha avuto effetti molto concreti sul modo in cui organizziamo la nostra vita quotidiana, compreso quando e quante volte mangiamo1, così come sui ritmi del sonno2. Quindi non è esagerato dire che la rivoluzione industriale ha anche cambiato profondamente il modo in cui pensiamo, ciò che consideriamo normale o evidente.

Questo mi ha colpito perché è così che avevo sviluppato gli strumenti di editing del colore, in modo intuitivo, fin dall’inizio: cercando di costruire strumenti generici che si basassero sul minor numero di presupposti per restare versatili, dando al contempo un controllo fine sui parametri dell’immagine, e affidandomi in ultima analisi alle abilità degli artigiani piuttosto che a strumenti mezzi rotti, non validati e auto-magici che funzionano solo nei casi ideali.

Fotografia digitale: automatizzare o godersi il processo?

Non ho mai capito la passione di molti fotografi, specialmente i più tecnofili, per i flussi di lavoro a pulsante e le procedure automatizzate. Ho imparato e insegnato il pianoforte, e sono abituato al paradigma stai zitto ed esercitati: allenarsi per sviluppare e mantenere l’agilità, e poi ripetere le stesse poche battute ancora e ancora finché il suono non è giusto. Lavorare la qualità, la trama e l’espressività del suono, attraverso la quantità di peso che metti sui tasti, la velocità dell’attacco, il movimento del polso e dell’avambraccio. Usare il proprio corpo per il movimento fine e allenarlo oltre le sue attuali capacità, trasformando gesti molto innaturali in riflessi. E infine, imparare a sentire nella mente il suono che stai cercando di raggiungere, prima ancora di muovere le mani. Tutte quelle cose che non saranno mai riducibili a cursori e pulsanti dell’interfaccia grafica, metriche, variabili o algoritmi.

Il modo in cui molti fotografi si avvicinano all’editing fotografico suona come se fossero stati puniti dalla fotografia digitale, perché ora devono usare un software per ottenere le loro foto. Quindi dovrebbe essere ridotta a una procedura senz’anima in cui tutto dovrebbe essere automatizzato se possibile. Ci scambiamo preset e ricette, alcuni le vendono persino. E ora abbiamo l’IA per emulare uno stile o un altro. Dov’è la gioia nell’industrializzare la creazione artistica? Che senso ha avere un hobby che sembra il peso di dover sviluppare le proprie foto? L’arte è un processo, non una procedura. Quale mente malata progetterebbe un robot che fa ceramica, incisioni o composizioni floreali al posto tuo? Che ne dici di usare il software come un’occasione per rifinire l’aspetto delle tue immagini secondo il tuo gusto e la tua sensibilità? Abbiamo perso il piacere grezzo di fare le cose da soli, anche male? A che età si perde questo appetito?

Certo, combattere contro un software di editing fotografico è un’esperienza frustrante, ma devi capire contro cosa stai combattendo. È solo la difficoltà intrinseca del tuo mestiere e la tua mancanza di abilità, o è la cattiva progettazione dello strumento? Quando fatichi su un pianoforte da 25 k€ appena revisionato dal tecnico, sai che lo strumento non è il problema. Ma con il software, come fai a saperlo? Beh, non puoi finché non ti dedichi pienamente al paradigma stai zitto ed esercitati. I bravi ritoccatori otterranno buoni risultati da qualsiasi software, la differenza sta in quanto tempo ci metteranno. E, beh, a volte devi fare un sacco di lavoro di copertura per i modelli di colore rotti delle applicazioni di editing.

Gli strumenti nell’interfaccia grafica dell’editing fotografico

In termini di progettazione dell’interfaccia utente, la parsimonia di strumenti generici e versatili è il modo migliore per evitare di essere sopraffatti da decine di funzioni che si nascondono a vicenda, si sovrappongono nella funzionalità e non fanno che inquinare il tuo campo visivo. È il feng shui del software. Ma poi, la natura degli strumenti si sposta un po'.

Ci sono due modi di pensare ai controlli del colore dell’elaborazione delle immagini: dal loro uso funzionale, e dal modo in cui permettono di manipolare le proprietà del colore. Dal loro uso funzionale:

FunzioneMetodi
Riduzione del rumoreFiltraggio wavelet, non-local means, filtro bilaterale, filtro guidato, diffusione,
DeblurDeconvoluzione di Richardson-Lucy, piramide gaussiana/laplaciana, filtro passa-alto, filtraggio wavelet, contro-diffusione, maschera di contrasto
SfocaturaFiltraggio wavelet, diffusione, filtro bilaterale, filtro guidato
SchiarireCorrezione dell’esposizione, curva dei toni, funzione di trasferimento di potenza (“gamma”), miscelatore di canali
Bilanciamento del biancoNormalizzazione per canale, trasformazione di adattamento cromatico, miscelatore di canali
Spostamento del coloreMiscelatore di canali, lift-gamma-gain, slope-offset-power, rotazione della tonalità, LUT
Aumento della vivacità cromaticaSaturazione, croma, vividezza, LUT
Aumento del contrastoCurva dei toni, funzioni di trasferimento sigmoidali, normalizzazione dell’intervallo (“livelli”), LUT
Compressione della gamma dinamicaCome il contrasto, ma in modalità “riduci” invece che in modalità “aumenta”

Nota che lo spostamento del colore potrebbe essere ulteriormente suddiviso in due modalità: correttiva (che richiede modelli di luce) e creativa (che richiede modelli percettivi). Non ci spingeremo così lontano.

Se affrontiamo la stessa lista dall’altro punto di ingresso, il modo in cui permettono di manipolare le proprietà del colore, otteniamo:

MetodoFunzioni
Filtraggio waveletRiduzione del rumore, Deblur, Sfocatura
DiffusioneRiduzione del rumore, Deblur, Sfocatura
Miscelatore di canaliSchiarire, Spostamento del colore, Bilanciamento del bianco
LUTAumento del contrasto, Spostamento del colore, Aumento della vivacità cromatica
Curva dei toniSchiarire, Aumento del contrasto, Compressione della gamma dinamica

Non ho rifatto tutta la lista ma hai capito l’idea: che tu voglia classificare la tua lista di strumenti per metodo o per funzione, non ottieni una corrispondenza 1:1, tranne che per alcuni. Quindi nessuna di queste mappature ti permette di fattorizzare sistematicamente i tuoi strumenti in elementi unitari dell’interfaccia grafica, così da onorare il principio di parsimonia.

E poi, l’elaborazione delle immagini non è solo un insieme di strumenti in una scatola, è in realtà una pipeline di filtri di pixel che devono essere inseriti come nodi di un grafo in un ordine che corrisponda ai requisiti di input dei filtri. Ecco qua (semplificato):

flowchart TD
    r(Raw input) --> d1[Raw denoise]
    d1 --> demosaic[Demosaic]
    demosaic --> d2[RGB denoise]
    d2 --> wb[White balance]
    wb --> bright1["Brightness enhancement (linear)"]
    bright1 --> blur1[Blur / Deblur]
    blur1 --> color_lin["Color shift (linear)"]
    color_lin --> contrast1["Contrast enhancement / Brightness enhancement (non-linear)"]
    contrast1 --> color_nl["Color shift (non-linear) / Colorfulness enhancement"]
    color_nl --> dr[Dynamic range compression]
    dr --> o(Output)

E, ultimo ma non meno importante, il problema che nessuno vede: la matematica. Per esempio, un filtro guidato applicato a una maschera di opacità e guidato dall’immagine RGB (come nel raffinamento delle maschere di Ansel/Darktable) non ha la stessa matematica di un filtro guidato applicato a una maschera di luminanza e guidato da se stesso (come nell’equalizzatore dei toni), o di un’immagine RGB completa guidata da se stessa (come nella rimozione della foschia). Questi devono essere implementati più volte, con diversi tipi di input e diversi tipi di ottimizzazioni. Lo stesso vale per i metodi che lavorano su immagini non demosaicizzate: dobbiamo tenere conto del fatto che non abbiamo un segnale RGB completo a ogni sensel, e le matrici XTrans richiedono una matematica speciale diversa da quella di Bayer.

Quindi, dato che:

  1. le funzionalità hanno metodi diversi,
  2. i metodi non possono essere ridotti a una singola funzionalità,
  3. tutti vengono inseriti come nodi in una pipeline dove l’ordine conta,
  4. i metodi hanno variazioni di implementazione a seconda del loro segnale di input, cioè della loro posizione nella pipeline,
  5. gli utenti vogliono divertirsi senza dover imparare nulla,
  6. il disordine dell’interfaccia grafica non serve a nessuno e stanca tutti,

…abbiamo un problema: come suddividere le funzioni e organizzarle come un’interfaccia grafica coerente?

In una configurazione professionale, dove ci si può aspettare che gli utenti sappiano costruire una pipeline da soli e comprendano i dettagli dei suoi nodi, puoi seguire la strada di DaVinci Resolve e costruire un editor nodale. Poi costruisci un nodo per metodo, e gestisci internamente le varianti di implementazione controllando il tipo di segnale di input. Questo è il modo più minimalista, perché non c’è alcuna duplicazione dell’interfaccia grafica: solo un insieme di nodi, e i nodi possono essere impostati in parallelo anziché forzati in sequenza. Ma richiede utenti esperti.

La strada di Lightroom/Capture One è di nascondere completamente che esista persino una pipeline, e fornire un’interfaccia grafica piatta. Poi la multi-istanziazione dei nodi avviene tramite le maschere: aggiungere nuove maschere ti permette di assegnare loro un sottoinsieme dei controlli del software per modificare selettivamente le regioni mascherate. Ma questo comporta anche il fatto che nessuna di queste applicazioni consente l’editing lineare riferito alla scena (scene-referred), il che rende traballanti la sfocatura, il deblur, la riduzione del rumore e le transizioni effettive delle maschere.

Ansel segue una via di mezzo. Innanzitutto, ora c’è un prototipo di editor nodale:

image
image

Questo ci permette di mostrare esplicitamente l’ordine della pipeline, riordinarlo manualmente e cambiare i preset di ordinamento, in un modo che mostra anche input e output. In precedenza, avevamo solo la pila di moduli dell’interfaccia grafica nella barra laterale destra, che in un certo senso suggeriva l’ordine della pipeline se letta come una pila di livelli, ma veniva spesso usata impropriamente dagli utenti come una semplice comodità di riordinamento della cassetta degli attrezzi dell’interfaccia grafica.

E poi, la suddivisione delle funzioni è ibrida:

  • I moduli equalizzatore del contrasto, contrasto locale e diffondi o rendi nitido sono intrinsecamente duali nella loro natura: possono aumentare o diminuire il contrasto locale e la nitidezza a seconda dei loro parametri. L’equalizzatore del contrasto ha persino un metodo di riduzione del rumore, il che ha senso perché la resa della nitidezza aumenta il rumore, quindi il posto giusto per tenerlo sotto controllo è dove viene creato. Questi sono moduli method-first (guidati dal metodo).
  • Il bilanciamento del bianco duplica la funzionalità della parte di adattamento cromatico della calibrazione del colore. Il bilanciamento del bianco è una semplice normalizzazione per canale che avviene nell’RGB del sensore, ed è necessaria per alcuni metodi di demosaicizzazione (specialmente per i sensori XTrans), mentre la calibrazione del colore esegue una compensazione dell’illuminante molto più accurata dal punto di vista percettivo nello spazio CIE CAT16. Quello spazio è definito a partire dallo spazio CIE XYZ 1931, che otteniamo solo dopo la profilazione del colore in input (e questo richiede un’immagine demosaicizzata per funzionare). Ci sono ragioni ed esigenze diverse per entrambi, e devono trovarsi in posizioni diverse nella pipeline. Questi sono moduli pipeline-first (guidati dalla pipeline): pur sembrando funzionalmente simili, le loro ragioni di esistenza e i loro requisiti interni (e la matematica completamente diversa) li rendono molto più diversi di quanto potresti pensare. Lo stesso vale per i vari moduli di riduzione del rumore: alcuni lavorano sull’input RAW, altri no, e alcuni funzionano meglio su segnali non lineari.
  • Il bilanciamento del colore è stato progettato come un modulo di colore tutto-in-uno, applicando un ASC CDL  esteso (slope-offset-power), e poi gestendo la saturazione e la croma globali e per luminanza, sostituendo quindi i precedenti moduli di Darktable come contrasto-luminosità-saturazione, vividezza e velvia (tutti operanti in CIE Lab 1976). Preso da solo, è un modulo functionality-first (guidato dalla funzionalità), ma non è l’unico modulo di spostamento del colore. Gli altri moduli di spostamento del colore usano metodi molto diversi (matrici, LUT o controlli per tonalità), che sono da 3 a 9 volte meno costosi da eseguire in termini di calcolo, e operano in spazi colore diversi.

Ansel eredita il suo concetto di moduli da Darktable: i moduli sono al tempo stesso un widget della cassetta degli attrezzi dell’interfaccia grafica e un filtro di pixel inserito da qualche parte nella pipeline. Quindi, progettare moduli molto piccoli (in termini di funzioni) genererà molti widget di alto livello nell’interfaccia grafica della barra laterale destra, mentre progettare moduli molto grandi produrrà meno widget di alto livello, ma questi saranno più alti o useranno più schede interne. La seconda opzione potrebbe comunque essere preferibile, perché i moduli di alto livello dell’interfaccia grafica agiscono come vassoi, quindi meno vassoi, funzionalmente coerenti, aiutano a comprendere meglio la suddivisione delle funzioni di alto livello (come un indice).

Ma non finisce qui, perché di nuovo… i nodi. Un modulo dovrebbe essere un insieme di controlli del colore coerenti come nodo mascherato multi-istanziato nella pipeline. Non è buona cosa riempire un modulo con decine di funzioni dove metà di esse hanno senso come impostazioni globali, e il resto solo nella località della maschera; una volta istanziate, non faranno che consumare cicli di CPU per nulla.

E infine, c’è la performance. I controlli del colore che devono operare in un particolare spazio colore avranno bisogno di una conversione di colore avanti e indietro, che consumerà cicli di CPU, quindi è meglio che vengano eseguiti tutti nello stesso modulo se hanno senso insieme dal punto di vista funzionale. Inoltre, ogni nuovo modulo eseguirà un nuovo ciclo sui pixel, il che significa che sposterà l’immagine ancora una volta nella cache di memoria della CPU da/verso la RAM. Quindi, comprimere le funzioni nello stesso ciclo previene un ulteriore abuso della larghezza di banda di I/O e aiuta con la performance.

Quindi, se ricapitoliamo l’intera lista di vincoli, ecco, è una sfida davvero difficile da risolvere:

  1. dovremmo sempre sforzarci di costruire il minor numero di elementi dell’interfaccia grafica, perché un’interfaccia grafica ingombra rende tutto difficile da trovare (e cognitivamente opprimente): il posto migliore per nascondere un albero è nella foresta,
  2. il disordine che costruiamo dovrebbe essere organizzato dal globale al locale, dal generico allo specifico, dal frequentemente usato al di nicchia, perché è il modo più facile per ragionarci sopra: pensare alla struttura dell’interfaccia grafica come a un “indice” è il meglio che sono riuscito a trovare finora,
  3. ma fare una regola del suddividere sistematicamente le funzioni in base alla funzionalità o in base al metodo finisce comunque con duplicazioni in entrambi i casi, a meno che non andiamo nella direzione del full-node-editor, facciamo tutto basato sul metodo, e deleghiamo la responsabilità di costruire le pipeline all’utente esperto,
  4. i moduli dovrebbero essere progettati come functionality-first ogni volta che è possibile, ma si applicano molti limiti:
    1. il tipo di segnale di input, che determina la posizione nella pipeline, e può costringerci a dare priorità al pipeline-first e a duplicare gli strumenti,
    2. la pertinenza e la coerenza dell’insieme di controlli del modulo quando multi-istanziato e mascherato: un modulo dovrebbe essere un’unità coerente del flusso di lavoro di editing, non un contenitore in cui stipare tutto. In particolare, se ha senso (dal punto di vista del flusso di lavoro) applicare una maschera solo a un sottoinsieme delle funzioni del modulo, allora questo sottoinsieme dovrebbe essere un modulo a sé,
    3. i problemi di performance (andata e ritorno tra spazi colore, mappatura del gamut dell’output, larghezza di banda di I/O): non possiamo pensare all’ergonomia dell’utente solo dal lato dell’interfaccia utente; la velocità di esecuzione fa parte anch’essa dell’ergonomia,
    4. la natura matematica delle operazioni realizzate: alcuni metodi (specialmente resa della nitidezza/contrasto locale) possono avere effetti opposti a seconda del segno dei loro parametri, alcuni metodi si prestano male a essere raggruppati insieme nello stesso filtro di pixel,
  5. infine, va considerata la quantità di clic/passi di scorrimento necessari per raggiungere una funzione frequentemente usata, perché l’asse generico -> specifico non è sempre parallelo all’asse frequentemente usato -> di nicchia. Quindi, mentre l’organizzazione di alto livello generico -> specifico ha senso dal punto di vista cognitivo, non è sempre la più ergonomica.

Tutti questi requisiti antagonisti devono essere arbitrati caso per caso, guardando alla totalità della pipeline, altrimenti non costruiamo un’applicazione di flusso di lavoro ma un registro di plugin. Vivono all’incrocio tra programmazione di basso livello, matematica, flusso di lavoro di ritocco ed ergonomia dell’interfaccia utente, e nessuno di questi concetti è in generale più importante degli altri. Tuttavia, alcuni di questi vincoli sono compresi più facilmente di altri, il che farà sì che ricevano molta più attenzione, in un tipico effetto lampione : continuare a inseguire i problemi nello strato che comprendi, scartando completamente la loro vera origine perché tocca uno strato che non comprendi/di cui non sai nulla. Ecco perché è una vera rottura di scatole lavorare con i “designer di UX”, perché tipicamente non hanno le basi per guardare oltre l’interfaccia grafica e spesso non si preoccupano del fatto che c’è un motore da controllare sotto l’interfaccia utente. Non puoi semplicemente scegliere di annullare la gravità perché vorresti rimuovere il controllore di beccheggio  per un’interfaccia utente più semplice.

Il design è un processo di raffinamenti iterativi sotto il feedback degli utenti. Alcune di queste iterazioni ridisegneranno dal macro al micro (dall’architettura globale dell’applicazione ai controlli interni dei moduli), e alcune ridisegneranno dal micro al macro, finché non converge verso una semantica unificata e una suddivisione coerente delle funzioni. È folle pensare che qualcuno ci riesca al primo colpo, o pensare che solo uno dei livelli micro/macro abbia bisogno di correzioni. È un ponte da costruire da entrambe le estremità allo stesso tempo, trovando un modo di farle incontrare a metà strada.

Le proprietà dei buoni controlli del colore

Dai miei 17 anni di esperienza nell’editing di immagini, e 8 anni di esperienza nello studio e nella sperimentazione della matematica dell’elaborazione delle immagini, ci sono un paio di cose che ho imparato su cosa sia un buon o un cattivo controllo del colore. Per “controllo del colore” intendo un qualche modo di fornire un’intenzione dell’utente a un algoritmo di pixel che modificherà una proprietà visiva di un’immagine. I buoni controlli del colore:

  1. sono ortogonali tra loro, il che significa che un controllo cambia una dimensione del colore in un dato momento e non ti costringe a compensare su un altro controllo,
  2. hanno una scala uniforme da una prospettiva percettiva, il che significa che passare da “0” a “1” cambierà il risultato visivo della stessa quantità di quando si passa da “1” a “2”. Questo purtroppo non è sempre possibile, perché la matematica e la fisica ti odiano.
  3. scalano con grazia all’aumentare della gamma dinamica, il che scarta praticamente tutti i modelli di apparenza del colore (CIE Lab 1976, CIECAM 16, dt UCS 22), costruiti per SDR su dataset registrati su campioni di colore dipinti.
  4. degradano con grazia all’aumentare dell’entità dei cambiamenti, il che significa che possono essere esagerati ma non possono cambiare il contenuto dell’immagine né creare artefatti,
  5. preservano i gradienti dell’immagine, il che significa che mantengono le variazioni locali tonali e cromatiche come variazioni, invece di appiattirle, farle sovraeccedere (creando aloni, frange, rumore, ecc.) o invertirle.
  6. permettono agli artisti di avvicinarsi il più possibile alla loro intenzione nel minor tempo possibile.
  7. non sono duplicati.

Dal punto 1., deduciamo per esempio che qualsiasi tipo di curva dei toni RGB è cattiva, perché desaturerà le alte luci e saturerà le ombre come effetto collaterale della quantità di contrasto (di luminanza) che hai aggiunto, e non puoi controllare (o decorrelare) la quantità di cambiamento di saturazione che otterrai per la quantità di cambiamento di contrasto che hai richiesto, se non con trucchi come la preservazione dei rapporti RGB o massaggiando manualmente la saturazione/desaturazione attraverso l’applicazione della curva dei toni. Questa è la ragione di esistere dell’equalizzatore dei toni, che corregge il contrasto usando una regolazione selettiva dell’esposizione invece di una curva dei toni.

Dal punto 2., deduciamo che i controlli dell’interfaccia grafica dovrebbero usare modelli di apparenza del colore ogni volta che è possibile.

Dal punto 3., deduciamo che i modelli di apparenza del colore usati nell’interfaccia grafica non dovrebbero essere usati sul pixel ma dovrebbero essere convertiti in modo che i pixel siano gestiti in RGB. Questo è un tipico paradigma model-view-controller  che viene costantemente ignorato in tutte le applicazioni di elaborazione delle immagini. A quanto pare, c’è una convinzione tra gli sviluppatori che il modello di colore dei pixel debba corrispondere 1:1 allo spazio colore del controller dell’interfaccia grafica.

Dal punto 4., deduciamo che i controlli praticamente utilizzabili solo su un piccolo sottoinsieme del loro intervallo di valori usano una matematica cattiva, modelli di colore cattivi, priori cattivi. Le modalità di fallimento sono altrettanto importanti di ciò che accade quando si usano i controlli nel loro punto ottimale.

Dal punto 5., confermiamo semplicemente il punto 3.

Dal punto 6., abbiamo sollevato un nuovo problema: molti fotografi non hanno un’intenzione di ritocco/editing (nel senso di: un obiettivo visivo finale), ma spingono e tirano solo i cursori nella direzione che sembra rendere l’immagine più bella, e finiscono con un felice incidente che non sarebbero in grado di riprodurre (o scartano l’immagine perché incapaci di lavorarla). In questo caso, non c’è alcuna metrica di successo per i controlli perché non c’è alcuna differenza da calcolare tra intenzione e risultato, dato che l’intenzione è indefinita. Ecco perché, quando lavoriamo con il feedback degli utenti, dobbiamo essere critici e indagare chi parla e da dove. Vale a dire: non tutti i feedback degli utenti sono buoni feedback (e anni di esperienza non sono di per sé prova di nulla).

E il punto 7. è semplicemente un richiamo alla sezione precedente: dover duplicare un’impostazione è di solito indicativo di una cattiva suddivisione delle funzioni, oppure devi avere una buona ragione per farlo.

Tutti questi sono ovviamente i casi ideali a cui tendere. In pratica, devi valutare diversi candidati e scegliere il migliore, che raramente soddisferà tutti i requisiti. Ma per valutare candidati in competizione, hai prima bisogno di punti di riferimento e scale oggettivi. Questi sono i punti di riferimento che mi sono diventati evidenti nel corso degli anni.

Le proprietà dei buoni flussi di lavoro di editing

Ricordo infinite catene di email, 9 anni fa sulla mailing list di Darktable (ora defunta), riguardo al modo migliore di riorganizzare l’interfaccia grafica, in cui mi fu detto: “non esiste un flusso di lavoro giusto o sbagliato, solo preferenze personali”. Il relativismo assoluto è sempre più stupido di quanto sembri. Quella stupidità continua ora su discuss.pixls.us. Sono davvero le stesse discussioni, che dicono le stesse cose sugli stessi problemi, andando in loop da oltre 9 anni, e ancora nessuna soluzione tangibile di sorta.

Prima c’è il caso ovvio in cui definisci una maschera parametrica su, diciamo, bilanciamento del colore RGB, e la imposti per mascherare i valori RGB compresi tra un qualsiasi valore e quel valore + epsilon. Poi, sei soddisfatto dei colori, ma la tua immagine sembra un po’ scura, quindi vai ad alzare l’esposizione. Ora la tua maschera parametrica non è più valida e devi rifarla da capo, perché l’esposizione si trova più a monte nella pipeline rispetto al bilanciamento del colore RGB, quindi hai spostato tutto il tuo intervallo di valori di codice RGB. Questo è editing circolare, è la perdita di tempo più evitabile, e se vuoi prevenirla, non c’è molta scelta: devi fare attenzione all’ordine della tua pipeline. L’editing circolare è un flusso di lavoro oggettivamente cattivo. Devo giustificarlo?

Non si ferma alle maschere, perché molti moduli di colore hanno bisogno di normalizzare il bianco HDR per poter usare modelli di colore che possono funzionare solo con l’assunzione che il bianco = {1, 1, 1}. Ecco perché li metto più avanti nella pipeline, dopo le regolazioni globali di luminosità e contrasto.

E poi, c’è il caso dell’editing in batch: hai una serie di immagini da modificare, vuoi che appaiano coerenti in tutta la serie, ma hanno piccole variazioni di illuminazione, contrasto e temperatura del colore. L’unico modo per farlo funzionare è avere un primo passo di normalizzazione dell’immagine, per gestire le variazioni delle singole immagini e convertirle a uno stato costante. Una volta fatto questo, puoi applicare in batch lo stesso stile o copiare-incollare la cronologia dei moduli successivi in cima, perché quel passo successivo riceverà input “costanti” normalizzati e dovrebbe quindi produrre output coerenti (se non costanti). Il mancato raggiungimento di quel primo passo di normalizzazione renderà il successivo completamente inaffidabile e imprevedibile, il che vanificherà lo scopo dell’editing in batch. E anche con quel flusso di lavoro apparentemente rigido, finirai comunque per dover fare una messa a punto individuale se vuoi davvero risultati coerenti. Questa non è una mia opinione, è un semplice fatto: se vuoi output coerenti per un insieme di modifiche di immagini con impostazioni rigide, hai bisogno di input coerenti.

Ma c’è un limite a questo, perché quando si lavora su un segnale HDR, hai bisogno di impostare presto il tuo tonemapping HDR -> SDR, così da poter effettivamente vedere ciò che stai facendo nella tua immagine, senza il clipping delle alte luci. Quindi c’è un primo passo di prendere una visione d’insieme del tuo contenuto, e poi un passo di finalizzazione dei limiti della gamma dinamica. Il che significa che dovresti sempre impostare per prima l’esposizione globale, guardando i mezzitoni (e nient’altro), e poi impostare per ora il tuo tonemapper di lavoro. Quindi quella regola di cercare di ancorare il tuo flusso di lavoro 1:1 sull’ordine della pipeline (a sua volta ancorato ai requisiti di input dei moduli) ha alcune eccezioni e non può essere applicata senza discernimento.

Il che significa che avresti dovuto imparare tutto ciò. I buoni flussi di lavoro vengono da persone che hanno riflettuto su come adattarsi agli strumenti che stavano usando, guardandoli sia dal punto di vista pratico che teorico, e non dai buontemponi che hanno scambiato tutte le abitudini prese nel corso degli anni per un flusso di lavoro. Di nuovo, ci sono cose che accadono sotto la superficie dell’interfaccia grafica, non stiamo scrivendo lettere in un programma di videoscrittura. Per oltre 9 anni, ho urlato in loop sui forum: È UNA PIPELINE, NON UN INSIEME SCOLLEGATO DI CONTROLLI DELL’IMMAGINE CASUALI. L’ordine conta. Se c’è una sola cosa che comprendi in tutto questo chiacchiericcio, dovrebbe essere questa.

E penso che Lightroom abbia fatto molti danni alle aspettative e alla comprensione degli utenti nascondendo la sua pipeline interna. Ma funziona per Lightroom perché toglie molti gradi di libertà agli utenti. Darktable ha riutilizzato molta della semantica dell’interfaccia utente di Lightroom, proponendo al contempo gradualmente più libertà e controllo diretto sui nodi della pipeline (introducendo nel corso degli anni il mascheramento per modulo, poi la multi-istanziazione dei moduli e il riordinamento relativo delle istanze, poi le maschere raster riutilizzabili tra moduli non consecutivi, e infine il riordinamento completo dei moduli), il che ha confuso sia i veterani che i nuovi arrivati.

L’idea di una pipeline non è nemmeno specifica della fotografia digitale. Anche la pittura a olio ha una pipeline, in un certo senso, dove inizi preparando il tuo supporto, lo rivesti di primer per renderlo meno assorbente, poi metti i contorni, poi prepari lo sfondo, poi stratifichi la tua velatura  e infine dai la mano di vernice. Nessuno sano di mente inizierebbe con la vernice e finirebbe con il primer. La fotografia analogica ha ovviamente una pipeline di bagni chimici, timer e simili. E le app di pittura come Photoshop, Gimp o Krita hanno una pipeline esplicita, materializzata dai livelli che si occludono a vicenda, dal basso verso l’alto, con livelli di effetto che non sono altro che filtri di pixel parametrici che producono output dinamici.

Ma in qualche modo, dato che i software di editing di foto raw fanno sembrare tutto scollegato dalle realtà materiali, sembra accettabile nel digitale lavorare senza struttura né metodo. Il flusso di lavoro di editing “non distruttivo” potrebbe anche essere stato interpretato liberamente come YOLO  qui, il che non aiuta nemmeno. Solo perché hai Ctrl+Z non significa che all’improvviso tutto sia perdonabile.

Per riassumere, i buoni flussi di lavoro di editing sono quelli che ti danno risultati prevedibili a ogni passo evitando al contempo l’editing circolare. Devono essere informati dall’ordine della pipeline, ma non possono attenersi ad esso 1:1 tutto il tempo, e devi usare il tuo giudizio per distinguere quando attenerti alla pipeline e quando allontanartene. Questo lascia pochissimo spazio alle preferenze personali.

L’etica dell’elaborazione digitale delle immagini

Ai tempi dell’analogico, gli artisti lavoravano con supporti fisici, e potevano eseguire ogni sorta di espediente e trovare nuove tecniche per ottenere risultati personalizzati. Era accessibile perché potevi toccare fisicamente il mezzo con cui stavi lavorando. Gli artisti erano liberi.

L’arte digitale è intrinsecamente violenta, nella misura in cui ha tolto la libertà agli artisti: ora non possono trovare da soli nuove tecniche, perché la loro arte esiste come pura informazione su qualche memoria di computer, quindi sono limitati a ciò che le applicazioni propongono, e possono o implorare gli editori/sviluppatori di software di considerare le loro esigenze, o imparare a programmare e programmarle da soli (il che è un bel prezzo d’ingresso se non hai alcuna formazione tecnica in scienze applicate o informatica). La perdita di libertà può essere nascosta dal fatto che qualsiasi cosa fatta nel software è reversibile, quindi i fotografi non danneggiano permanentemente i negativi, per esempio. Peggio ancora, il software può renderti più produttivo, quindi è un guadagno netto dal punto di vista aziendale. Ma questo non dovrebbe nascondere il fatto che gli artisti sono messi in una posizione di consumatore più passiva di prima, e dominati da coloro che sanno e vogliono programmare per loro, che decidono come faranno arte d’ora in poi.

“Violenza”, “soppressione della libertà”, “dominazione”… Sai dove sta andando a parare: si chiama oppressione. Un’oppressione seducente che ti promette di ottenere risultati professionali in pochi clic senza dover andare a una scuola di fotografia. Oppure, nel contesto del software libero, un’oppressione che sembra benevola e innocua perché non c’è nulla da pagare e la privacy dei dati è integrata. Ma niente di tutto ciò è incompatibile con il fatto che noi, gli sviluppatori, controlliamo ciò che hai il diritto di fare nelle/alle tue immagini, o no, perché controlliamo il codice. Non perché siamo stati eletti dagli utenti, non perché siamo competenti per il compito da svolgere (a questo punto, ho dimostrato molte volte qui che il “team” di Darktable non era altro che un branco di idioti senza cognizione di causa con troppo tempo libero), solo perché abbiamo i diritti di amministratore su qualche repository di Github. Questo ci dà potere, e il potere comporta responsabilità.

Questo mi è rimasto in mente per diversi anni ormai, perché diventa anche un dilemma etico (oltre a tutti quelli tecnici menzionati in precedenza) decidere quali funzioni aggiungere, rimuovere o rifattorizzare. Allo stesso tempo, cercare di accontentare tutti non è possibile e finirebbe per sopraffare tutti con un sacco di strumenti di nicchia che non useranno mai (di nuovo: nascondere un albero nella foresta). Poi, è anche più codice da mantenere, quindi più lavoro e un peso per i maintainer in futuro, con più minacce alla stabilità del software. Costruire un coltellino svizzero che è costantemente mezzo rotto non aiuterà nessuno.

Ma resta il fatto che rimuovere i controlli per il gusto di semplificare l’interfaccia grafica potrebbe semplicemente rimuovere la libertà, se non siamo sicuri che una funzionalità simile continui a esistere, in un modo o nell’altro, nel software. La libertà artistica non è un bene di consumo, è una necessaria boccata d’aria fresca in società che stanno sempre più scivolando nel (tecno-)fascismo, ancora una volta.

Di nuovo, tutto ciò deve essere arbitrato caso per caso. Lasciare che le app di elaborazione delle immagini vadano in tutte le direzioni contemporaneamente, cercando di accogliere tutte le esigenze in una singola app, anche le più peculiari, finirà per costruire pecore a 5 zampe che sono impraticabili da usare per chiunque. Il che ci riporta alla mia prima sezione: costruire strumenti generici, versatili e privi di presupposti che possono essere adattati a molte esigenze diverse in modo fattorizzato. Industria contro artigianato.

La produttività si ottiene attraverso la specializzazione (che, combinata con la standardizzazione, sblocca l’automazione), la specializzazione si ottiene attraverso la duplicazione, la duplicazione crea gonfiore e disordine nell’interfaccia grafica, il gonfiore e il disordine sono i nemici della UX e della creatività. La conclusione di tutto ciò è: scegliamo cosa vale la pena specializzare, e quindi ostacoliamo la libertà degli utenti. Pertanto, la produttività è il paradigma sbagliato: la sua conclusione naturale è l’oppressione.

L’opposto della produttività è la robustezza e la versatilità. Potrebbe essere più lento (lo è però?), ma possiamo gestire una varietà più ampia di casi con lo stesso numero di strumenti, senza rimuovere arbitrariamente opzioni, e quindi la libertà dell’utente. Il concetto di robustezza è già stato sviluppato nel contesto dell’instabilità sociale e climatica da Olivier Hamant, nel suo libro Antidote to the cult of performance. Robustness from nature (2024). Uno dei suoi principali insegnamenti è che il culto della performance (o dell’efficienza) porta solo alla competizione, che promuove la violenza, e nei tempi instabili a venire, abbiamo bisogno di cooperazione. In una società che produce più che a sufficienza per coprire i bisogni di tutti (ma li distribuisce male), la performance non ci fa guadagnare nulla se non più profitti (di nuovo, distribuiti male). Ma ciò che sicuramente produce è il burn-out, sia nelle persone che negli ecosistemi.

Nel software, il burn-out può derivare da diverse cose:

  1. tecnostress  legato a troppe applicazioni, strumenti, standard e paradigmi a cui adattarsi,
  2. sovraccarico di informazioni , legato a un eccesso di widget e strumenti dell’interfaccia grafica in cui navigare,
  3. affaticamento da cambiamento  legato ad aggiornamenti troppo frequenti che cambiano i flussi di lavoro.

Per riassumere, l’inseguimento della performance si riversa in una serie di svantaggi:

  1. da un punto di vista tecnico, significa dover costruire strumenti più specializzati che ingombrano l’interfaccia grafica, il che produce un sovraccarico di informazioni,
  2. da un punto di vista della UX, mantenere il disordine e il sovraccarico ragionevoli implica scegliere arbitrariamente le esigenze di chi verranno coperte (probabilmente la maggioranza) e le esigenze di chi verranno ignorate, il che significa rimuovere la libertà artistica a chiunque si discosti troppo dalla corrente principale: questa è una novità nella storia dell’arte, e nessuna quantità di libertà del software la rende meno violenta,
  3. da un punto di vista del marketing, solo i professionisti hanno bisogno di produttività, e al momento sembrano preferire in larga maggioranza il software commerciale. Non c’è alcun vantaggio per l’open-source nell’andare a “conquistare nuovi mercati”, dovrebbe piuttosto sforzarsi di coprire le nicchie trascurate. E inoltre, la fotografia professionale sta lentamente morendo dagli anni ‘80, quindi non sono sicuro che rimarrà un mercato sostanziale ancora a lungo.

Questa è stata una lunga introduzione, ma in un Mondo dove tutti pensano di poter essere un designer, è necessario enunciare completamente l’intera lista dei requisiti di design antagonisti per calmare coloro che pensano di essere il prossimo Leonardo Da Vinci, e dar loro la percezione che la semplice idea che hanno avuto sembra brillante solo perché non hanno la nota di specifica completa. Ne ho avuti troppi nella mia casella di posta e sui miei tracker di issue.


Come viene gestito in Ansel

Tutti gli screenshot sono stati fatti su un portatile da 15,6’’.

Presentazione dei moduli globali

Innanzitutto ricordiamo come la presentazione generale della camera oscura è stata rifatta:

image
  • le schede dei moduli hanno ottenuto nomi espliciti invece di icone criptiche,
  • le schede sono ordinate (esternamente) nell’ordine di flusso di lavoro suggerito, da sinistra a destra, così gli utenti devono solo seguire l’interfaccia utente come guida,
  • all’interno delle schede, i moduli sono ordinati nell’ordine della pipeline (con una logica di livello “sopra”, dal basso verso l’alto), che è anche l’ordine di flusso di lavoro generalmente consigliato. La nuova scheda “base” è un’eccezione, avendo sezioni di moduli: all’interno delle sezioni, i moduli sono ordinati secondo la pipeline, ma le sezioni stesse sono ordinate secondo il flusso di lavoro (di nuovo, logica di livello “sopra”, quindi dal basso verso l’alto),
  • la scheda “pipeline” o il grafo nodale dell’ordine dei moduli disambiguano tutto e mostrano una visione diretta dei nodi della pipeline senza alcun riordinamento intermedio,
  • le schede “preferiti” sono state interamente rimosse, dato che pretendono solo di risolvere il gonfiore aggiungendone dell’altro.

Nel frattempo, le barre degli strumenti centrali sono state interamente rimosse, liberando la massima quantità di spazio per le immagini in verticale, su schermi 16:9 e 16:10 dove lo spazio verticale è davvero più prezioso di quello orizzontale. L’uso di un menu globale ha di nuovo permesso di rimuovere molti strani pulsanti a icona dalle barre degli strumenti, e di sostituirli con voci di menu esplicite e testuali. Quindi, in modalità a schermo intero, ora perdi solo l’altezza della barra del menu globale:

image

Le opzioni di fusione e mascheramento, essendo unificate tra i moduli, sono state spostate nella barra laterale sinistra. Questo libera molto spazio verticale per i moduli, riducendo la necessità di schede interne e prevenendo un sacco di clic in giro. Nota che le opzioni di fusione sono attualmente in fase di riscrittura, dopo che l’API delle maschere è stata interamente rifattorizzata, semplificata ed estesa, quindi questa è solo una visione temporanea.

Le viste di Ansel sono piuttosto verbose, quindi per aiutare a distinguere tra testo costante (etichette) e variabili (valori), è stata introdotta una colorazione della sintassi:

  • le etichette costanti sono bianche,
  • i valori variabili sono arancioni.

Calibrazione del colore

In calibrazione del colore, le 3 schede R, G e B sono state unite nella stessa scheda mixer, che ora si adatta interamente in verticale. Lo stesso vale per luminosità, colorfulness e B&N che sono ora unite in uscite.

La scheda mixer ha ora 2 modalità GUI alternative, oltre a quella tipica (ora denominata completa) ;

La vista primari è stata portata in Darktable a monte, solo che ne hanno fatto un modulo a sé stante, il che è stupido : la matematica interna dei pixel è esattamente una moltiplicazione tra matrici 3×3, che è ciò che è anche la calibrazione del colore, quindi non c’era bisogno di un modulo aggiuntivo. Anche questo è un problema risolto nel livello sbagliato : serviva un livello GUI aggiuntivo in un modulo esistente, e ne hanno fatto un modulo duplicato.

Ansel invece lo implementa come un livello GUI, il che significa che i tipici parametri del channel mixer vengono convertiti avanti e indietro nei parametri della vista primari, e la matematica dei pixel del modulo non è cambiata dal 2021. Per amore di una trasformazione completamente invertibile dalla matrice 3×3 alla vista primari, è stato necessario aggiungere un ulteriore parametro di guadagno per chiudere matematicamente la trasformazione.

La vista semplice è qualcosa che tenevo in sospeso da diversi anni : riesprimere i parametri poco intuitivi del mixer in termini di rotazione della tinta, stiramento del piano di croma (contrasto di colore) e ridimensionamento acromatico. Lo stiramento U/V sostituisce il vecchio modulo Darktable color contrast che lavora in CIE Lab 1976, e spingeva/tirava la cromaticità a e b. La vista semplice va oltre e ti permette di definire il tuo spazio di cromaticità uv usando la rotazione degli assi di croma (uv) : quando è impostata a 0°, u è un asse verde-magenta e v è un asse blu-giallo (simile a color contrast). Ma poi puoi ruotarlo come ti serve, per esempio intorno a -20°, l’asse v diventa piuttosto vicino a un asse di temperatura del colore, e l’asse u all’asse di tinta ortogonale. Ti lascio con la documentazione.

Questa modalità è particolarmente adatta a recuperare luci da palco blu opprimenti, molto più facilmente che con la tipica interfaccia del channel mixer :

After After
Before Before
Foto © Reinout Nonhebel, 2018
  1. comprimendo l’asse V, comprimiamo pesantemente il gamut sull’asse blu-giallo, il che è molto più delicato sul resto del gamut rispetto all’uso di una compressione globale della croma,
  2. comprimendo l’asse U, comprimiamo il gamut anche sull’asse magenta-verde, ma in modo molto più delicato,
  3. la tinta di accoppiamento acromatico è impostata sul blu profondo. Aumentando la quantità di accoppiamento, rimappiamo una porzione di blu nell’asse acromatico, cioè lo desaturiamo e lo schiariamo allo stesso tempo, il che aiuta molto a recuperarlo nel gamut, pur preservando l’impressione complessiva del blu. Al contrario, il colore complementare viene scurito e risaturato, ma poiché quel colore opponente è il giallo, e abbiamo compresso l’asse giallo-blu tramite V, finiamo per trovarci grosso modo nello stesso punto.

Quindi questa riscrittura in coordinate semplici dei parametri del channel mixer produce 6 controlli invece di 9, e sono molto più significativi e più facili da controllare. Questo è un problema di UX affrontato puramente dal lato matematico, perché non è altro che riesprimere una matrice 3×3 in una nuova base ortogonale di autovettori, ruotata sull’asse RGB acromatico, cioè è partito puramente da un’intuizione di algebra lineare. Grazie alle proprietà di questa nuova base di autovettori (che sono imposte per costruzione), sono stato in grado di rimuovere dimensioni e trasformare quelle rimanenti in controlli più significativi. Che è ciò che intendo quando ripeto che non puoi risolvere i problemi di UX limitandoti a guardare la GUI.

Split-toning RGB

Il vecchio modulo Darktable split-toning lavorava nello spazio HSL, che non supporta valori di codice RGB maggiori di 1 (quindi, niente riferito alla scena). Inoltre, mescolare i colori in HSL è strano e sembra di usare un filtro giocattolo quando inizi ad aumentare le impostazioni.

Allo stesso tempo, l’attuale schema di adattamento cromatico in Ansel presuppone un unico illuminante. Tuttavia, le scene reali hanno sempre almeno due illuminanti :

  1. la sorgente luminosa principale, che è l’illuminante primario, e peserà per lo più sulle alte luci e sui mezzitoni,
  2. superfici colorate che riflettono la luce dalla sorgente principale, tingendola, che agiscono come illuminanti secondari, e peseranno per lo più dalle ombre fino ai mezzitoni.

Finora, per gestire questa situazione di illuminanti misti, dovevi duplicare istanze di calibrazione del colore e mascherarle dentro/fuori. Ma cercare di ritagliare una maschera binaria (una regione attribuita a un illuminante, e il resto all’altro illuminante) è fragile perché non tiene conto della mescolanza di luce che avviene intorno ai mezzitoni.

Quindi il nuovo modulo split-toning in Ansel propone due channel mixer e due correzioni di temperatura del colore, e duplica le nuove modalità GUI dalla calibrazione del colore. Ti permette di definire la luminosità di ciascun illuminante, associa una matrice di colore a ciascuno, e calcola una miscela di entrambe le matrici da applicare a ciascun pixel a seconda della sua luminanza.

After After
Before Before
© Luc Viatour, 2016

A questo punto, potresti pensare che io sia ossessionato dalla fotografia di concerti, ma è solo perché le luci da palco sono la configurazione più esigente e non perdonano alcun errore nella pipeline del colore. Questi sono stati problemi irrisolti per decenni; è noto che le luci blu degenerano in magenta, e sono il banco di prova definitivo del colore.

Qui abbiamo regolato la temperatura delle alte luci per toni della pelle più naturali, preservando al contempo l’ambiente complessivamente blu nelle ombre. In una scena del genere, non c’è nessun bianco da campionare, quindi puntare a toni della pelle naturali è l’unica guida. Poi fai del tuo meglio per preservare lo spirito dell’illuminazione da palco (mantenere il blu blu), tenendo conto dei limiti del tuo gamut RGB. Per maggiori dettagli, vedi la documentazione.

Primari del colore

Come ho accennato in precedenza, il modulo primari di Darktable è un semplice duplicato del channel mixer con un’interfaccia diversa. Ma ci sono casi in cui manipolare l’intero spazio colore attraverso i suoi primari danneggia troppo l’intervallo a bassa saturazione che era perfettamente valido. Quindi c’era bisogno di agire sui colori primari e secondari (ai vertici del cubo del gamut) in modo da escludere il centro del gamut, ma fondendo comunque gli effetti in modo fluido tra entrambe le regioni e preservando i gradienti dell’immagine.

Questo è stato ottenuto costruendo una LUT RGB in un nuovo modulo : primari del colore.

After After
Before Before
© Andrea (sorgente )

Questo esempio è stato progettato per rendere il rosso e l’arancione meno opprimenti, ma per approfondire drasticamente i blu, per mostrare quanto sia stabile la trasformazione del colore lungo i bordi tra superfici di colore diverso.

Poiché, internamente, il modulo costruisce dinamicamente una LUT spostando il colore dei nodi di controllo, gli utenti hanno la possibilità di decidere quanto lontano dai vertici del cubo RGB si trovino i nodi di controllo, tramite il cursore copertura del gamut. Poi, 3 parametri di smussamento permettono di fondere in modo più o meno marcato gli spostamenti di colore in RGB, e di proteggere in modo più o meno marcato i colori neutri dallo spostamento. Infine, il modulo ha un visualizzatore di LUT 3D:

image

Il visualizzatore di LUT mostra gli spostamenti di colore attraverso l’intero cubo RGB dall’origine alla destinazione. Può essere ruotato attorno all’asse acromatico (azimut), o messo in una vista sul piano di cromaticità (inclinazione dell’asse = 90°). Può essere ingrandito, spostato e ruotato in 3D con eventi del mouse, e sezionato per ottenere una vista migliore a una certa profondità. Infine, la LUT 3D generata può essere esportata come file cLUT .cube per essere riutilizzata in qualsiasi software che li supporti. Per maggiori dettagli, vedi la documentazione.

Equalizzatore del colore

Il “team” di Darktable ha preso il mio secondo prototipo (non funzionante)  di equalizzatore del colore, non ha capito perché non funzionasse, ha aggiunto passaggi di post-filtraggio per nascondere i problemi, e lo ha rilasciato come se fosse opera loro, senza nemmeno accreditarmi. Possono tenerselo : è merda. E comunque io non firmo la merda col mio nome.

Vedi, il problema di quel prototipo è che applicava lo spostamento di saturazione nello spazio colore dt UCS 22 HSB, che ho progettato nel 2021 . Questo spazio colore è già usato in color balance RGB per la saturazione, ed era mirato a trovare la giusta quantità di scurimento da applicare a un colore quando se ne aumenta la “saturazione” (in realtà, la sua croma, in termini rigorosi di scienza del colore), così da evitare di degenerare in innaturali colori fluo e neon, che sono i tipici tranelli quando si aggiunge molta “saturazione”. Quindi, invece della tipica impostazione di croma che riduce la colorfulness a luminanza o chiarezza costante, questa formula di saturazione scurisce anche. E mentre funziona molto bene su campioni di colore piatti, il problema è che le immagini non sono superfici a colore piatto, ma hanno gradienti.

Mi fu segnalato intorno al 2022 che la saturazione dt UCS HSB di color balance RGB creava una strana frangia acromatica luminosa tra le foglie autunnali gialle, luminose e sature e il cielo blu profondo dietro di esse. Il problema era che, sul bordo, la luce gialla delle foglie e la luce blu del cielo si mescolavano in acromatico (come dovrebbe essere, essendo colori complementari) a causa di un obiettivo leggermente morbido o della foschia atmosferica. L’algoritmo di saturazione scuriva il giallo e il blu su ciascun lato della frangia acromatica, ma non la frangia stessa, che ora spiccava più luminosa. E non c’è rimedio a questo; non è un bug algoritmico: il problema è il modello di colore, che tiene conto della percezione ma non della mescolanza della luce. Così sono stato l’ennesimo autore dell’ennesimo spazio colore difettoso che mi ha richiesto mesi per svilupparlo e 20 ore di calcolo per adattare numericamente i parametri del modello.

Cercare di implementare un equalizzatore del colore riutilizzando quello stesso spazio colore ha reso questi problemi ancora peggiori perché ora l’effetto era guidato in base alla tinta, il che significava problemi su due dimensioni invece di una. Per alleviare il problema, ho provato a smussare le cose usando filtri guidati RGB. Ma non riuscivo proprio a trovare la formula magica per avere una fusione adeguata e robusta. È stato allora che il team di Darktable ha deciso di sgraffignare la nuova cosa luccicante dallo scaffale, ed è stato quando ho capito che questo poteva avvenire solo in RGB se doveva fondersi correttamente e preservare i gradienti.

After After
Before Before
© baongoc124 (sorgente )

L’equalizzatore del colore eredita lo stesso cursore interattivo dell’equalizzatore dei toni, per la modifica diretta sull’immagine campionando la tinta del pixel sotto il cursore, e lo scorrimento aggiornerà automaticamente il grafico. I nodi possono essere aggiunti liberamente ovunque, e dal cursore interattivo, l’aggiunta di un nodo alla tinta corrente si effettua con il clic destro.

L’equalizzatore del colore permette di definire uno spostamento di colore in base alla tinta per ombre, mezzitoni e alte luci. Il selettore di colore permette di vedere dove si colloca una regione tra i controlli tonali. Questo permette un controllo molto granulare che, insieme allo stesso smussamento 3D dei primari del colore, fornisce un modo molto robusto di fondere gli spostamenti di colore. Il rumore di croma che era il problema principale, quando si definivano spostamenti di colore drastici, con il vecchio modulo Darktable color zones (che lavora in CIE Lab 1976) o con il precedente prototipo di equalizzatore del colore non si presenta più.

Come per i primari del colore, questo modulo crea dinamicamente una LUT RGB 3D che può essere visualizzata e salvata in file .cube allo stesso modo. Per maggiori dettagli, vedi la documentazione.

Disegno

image

Devo dire altro ?

Ansel implementa ora un prototipo di modulo di disegno che ti permette di disegnare immagini raster in una pipeline riferita alla scena a partire da pennelli a 32 bit che supportano colori HDR (>100%). I pennelli supportano opacità e flusso (come Photoshop), spruzzi casuali, smussamento del tracciato, sfumatura dei bordi, e possono essere usati in modalità pittura, cancellazione, sfumatura e sfocatura. Dimensione, opacità, flusso e durezza del pennello possono essere mappati sulla pressione e sull’inclinazione della penna Wacom, o su un’accelerazione generica del cursore. Usano un alfa premoltiplicato adeguato e salvano i livelli in file collaterali TIFF float a 16 bit che possono essere modificati nella maggior parte delle principali app di disegno.

Diversi livelli possono essere usati istanziando più istanze del modulo disegno e composti sull’immagine usando le opzioni generiche di fusione e mascheramento di Ansel. Può anche essere usato per comporre qualsiasi tipo di livello arbitrario proveniente da qualsiasi software, purché sia salvato in float a 16 bit come livello nel file collaterale TIFF di Ansel. L’immagine di sfondo (prima del modulo) può essere esportata come livello di sfondo se hai bisogno di un’immagine di riferimento su cui disegnare in un altro software e reimportarne il risultato.

Questo è stato reso possibile dalla nuova architettura della pipeline che ha abilitato una modalità in tempo reale. Certo, non è ancora veloce come Photoshop perché, a ogni aggiornamento del tratto di pennello, ci sono altri moduli che girano dopo disegno nella pipeline.

Questa è la libertà definitiva di realizzare tutto ciò che pulsanti e cursori non ti daranno mai, che si tratti di schiarire e scurire, riparare parti danneggiate (alte luci tagliate, aree mancanti) o semplicemente mescolare fotografia e pittura. Per maggiori dettagli, vedi la documentazione.

Grana fotografica

Il vecchio modulo grana di Darktable era davvero insoddisfacente, poiché permetteva solo la grana di luminanza ed era applicato sul canale di chiarezza dello spazio colore CIE Lab 1976. I risultati erano strani, non corrispondevano in alcun modo agli alogenuri d’argento. Ho finalmente implementato la sintesi stocastica della grana  che ho sviluppato nel 2023 in un nuovo modulo: grana fotografica. Questo suddivide il campo luminoso in cristalli virtuali di alogenuro d’argento e simula sensori di grana impilati su livelli. Funziona sia per la grana in B&N che a colori, anche se ho dovuto prendere qualche distanza dal mio articolo iniziale per gestire il colore.

After After
Before Before
© Alessandro Amato del Monte (sorgente )
After After
Before Before
© Alessandro Amato del Monte (sorgente )

Filmic

Per diversi anni, la gente mi ha detto che gli stupidi moduli Darktable sigmoid e il più recente AgX davano loro un po’ più di controllo. E nessuno di loro è stato in grado di dirmi esattamente controllo su cosa. Quindi mi ci è voluto molto tempo per capirlo.

Sigmoid e AgX non sono rivoluzioni, sono altri filmic :

  1. converti i colori usando un logaritmo o un modellatore a potenza,
  2. ci schiaffi sopra una curva a S,
  3. poi fai del tuo meglio per rimediare a ciò che la curva dei toni ha fatto alla croma durante il processo,
  4. e infine annulli il modellatore.

Sigmoid e AgX avrebbero potuto essere modalità alternative all’interno di filmic : passano tutti attraverso gli stessi passaggi con priorità e strategie leggermente diverse. Fare così avrebbe fornito un unico modulo per la compressione della gamma dinamica, con modalità diverse a seconda di quanto controllo granulare volessero gli utenti. Invece di questo, hanno duplicato la funzionalità e aggiunto rigonfiamento alla GUI, così ora gli utenti devono scegliere tra base curve (che era già una variante duplicata e specializzata della tone curve stessa), filmic, sigmoid e AgX per compiere lo stesso compito, mentre nessuno di questi dichiara effettivamente la funzionalità che fornisce.

L’unica cosa che filmic fa meglio è gestire esplicitamente i confini della gamma dinamica, il che permette di usarlo per la compensazione del punto di nero durante la stampa. Gli altri due li gestiscono come sottoprodotto dell’impostazione del contrasto. Poiché gli sviluppatori degli altri due non si preoccupano delle stampe, puoi scommettere che questo allevia alcuni vincoli sulla progettazione, e rimuove alcuni cursori nella GUI. L’unica cosa che gli altri due fanno meglio è fornire controlli manuali di colore per rimediare ai problemi di saturazione e spostamento di tinta attraverso la mappatura dei toni, ma non credo proprio che quel livello di granularità del colore appartenga a una funzione di mappatura dei toni : è un flusso di lavoro e una suddivisione delle funzioni completamente sbagliati.

Comunque, alla fine ho capito che il controllo più fine del contrasto derivava dal fatto che sigmoid fornisce direttamente un controllo dei nodi di piede e spalla, mentre filmic usa una latitudine e un offset globali che sono scomodi da usare poiché collegano entrambi. Questo era stato originariamente progettato per mapparlo sulle effettive schede tecniche delle pellicole, perché la latitudine è una cosa reale della pellicola, allo scopo di magari emulare un giorno pellicole reali. Quel giorno non è mai arrivato.

Quindi ho risolto il problema nel livello GUI aggiungendo una conversione tra le impostazioni latitudine/offset e alte luci/ombre, e ora filmic RGB ti permette di manipolare direttamente la posizione dei nodi di piede/spalla :

image

Nessuna matematica dei pixel è stata cambiata nel processo, i parametri del modulo sono ancora gli stessi di prima, nessun nuovo modulo è stato creato, è solo un passaggio intermedio di conversione della GUI.

Conclusione

Tutti i nuovi moduli supportano l’offloading su GPU tramite OpenCL. Sono stati progettati per la robustezza, e penso che quell’obiettivo sia stato raggiunto. Hanno sostituito moduli precedenti peggiori, che lavoravano in CIE Lab 1976, che hanno mostrato i loro limiti e difetti per molto tempo. Ora esegui una pipeline RGB completa in Ansel. I moduli legacy sono ancora nel programma e continueranno a funzionare per le vecchie modifiche. Inoltre, i cursori colorati e i grafici delle tinte sono gestiti a livello di colore usando il profilo colore del display.

I moduli che ho introdotto di recente non sono nuovi giocattoli luccicanti di cui entusiasmarsi. Sono la conclusione di anni di riflessione su una suddivisione delle funzioni coerente e coesa che aiuta il flusso di lavoro riferito alla scena. Quel flusso di lavoro riferito alla scena è più complesso di quello precedente riferito al display, se non altro perché dobbiamo normalizzare il “bianco” prima di entrare in qualsiasi LUT o spazio colore percettivo, ma è l’unico modo per affrontare le immagini HDR, un’adeguata fusione alfa per le maschere, e filtri di pixel fisicamente accurati che simulano la mescolanza della luce. I filtri fisicamente accurati sono robusti e producono risultati organici, anche spinti a impostazioni drastiche. Ma sono spesso meno accessibili ai nuovi arrivati e sconcertanti per i ritoccatori esperti abituati a Lightroom e simili.

Questo sarà il mio ultimo post su questo sito perché mi ritiro dallo sviluppo. Mi è costato troppo : troppo stress, troppi burn-out, troppi anni passati a sistemare la merda di altre persone e a soffrire per le loro cattive decisioni. Sono stanco oltre ciò che puoi immaginare. Odio programmare e odio i programmatori. Ne conosco pochissimi che programmano per costruire cose o per risolvere problemi, la maggior parte semplicemente si diverte troppo a passare del tempo di qualità con un computer, e si trasformano in pompieri piromani a cui non puoi affidare la progettazione delle cose. Odio la tecnologia e la cosiddetta “innovazione”: tutto questo è solo una truffa capitalistica progettata per una crescita infinita in un Mondo dove le risorse sono limitate, e fingiamo di risolvere problemi creati dalla tecnologia con ancora più tecnologia. È una follia. Il mondo open-source eredita la stessa mentalità, incluso il tecno-soluzionismo , perché quello è il tipo di marciume cerebrale che 350 anni di capitalismo producono, anche se il FLOSS non ha i profitti per giustificarlo. È pieno di bugie e pieno di merda, perché libre significa libertà solo per gli ingegneri, e gli utenti possono andare all’inferno. Il problema è che io credevo in quelle bugie, in quei valori : erano (e sono ancora) i miei. Ma rendermi conto che sono solo parole vuote ripetute in “comunità” tossiche di uomini bianchi di mezza età con B.Eng, M.Sc e Ph.D è stato un brutale risveglio. Cosa facciamo davvero per dare potere agli utenti che ne hanno davvero bisogno ? A che punto il richiedere con disinvoltura di usare la CLI dà potere a chiunque non sappia leggere il codice ? Stiamo solo contribuendo ad approfondire il divario tra le élite alfabetizzate al computer e i contadini. Ricorda, qui stiamo facendo software di fotografia, non una libreria di backend, non un’infrastruttura server, ma un’applicazione desktop per l’utente finale.

Ho svuotato qui il mio cervello, per registrare tutto ciò che ho imparato sulla progettazione dell’elaborazione delle immagini, come l’ho fatto, e perché. È importante capire che gli utenti, e la maggior parte degli sviluppatori, sanno solo come si comporta un’applicazione sulle proprie immagini. Per 8 anni ho ricevuto molte immagini patologiche che la gente mi ha inviato, che mostravano difetti e limitazioni degli strumenti. Ho circa 45 GB di quelle immagini sul mio disco rigido, proprio ora. Questo dà una prospettiva completamente diversa sui problemi reali rispetto a quella che possono avere tutti gli spensierati : io sono il tizio che sa cosa si rompe e quando. Io sono il tizio che i problemi trovano. Io sono la Cassandra  del progetto. Ed è fastidioso dover giustificare in continuazione, a persone che non vedono i problemi, perché quella cosa che potrebbe essere molto più semplice non può essere molto più semplice perché ci sono casi patologici in cui dobbiamo adattarci alla variabilità dell’input. Per adattarsi alla variabilità dell’input, servono parametri utente invece di costanti codificate. Quindi rigonfiamento della GUI. Il tipo di rigonfiamento della GUI che non puoi evitare senza danneggiare l’usabilità.

Non puoi valutare la qualità di un progetto se non ne conosci i requisiti. “A me piace” o “a me non piace” è irrilevante. A nessuno piace indossare la cintura di sicurezza, è comunque una buona progettazione se consideri quante vite ha salvato. Qualsiasi vera critica può riguardare solo come la soluzione proposta ha raggiunto l’obiettivo, il che può avvenire solo se conosci l’obiettivo. Nell’elaborazione delle immagini, la natura mista dei requisiti rende difficile evitare di tuffarsi a un certo punto nella matematica e nei suoi geroglifici, ed è lì che perdi le persone. Ma questo non impedisce comunque loro di dare la propria opinione inutile, iniziando con “non sono un programmatore”/“non sono un matematico”/“non sono uno scienziato del colore”… “MA”… [segue del rumore cerebrale casuale]. Fare codice open-source, dove tutto è pubblico, permette quel tipo di rumore ovunque : è davvero stancante, e ci sono molte volte in cui ho desiderato che il sorgente fosse chiuso, solo per poter lavorare in pace. La maggior parte di quei tizi ha buone intenzioni e vuole solo far parte di qualcosa, ma contribuire al sovraccarico di informazioni non aiuta e contribuisce solo a creare stanchezza. La comunicazione è dove ogni lavoro di squadra perde produttività

La progettazione non consiste nell’ascoltare ciò che piace alla gente. Se il 65% del tuo panel di test gradisce il testo scritto in rosso, e il 72% gradisce il testo scritto su sfondo rosso, scrivi testo rosso su sfondo rosso ? Non ha senso. Non stiamo facendo politica cercando di compiacere gli elettori durante una campagna, stiamo cercando soluzioni a lungo termine/a prova di futuro ai problemi. La progettazione consiste nell’ascoltare ciò di cui le persone hanno bisogno, cosa che raramente sanno esprimere chiaramente, e nel trovare modi per fattorizzare quei bisogni. Quindi le uniche statistiche che vale la pena calcolare sono quelle sui casi d’uso : come viene usato il software, quali sono i punti dolenti più comuni, e qual è la loro causa profonda. Poi correggi la causa profonda, che può essere ben lontana dall’effettiva manifestazione del problema. Anche quella è un’abilità reale e preziosa : seguire il filo del problema, attraverso indizi e odori, per scoprire la vera origine, e non limitarsi a rattoppare il problema finale o ad aggirarlo. “Ascoltare gli utenti” non significa ascoltare ogni individuo e dargli ciò che vuole individualmente : non stiamo fornendo terapia. Significa ascoltare l’intera base di utenti, e identificare i bisogni e i punti dolenti comunemente condivisi in modo da ideare una soluzione fattorizzata che coprirà il maggior numero di bisogni con la minor quantità di tecnologia. Questo non implica scartare chiunque devii dalla media di più di una deviazione standard, ma quelle persone potrebbero dover ricorrere a metodi che non sono su misura e ottimizzati per i loro bisogni.

La progettazione non esiste su un’isola : ci sono altre app di editing delle immagini in giro. È di nuovo difficile valutare quando la tua progettazione debba copiare le altre perché gli utenti saranno abituati alla loro semantica dell’interfaccia, e quando dovresti allontanartene perché il problema che stai cercando di risolvere è troppo diverso da ciò che fa la concorrenza, o il tuo utente tipico è troppo diverso. L’open-source è costantemente combattuto tra la tentazione di copiare 1:1 i leader commerciali che tanto detesta (ma a cui aspira silenziosamente a essere), e la brama di superare in astuzia tutti reinventando la ruota (spesso in modo peggiore). In tutto ciò, la tua Stella Polare è chiederti, ogni ora di ogni giorno : qual è il problema che stiamo cercando di risolvere, e chi sono le persone che lo affrontano ? È così che puoi adattare le cose al tuo pubblico, piuttosto che cadere nei culti del cargo  e adottare soluzioni perché hanno avuto successo in un contesto che non capisci davvero e che non è necessariamente il tuo.

La mia principale conclusione da tutti questi anni è che applicare trasformazioni di colore ai pixel in qualsiasi spazio diverso da RGB è destinato a fallire, come mostra l’esempio di colorbalance RGB : mentre potrebbe sembrare una grande idea decorrelare il lavoro sul “colore” (inteso come tinta/croma) dal lavoro tonale, sarà sempre e solo una questione di scegliere il proprio dolore. Aumentare la croma a chiarezza costante degrada i colori in fluo, aumentare la saturazione a luminosità costante (quindi scurendo complessivamente) non rispetta la teoria della mescolanza della luce, ed entrambi producono rumore di croma a causa della natura instabile degli angoli di tinta. Ma poi RGB non è percettivamente uniforme, e l’intervallo verdastro di qualsiasi scala di tinta HSL/HSV occupa circa il 30 % dello spazio, mentre il verde è solo 1/6 dell’anello percettivo delle tinte. L’unica soluzione è gestire la GUI in modelli di colore percettivi, e convertire, in un modo o nell’altro, in RGB prima di applicare ai pixel. Il che richiede ulteriore ginnastica di astrazione per gli sviluppatori. E questo chiaramente non è il loro forte, dato che il livello matematico è piuttosto basso.

Ho già un successore, ma il futuro di Ansel dovrà essere una cooperativa dove gli utenti garantiscono agli sviluppatori condizioni di lavoro eque, e gli sviluppatori garantiscono agli utenti che i loro bisogni saranno coperti, ricambiando responsabilità reciproche. Non possiamo continuare così, non è sano. E, con “così”, intendo da un lato lo “sviluppatore hobbista” con zero responsabilità, e dall’altro l’unico sviluppatore in burn-out che vive sotto la soglia di povertà per far più o meno succedere le cose. Quel paradigma ha dato tutto ciò che poteva, non può essere ritoccato. Le stesse cause porteranno solo alle conseguenze che già conosciamo : l’open-source fa schifo. Se vuoi di più, quel paradigma dovrà cambiare. L’open-source, da un lato, è una dittatura degli sviluppatori (quelli che sanno e possono) sugli utenti (quelli che hanno bisogno), ma dall’altro lato, è sfruttamento di chi lavora da parte di chi prende. Questo alimenta solo risentimento reciproco, disprezzo sottile e paternalismo. Ci perdono tutti.

L’alternativa è l’attuale enshitification delle piattaforme aziendali e il tecnofascismo che sta attualmente abilitando. Sei stato avvisato.


Translated from English by : Claude. In case of conflict, inconsistency or error, the English version shall prevail.

  1. Grignon, Claude. La règle, la mode et le travail : la genèse sociale du modèle des repas français contemporain. In Le temps de manger, édité par Maurice Aymard, Claude Grignon, et Françoise Sabban. Paris: Éditions de la Maison des sciences de l’homme, 1993. doi:10.4000/books.editionsmsh.8155. URL  ↩︎

  2. Ekirch AR. Segmented Sleep in Preindustrial Societies. Sleep. 2016 Mar 1;39(3):715-6. doi: 10.5665/sleep.5558. PMID: 26888454; PMCID: PMC4763365. URL  ↩︎