martedì 27 marzo 2012

Correzione della distorsione di una lente sotto linux: soluzioni eleganti per vecchie ottiche

Premessa

Chi ha Pentax spesso ha anche vecchie ottiche delle serie K, M e A che non sono riconosciute negli exif e che non vengono corrette da software commerciali (come PTLens, ad esempio) .
La cosa è quantomeno sgradevole, poiché le ottiche DA o D-FA (ma credo anche molte FA e F) al contrario sono gestite da molti software commerciali, e addirittura direttamente in camera le DA e le D-FA, e spesso la correzione della distorsione e delle aberrazioni cromatiche è necessaria. 
Come fare allora? Buttiamo via un pentax A 35-105 f3.5 ed i suoi meravigliosi colori solo per questioni di software?

No!

Ecco la soluzione!


Passo numero 1: cambiamo sistema operativo! :P

Il titolo è un po' una provocazione, ma fino ad un certo punto...
Tra tanti software commerciali che costano centinaia di euro e che fanno tanto "pro" chi li usa (magari piratati), fa un po' impressione che la soluzione al problema venga da due progetti opensource e gratuiti: Hugin e Lensfun .
Intendiamoci: Hugin SPACCA! E', nel mondo del software, quello che un corridore giamaicano o etiope è nell'atletica leggera: sviluppo spartano, ma tanto tanto valore.
Poiché non credo molto al porting di questi software sotto windows, perché non provarli direttamente sotto le ali protettive del pinguino? ;)


Passo numero 2: troviamo i parametri

LensFun è la libreria per la correzione della distorsione di un obiettivo di gran lunga più importante sotto linux e si basa sul modello panotools. Viene utilizzata in darktable, rawstudio, digiKam, UFRaw e altre applicazioni di fotografia digitale per Linux
Lensfun funziona abbastanza bene, ma non contiene un elenco particolarmente esaustivo di obiettivi, e non è detto che l'ultimissimo obiettivo appena comprato o il reperto di archeologia industriale che abbiamo trovato in soffitta attaccato ad una Spotmatic siano già presenti nel database. Anzi, probabilmente sicuramente non lo sono.
Inoltre non vi è alcuna interfaccia utente dedicata per creare nuove voci per questa libreria. Ecco perché Andrew Zabolotny, sviluppatore principale di LensFun, ha suggerito a tutti di utilizzare solo Hugin. La app di calibrazione della lente di Hugin è, quindi, un primo passo nella direzione di fornire tale interfaccia utente. Il primo passo è quindi quello di scaricare Hugin (magari l'ultima versione presente nel launchpad se usate Ubuntu), o istallarlo da sorgenti se si vuole, ed eseguire l'applicazione Hugin Calibrate Lens.  
Ecco come funziona. 
Prima di tutto, per creare un modello di distorsione della lente nuovo o migliore (dal momento che alcune descrizioni delle lenti ci sono, ma sono molto semplicistiche), c'è bisogno di un'immagine scattata con quella focale o di una serie di immagini scattate con più focali se si tratta di un obiettivo zoom. L'immagine può essere una griglia stampata e fotografata, o una foto di un edificio con evidenti linee orizzontali e verticali.
E' importante che non vi siano punti di fuga, quindi bisogna mettersi il più posibile perpendicolari alla griglia.

Si apre quindi lo Hugin Calibrate Lens e si aggiunge l'immagine appena creata.
Se si vuole una maggiore precisione, è meglio creare una serie di immagini e caricarle tutte.
Dopo aver caricato le immagini si deve inserire la focale ed il fattore di crop legato alle dimensioni del sensore.

A questo punto inizia la fase "complicata": bisogna trovare le linee.
Per fare questo bisogna giochicchiare un po' con le opzioni. In genere aumentare i primi due valori tende a far riconoscere meno le linee presenti nell'immagine (può essere un vantaggio se le linee sono molto evidenti rispetto ad un fondo rumoroso), mentre dimensione immagine e lunghezza minima delle linee permettono di distinguere un maggior numero di linee.
Una volta trovate un certo numero di linee, si passa all'ottimizzazione e si ottengono tre parametri che verranno inseriti nel file xml che descrive la lente.
Nel caso di uno zoom bisogna ripetere questi passaggi più volte in modo da coprire tutte le focali.


Passo numero 3: creiamo il modello

I file del database LensFun si trovano in /usr/share/lensfun/ e sono file xml. Se non li trovate sotto windows, tornate al passo n.1 :P 
Possiamo immaginare di creare un file "self-pentax.xml" con i nostri obiettivi.
Il file che descriverà l'obiettivo o gli obiettivi (in questo caso è preso come esempio un file in cui è presente solo il 12-24 DA) sarà del tipo (la parte interessante è alla fine):
 <lensdatabase>

    <mount>
        <name>Pentax K</name>
        <name lang="ru">Байонет K</name>
        <compat>M42</compat>
        <compat>Pentax KA</compat>
        <compat>Pentax KAF</compat>
        <compat>Pentax KAF2</compat>
        <compat>Generic</compat>
    </mount>

    <mount>
        <name>Pentax KA</name>
        <compat>M42</compat>
        <compat>Pentax K</compat>
        <compat>Pentax KAF</compat>
        <compat>Pentax KAF2</compat>
        <compat>Generic</compat>
    </mount>

    <mount>
        <name>Pentax KAF</name>
        <compat>M42</compat>
        <compat>Pentax K</compat>
        <compat>Pentax KA</compat>
        <compat>Pentax KAF2</compat>
        <compat>Generic</compat>
    </mount>

    <mount>
        <name>Pentax KAF2</name>
        <compat>M42</compat>
        <compat>Pentax K</compat>
        <compat>Pentax KA</compat>
        <compat>Pentax KAF</compat>
        <compat>Generic</compat>
    </mount>

    <mount>
        <name>Pentax KAF3</name>
        <compat>M42</compat>
        <compat>Pentax K</compat>
        <compat>Pentax KA</compat>
        <compat>Pentax KAF</compat>
        <compat>Pentax KAF2</compat>
        <compat>Generic</compat>
    </mount>

    <camera>
        <maker>Pentax</maker>
        <maker lang="en">Pentax</maker>
        <model>35mm film: full frame</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.0</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX *ist DL2</model>
        <model lang="en">*ist DL2</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX *ist DL</model>
        <model lang="en">*ist DL</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX *ist DS2</model>
        <model lang="en">*ist DS2</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX *ist DS</model>
        <model lang="en">*ist DS</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX *ist D</model>
        <model lang="en">*ist D</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K-m</model>
        <model lang="en">K-m</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K100</model>
        <model lang="en">K100</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K100D Super</model>
        <model lang="en">K100D Super</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K110</model>
        <model lang="en">K110</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K200D</model>
        <model lang="en">K200D</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K10D</model>
        <model lang="en">K10D</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX Corporation</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K20D</model>
        <model lang="en">K20D</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K-7</model>
        <model lang="en">K-7</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K2000</model>
        <model lang="en">K2000</model>
        <mount>Pentax KAF3</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K200D</model>
        <model lang="en">K200D</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <camera>
        <maker>PENTAX</maker>
        <maker lang="en">Pentax</maker>
        <model>PENTAX K-x</model>
        <model lang="en">K-x</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
    </camera>

    <lens>
        <maker>Pentax</maker>
        <model>SMC PENTAX DA 12-24mm F/4 ED AL IF</model>
        <mount>Pentax KAF2</mount>
        <cropfactor>1.5</cropfactor>
        <calibration>
            <distortion model="poly3" focal="12" k1="-0.01919" />
            <distortion model="poly3" focal="15" k1="-0.00774" />
            <distortion model="poly3" focal="18" k1="-0.00345" />
            <distortion model="poly3" focal="21" k1="-0.00199" />
            <distortion model="poly3" focal="24" k1="0.00061" />
            <tca model="poly3" focal="12" br="0.0000916" vr="0.9999904" bb="-0.0002397" vb="1.0006490" />
            <tca model="poly3" focal="15" br="0.0001253" vr="0.9999184" bb="-0.0002858" vb="1.0008241" />
            <tca model="poly3" focal="18" br="0.0001204" vr="0.9999075" bb="-0.0001990" vb="1.0006258" />
            <tca model="poly3" focal="21" br="0.0001063" vr="0.9999562" bb="-0.0001477" vb="1.0005692" />
            <tca model="poly3" focal="24" br="0.0000982" vr="1.0000005" bb="-0.0001137" vb="1.0004136" />
            <vignetting model="pa" focal="12" aperture="4.5" distance="100" k1="-0.19267" k2="0.09379" k3="-0.38938" />
            <vignetting model="pa" focal="15" aperture="4.5" distance="100" k1="-0.08756" k2="-0.28192" k3="0.06908" />
            <vignetting model="pa" focal="18" aperture="4.5" distance="100" k1="-0.05982" k2="-0.45748" k3="0.25039" />
            <vignetting model="pa" focal="21" aperture="4.5" distance="100" k1="-0.28874" k2="-0.06687" k3="0.09488" />
            <vignetting model="pa" focal="24" aperture="4.5" distance="100" k1="-0.44227" k2="0.2599" k3="-0.09436" />
        </calibration>
    </lens>
</lensdatabase>
 In pratica all'interno del tag "lens" ci sarà sempre un "maker", un "model" ed un "mount", il fattore di crop, dopo di ché si inserirà tra i tag <calibration> e </calibration> la parte relativa alla distorsione. Nell'esempio è riportato anche il codice relativo alla correzione delle aberrazioni cromatiche e della vignettatura, supportati da LensFun ma fuori dall'obiettivo di questo post.
La correzione geometrica riportata per il 12-24 è solo quella del parametro "b" di Hugin Camera Lens, ovvero la distorsione a barilotto. Volendo inserire al posto del modello "poly3" il modello "ptlens" con tre parametri, le righe avranno un codice di questo tipo: 
 <distortion model="ptlens" focal="16" a="0.012341" b="-0.035947" c="0" />
Qual è la differenza tra il ptlen ed il poly3?
Se Ru è il raggio del pixel non distorto e Rd il raggio del pixel distorto, la correzione attuata con ptlens sarà effettuata secondo una legge di questo tipo:

Ru = a * Rd^4 + b * Rd^3 + c * Rd + Rd
 
mentre quella effettuata con poly3 seguirà un andamento polinomiale di terzo grado:

Ru = k1 * Rd^3 + Rd

Aggiungere ulteriori obiettivi è semplicissimo: si aggiunge un'altra parte "lens" di seguito alla prima, e si incrementa il database.

fonti: 
http://lensfun.berlios.de/lens-calibration/lens-distortion.html
http://lensfun.berlios.de/manual/dbformat.html

1 commento:

  1. molto interessante.. soprattutto in vista di un 14mm :)
    ora non resta che scoprire come risolvere la vignettatura ;)

    RispondiElimina

Puoi commentare quello che vuoi, ed io sono libero di pubblicarlo o meno.