TZ=Indian/Antananarivo

Ahanements d'octets austraux
Billet classé dans la catégorie : Accueil > Photos > Workflow2

lundi 09 juillet 2007

[ 04:10 ] Méthode LPMM : les logiciels

(Téléchargement outil version française :
<http://blog.barijaona.com/download/LPMM-photokit.zip>)

(Download the english version tool :
<http://blog.barijaona.com/download/LPMM-photokit-en.zip>)

On va faire une petite pause sur certaines guerres de religion ; très jésuistiquement, on va faire passer la défense des libertés par le logiciel libre, appelé en mercenaire étranger dans les bonnes vieilles guerres de souveraineté Mac contre PC et Nikon contre Canon.

A l'heure qu'il est, il y aurait eu une centaine d'individus qui auraient fait une incursion sur mon introduction au traitement des images numériques.

J'ai le sentiment d'avoir transmis l'impression que le traitement des fichiers RAW était une activité essentiellement ésotérique. Aussi, pour remotiver les troupes (j'entends par là les trois pelés et quatre tondus qui pourraient dans un instant d'égarement me lire vraiment sérieusement), je préfère montrer que toute cette prise de tête aboutit à un menu contextuel simple, destiné à traiter en masse de grandes séries de photos, et qui couvre 99% des attentes.

Menu contextuel sous MacOS X

Même si je garde une version de mes photos sur 16 bits par couleur afin de pouvoir les retravailler sous un logiciel de traitement d'image comme Photoshop ou Chocoflop, mes besoins dans la quasi-totalité des cas peuvent se résumer à produire un JPEG "standard mais soigné" pour pouvoir ensuite :

La véritable difficulté, le petit défi personnel, c'est que la qualité doit pouvoir se comparer avantageusement à ceux des outils payants infiniment plus coûteux.

Car cet assemblage d'utilitaires est entièrement gratuit (et la plupart sont en "open source"), même si pour récompenser les nuits blanches d'expérimentation, il ne vous est pas interdit d'utiliser ici la petite monnaie que vous a laissé l'achat à titre personnel d'un Airbus A380 ou une partie des dollars que vous auriez été prêt à dépenser pour un logiciel commercial.

(Article long : entre la première ébauche et la mise en ligne, il s'est passé six mois...)


La photo, c'est la liberté

Mes petits efforts se téléchargent donc à <http://blog.barijaona.com/download/LPMM-photokit.zip>.

Mais ils ne se suffisent pas à eux seuls. Il vous faut compléter avec une collection d'outils libres qui comprend à ce jour :

Il y a aussi sips, inclus dans Mac OS X depuis Tiger (MacOS 10.4). Les utilisateurs Windows et autres Unixes sont priés de ne pas pleurer, je ne m'en sers que pour créer l'aperçu MacOS, ce dont ils n'ont cure.

Un autre élément spécifiquement Apple que j'utilise est Automator pour disposer d'un menu local permettant de lancer le traitement d'un fichier ou de tout un lot. A priori, on peut faire quelque chose de vaguement approchant sous Windows (pas testé, voir les copies d'écran de ce forum).

Résumé de l'épisode précédent : obtenir un négatif

Je disais que la méthode commençait par transformer l'image latente du RAW en un "négatif" fidèle.

Dans ce cadre, dcraw est utilisé pour générer un fichier ".ppm" en 16 bits par couleur, et la commande convert d'ImageMagick est ensuite utilisée pour :

En ligne de commande, ça donne à peu près ceci :

dcraw -c -4 -q 3 -w -f "$fichier.RAF" |\
    
convert - \
    
-profile MyE900Profile.icc \
    
-profile WideGamutD65Gamma1Profile.icm \
    
"originals/$fichier.png"

(Bon, je simplifie un peu, mais vous avez un exemple complet en fin d'article pour toutes les subtilités. Et tout ça doit être considéré comme une seule ligne de commande, ce qu'indiquent les délimiteurs \).

Si on ne prend pas ces précautions particulières, le coin de ma rue est rendu par dcraw avec un coté un rien apocalyptique :

Image 16 bits sans correction

L'application du profil colorimétrique linéaire améliore immédiatement l'apparence des choses :

Image 16 bits avec prise en compte du gamma de 1,

et ce sans changer l'histogramme de notre image, calé à des niveaux assez bas :

L'essentiel de l'histogramme est dans le premier tiers

Si j'ai des ambitions artistiques et/ou que je dois retravailler la photo sous Photoshop ou un autre logiciel de retouche, j'utilise ce fichier ".png" comme base de travail. Mais un bon JPEG de référence sert toujours, et c'est pourquoi le reste de cet article va se concentrer sur des corrections à usage général.

Regard critique sur ces données "brutes de derawtisation"

L'examen d'une série de fichiers ".png" créés par la méthode précédente montre qu'ils présentent tous un contraste très doux qui en usage généraliste sera souvent considéré comme peu flatteur. Certains parleront même d'apparence brumeuse... (et pourtant, lors de la prise de vue de l'exemple, je me souvenais plutôt d'avoir aperçu des cumulus...).

Un bruit chromatique, discret mais réel, apparaît également sur certaines photos à partir de 200 ISO, et est franchement observable pour les photos prises en haute sensibilité (400 ou 800 ISO). Impossible de confondre cette signature typique des appareils numériques avec le grain d'un film argentique (grain qui au bout d'un siècle de photo "classique" a fini par plaire à notre oeil, du moins lorsqu'il est fin et régulier).

Ces deux caractéristiques méritent donc d'être retravaillées immédiatement pour obtenir des fichiers destinés à des usages standard.

Le contraste

Première tentative pour donner du peps aux fichiers destinés à Tatie Danielle

Pour augmenter le contraste, la technique d'amélioration du contraste local par un masque de flou donne souvent des résultats très esthétiques. Il s'agit d'appliquer une légère accentuation sur un rayon élevé pour souligner les transitions importantes de l'image.

La commande convert d'ImageMagick dispose d'une option -unsharp qui semble adaptée à cet usage. Avant de s'en servir, il faut cependant savoir que les options de flou ou d'accentuation d'ImageMagick présentent deux particularités historiques (certains diront deux bogues) qui peuvent rendre leur utilisation délicate :

Tout ceci pour dire qu'une commande de type :

convert image1.png -channel RGBA -unsharp 0x50+0.3+0 image2.png

accroîtra effectivement la netteté de notre image...

Mais elle s'avérera horriblement lente pour les grandes valeurs de sigma, et amène à se demander pourquoi ImageMagick met de longues minutes à réaliser ce que Photoshop arrive à achever en quelques secondes.

Passons par un chemin de traverse : prêchons le flou pour arriver au net

Il m'a fallu un certain temps pour intérioriser une donnée qui n'est pas si intuitive : le flou et le net sont les deux facettes d'une même médaille. Avec leur rigueur habituelle, les matheux vous diront que flouter une image ou accentuer ses contours, c'est toujours lui appliquer une convolution. Les autres comprendront peut-être plus facilement la logique derrière le curieusement nommé masque de flou (unsharp mask) si je l'explique ainsi :

Lorsque nous voulons que le voisinage soit étendu, la tâche la plus laborieuse dans ce processus devient le floutage de l'image... C'est particulièrement long dans ImageMagick, qui à l'origine est un logiciel qui privilégie la rigueur mathématique, et qui, lorsqu'il calcule un flou gaussien, le fait rigoureusement, au lieu d'utiliser comme Photoshop une approximation.

Un peu intégriste, ImageMagick ne me laisse pas beaucoup d'options pour flouter sommairement et fortement une image, sinon de réduire sa dimension, puis de la ramener à la dimension initiale...

Une fois cela accompli, j'obtiens en fusionnant à égalité l'image nette et le négatif de l'image floue le filtre passe-haut visible ci-après (technique pompée sur un tutoriel Gimp) :

Valeurs de l'augmentation locale du contraste

Reste à superposer le résultat obtenu, très proche d'un gris médian, et notre image originale pour obtenir une image accentuée.

Evidemment, il faut doser l'effet pour ne pas faire trop caricatural. Avantage annexe au passage : comme notre filtre passe-haut est monochrome, nous évitons par cette technique d'accroître le bruit chromatique, celui auquel l'œil humain est le plus sensible.

Un petit coup de crayon pour souligner les contours

Si la méthode précédente renforce le contraste entre les grandes régions de notre image, elle ne met pas en évidence les fins détails.

Pour cela, une accentuation avec un rayon nettement plus faible est nécessaire pour simuler une combinaison film/révélateur à forte acutance.

Pour cela, je peux utiliser l'option -unsharp d'ImageMagick sans subir une pénalisation excessive de performance. Mais en appliquant une forte accentuation, je risque de faire monter le bruit... D'où l'idée d'accentuer plus fortement dans les contours de l'image, et moins dans ses parties uniformes.

C'est l'idée de l'option -adaptive-sharpen d'ImageMagick. Le traitement, assez lent, aboutit à un résultat qui ne me paraît cependant pas suffisamment marqué. Faute de paramètres supplémentaires permettant d'agir, je me suis résolu à faire ma propre petite tambouille en m'inspirant de cette recette médievale pour détecter les bords. Cela donne le masque ci-dessous dont les parties les plus claires subiront l'accentuation.

Masque d'application d'une accentuation locale

(plutôt sympa, cette pseudo-lithographie, non ?)

Et pour finir, les grands classiques...

En fin de traitement, un rehaussement classique du contraste, par application d'une courbe en S s'avère nécessaire pour donner un rendu plus proche d'un film et "déterrer" les ombres.

Cela se fait avec l'option -sigmoidal-contrast d'ImageMagick. Comme nos images sont encore calibrées avec un profil colorimétrique de gamma 1, il s'avère nécessaire de prendre en compte dans les paramètres à passer le fait que le gris moyen se situe à un niveau sensiblement plus bas que dans des images plus classiques : l'augmentation de contraste doit se concentrer autour de 20 ou 25% du niveau de luminosité maximum, au lieu de typiquement 50%.

Cette option -sigmoidal-contrast éclaircit l'image et ravive son contraste moyen ; mais je me suis rendu compte que de temps à autres l'histogramme de nos images demeure un peu trop resserré, l'algorithme étant assez précautionneux à ne pas faire bouger les valeurs extrêmes.

L'ajout d'un traitement -contrast-stretch 0.01x99.999% permet de faire face à de tels cas, en élargissant l'histogramme de niveaux ; ceci tout en limitant quand même sérieusement la proportion de points qui deviennent complètement noirs ou totalement blancs, et en particulier éviter de brûler notre image, puisque nous sommes au final amenés à la convertir en un gamma plus élevé, dans un espace colorimétrique plus étroit (sRGB).

Résultat des courses, après conversion en JPEG "classique", notre image finale présente l'apparence générale suivante.

Image avec son contraste final

Pas de bouleversement par rapport à notre fichier ".png" de départ, mais un examen attentif permet de relever de réelles différences d'apparence.

Par contre, l'histogramme de niveaux est sensiblement différent ; on arrive à reconnaître pas mal des pics et des creux de l'histogramme initial, mais la distribution apparaît sensiblement aplatie et décalée vers la droite, et les importances relatives n'ont plus grand chose à voir !

Pic autour de 50%

Travailler en silence

Le bruit numérique n'apparaît progressivement qu'à partir de 200 ISO, et n'est réellement visible qu'aux forts grossissements. Pour les tirages au format 10x15 cm, ou pour le web, il sera rarement gênant, sauf en cas de photo gravement sous-exposée... ce qui devrait être un peu masqué par nos efforts antérieurs pour rééquilibrer les niveaux.

Après avoir un peu expérimenté Greycstoration (qui manque sérieusement de documentation exploitable : commencer par greycstoration -help, car les exemples qu'on trouve sur internet ne sont pas très à jour), je reste réticent vis à vis de ce qui revient à flouter une image pour lutter contre le bruit numérique alors que tant d'efforts sont faits par ailleurs pour augmenter la netteté.

Tout ceci pour dire que je ne ressens pas trop le besoin d'attaquer très violemment le bruit. Alors que fignoler le contraste général ou la colorimétrie est rentable même sur une image format carte postale, trouver le compromis parfait entre bruit et netteté n'est gratifiant que sur un agrandissement proche de 100% ou un tirage grand format.

Le compromis raisonnable ne saute pas aux yeux, d'autant qu'il dépend largement du support de destination des images, et du coup je préfère n'en faire pas assez que trop.

Mais impossible de ne pas se rendre compte de l'apport très positif de la réduction du bruit par la méthode des ondelettes (wavelet) implémentée dans les versions récentes de dcraw (option -n suivi d'un chiffre, généralement compris entre 50 et 1000). Est-ce dû à la mise en oeuvre du procédé très en amont du traitement ? Toujours est-il que je n'ai trouvé aucun autre procédé qui neutralise autant le bruit d'un fichier RAW sans en détériorer les véritables détails. Je l'ai donc mis en oeuvre, même si cela m'amène à m'éloigner un peu de mon objectif initial d'avoir un "négatif" aussi peu "dénaturé" que possible.

En aval, pas de traitements supplémentaires anti-bruit, sauf pour les images les plus perturbées, celles à ISO 800 :

C'est forcément assez subjectif, mais je pense que le rendu obtenu se défend très honorablement. On peut comparer ci-après les détails agrandis à 100% d'une photo prise à 400 ISO, traitée avec 4 logiciels différents :

La chaîne de traitement

Sur un iMac 2 GHz Intel Core 2 Duo, le script ci-dessous prend deux à trois minutes d'exécution pour chaque photo. Sur un Mac G4 Cube 450 MHz, il faut compter pas loin d'un quart d'heure...

Ceci explique pourquoi je privilégie le batch... Mon organisation actuelle est la suivante :

Et voici donc le script :

# Copyright (c) 2007, Barijaona Ramaholimihaso <photokit@barijaona.com>

# Camera specific settings
# raw files extension
rawfileext=".RAF"
# location of Gamma 1 camera color profile
rawfileprofile=~/Library/ColorSync/Profiles/MyE900Profile.icc
# noise reduction intensity 
nrintensity=75
# ISO value above which we will not try to sharpen (too much noise)
# and we will blur colors information
isomaxisharpen=400
# brightness value under which we will blur colors informations (in % for 100 ISO) 
noiseunder=6.25

PATH=/usr/local/bin:/usr/local/ImageMagick/bin:/bin:/sbin:/usr/bin:/usr/sbin
export PATH

export MAGICK_HOME="/usr/local/ImageMagick"
export DYLD_LIBRARY_PATH="$MAGICK_HOME/lib"

versionscript="BJR script v20070707 for dcraw/ImageMagick"
version=`dcraw 2>&1 | grep \"dcraw\"`

for i in "$@"
do
        
name=`basename "$i" "$rawfileext"`
        
cd "`dirname "$i"`"
        
if [ ! -d raws ] ; then
                
mkdir raws
        
fi
        
if [ ! -d originals ] ; then
                
mkdir originals
        
fi

        
# get ISO value
        
iso=`exiftool -ISO "$i" | awk '{print $NF }'`
        
noisethold=`echo "scale=9 ; $nrintensity*$iso/100" | bc`
        
nice dcraw -c -4 -q 3 -w -f -n $noisethold "$i" |\
         
nice convert - \
         
-profile $rawfileprofile \
         
-profile ~/Library/ColorSync/Profiles/\
AIMRGBPro\ \=WideGamutD65G1.00.ICM \
         
"/tmp/$name.mpc"

        
# create a PNG file in 'originals' folder
        
nice convert "/tmp/$name.mpc" "originals/$name.png"
        
# copy Exif infos
        
exiftool -TagsFromFile "$i" -x Orientation \
         
-Software="$version" "originals/$name.png"
        
# correct ISO value if it is not in the standard exif:iso tag
        
exiftool -exif:iso=$iso -if 'not $exif:iso'\
         
"originals/$name.png"
        
rm "originals/$name.png_original"
        
# create a MacOS preview
        
sips -i "originals/$name.png"
        
# same change date as our Raw file
        
touch -r "$i" "originals/$name.png"

        
# local contrast : create a high-pass filter
        
size=`identify -format %wx%h! "/tmp/$name.mpc"`
        
# large range, quick and dirty blurring
        
nice convert "/tmp/$name.mpc" -channel RGBA -resize 1.5625%\
         
"/tmp/thumb-$name.mpc"
        
nice convert "/tmp/thumb-$name.mpc" -negate -filter Mitchell\
         
-resize "$size" "/tmp/blur-$name.mpc"
        
# high-passed picture
        
nice composite -blend 50\
         
"/tmp/$name.mpc" "/tmp/blur-$name.mpc"\
         
"/tmp/pass-$name.mpc"
        
nice convert "/tmp/pass-$name.mpc"\
         
-colorspace Gray "/tmp/pass-$name.mpc"
        
# overlay the image and the high-pass mask (local contrast)
        
nice composite "/tmp/pass-$name.mpc" "/tmp/$name.mpc"\
         
-compose Overlay "/tmp/highcont-$name.mpc"

        
# soften the local contrast effect
        
nice composite -blend 70 \
         
"/tmp/highcont-$name.mpc" "/tmp/$name.mpc" \
         
"/tmp/cont-$name.mpc"

        
# indication of general contrast
        
stddev=`convert "/tmp/thumb-$name.mpc" -colorspace Gray - |\
         
identify -verbose - | grep "Standard deviation" |\
         
awk '{print substr($4, 2, length($4) -2)*100"}'`

        
# cleanup
        
rm "/tmp/blur-$name.mpc" "/tmp/blur-$name.cache" \
         
"/tmp/pass-$name.mpc" "/tmp/pass-$name.cache" \
         
"/tmp/thumb-$name.mpc" "/tmp/thumb-$name.cache"

        
# apply low radius sharpening if noise is reasonable
        
if [ $iso -le $isomaxisharpen ] ; then
                
# selective ("smart") sharpening
                
nice convert "/tmp/cont-$name.mpc" \
                 \
( +clone -channel RGBA -unsharp 0x1+1.5+0 \) \
                 \
( -clone 0 -edge 3 -colorspace GRAY -level 20%,95% \
                  
-blur 0x1 -level 10%,95% \) \
                  
-composite "/tmp/cont-$name.mpc"
                
# general sharpening
                
nice mogrify -channel RGBA -unsharp 0x0.7+0.7+0\
                 
"/tmp/cont-$name.mpc"
        
else
                
# reduce color noise for dark areas (more for high ISOs)
                
step=`echo "scale=9 ; $iso*$noiseunder*6.55535" | bc`
                
nice convert \
                \
( "/tmp/cont-$name.mpc" -despeckle \)        \
                \
( -clone 0 -channel RGBA -blur 0x3 \) \
                \
( +clone -white-threshold $step -negate \) \
                
-compose Colorize -composite "/tmp/cont-$name.mpc"
        
fi


        
# apply an S-Curve ; intensity is chosen to avoid burning highlights
        
if [ $stddev -lt 20 ] ; then
                
sigma="4x20%"
        
else
                
sigma="3x25%"
        
fi
        
nice mogrify -sigmoidal-contrast $sigma\
         
-contrast-stretch 0.01x99.999% "/tmp/cont-$name.mpc"

        
# make a JPEG
        
nice convert "/tmp/cont-$name.mpc" -profile\
         
/System/Library/ColorSync/Profiles/sRGBProfile.icc\
         
-quality 95 -sampling-factor 1x1 "$name.jpg"

        
# cleanup
        
rm "/tmp/$name.mpc" "/tmp/$name.cache"\
         
"/tmp/highcont-$name.mpc" "/tmp/highcont-$name.cache"\
         
"/tmp/cont-$name.mpc" "/tmp/cont-$name.cache" "cache:-"

        
# copy exif infos and modification date to JPG file, create MacOS preview
        
exiftool -TagsFromFile "originals/$name.png"\
         
-Software="$versionscript" "$name.jpg"
        
rm "$name.jpg_original"
        
sips -i "$name.jpg"
        
touch -r "originals/$name.png" "$name.jpg"

        
# move our raw file in 'raws' folder
        
mv "$i" raws

done

Les commentaires sont les bienvenus, notamment sur les paramètres qui vous paraissent adéquat si vous adaptez ce script pour un autre type d'appareil photo... (la plupart des adaptations nécessaires ont été regroupées en début de script).

Dernière mise à jour le 9/7/2007 04:26
Commentaires du blog hébergés par Disqus


<- No comprendo
Les petits détails qui améliorent la vie ->
 Accueil |  Humour | Macintosh | Bidouilles | Sélection | Éditeur 

Certains droits protégés par licence Creative Commons , 2007 Barijaona Ramaholimihaso
Réagissez par les liens de commentaires ou par courriel : reactions (arobace) barijaona.com