Local Lab controls/fr

From RawPedia
Jump to: navigation, search

Quel type de contrôle local?

Lorsqu'on observe les différents logiciels du marché on trouve plusieurs types de contrôles locaux

  1. les contrôles de type "lasso", associés à des calques et masques de fusion, comme par exemple dans Photoshop (c)
  2. les dispositifs de suppression de "yeux rouges", ou de "spot" liés aux imperfections du capteur
  3. les contrôles de type U-points, utilisés jusque récemment dans Nikon Capture NX2 (c), ou comme complément à d'autres logiciels comme Nik Software (c)

Dans la version présente de Rawtherapee, l’algorithme développé est proche dans le principe du point 3) ci-dessus, les U-points. Bien sûr, le code de Nik Software est inconnu, mais il y a quelques années j'ai été séduit par la facilité d'utilisation et les performances des U-points, et j'ai entrepris de développer un produit qui ne ferait pas appel, ni au lasso, ni aux calques, ni aux masques de fusion.

La version actuelle est très certainement perfectible, au niveau de l'interface graphique - GUI - notamment:

  • pour le suivi et repérage des points de contrôle à l'écran
  • pour les réglages des différents curseurs qui gagneraient à être intégrés au point de contrôle, comme le fait Nik Software (c).

Cependant, ces deux points n'affectent pas ni l’utilisation courante, ni la portabilité.

J'ai ajouté, pour faciliter l'utilisation et éviter les menus trop longs en mode écran, une interface GUI similaire à celle de Wavelet, avec des "expanders". Vous avez ainsi la possibilité pour chaque famille d'action (color and light, Blur, Retinex, etc.):

  1. faire apparaître ou non le détail des commandes : curseurs, méthodes, courbes,..
  2. activer ou non l'ensemble des fonctions de la famille d'action.

Attention, le choix - 2 - active ou annule l'ensemble des points de contrôle; il est théoriquement possible d'associer cette possibilité à chaque point, mais quel intérêt ?

Contrôles locaux Lab et RGB

  • Les premiers algorithmes sont écrits en mode L*a*b* avec les contrôles suivants : "Color and Light", "Blurr addnoise", "Retinex", "Tone mapping", "Sharpen", "CBDL", "Denoise"..Deux contrôles suivants ont été ajoutés : "Exposure", "Vibrance"...
  • Voir ci-dessous le principe des algorithmes, mais un des points clefs à retenir pour la détection de forme et la prévention des artefacts est que le mode Lab préserve la teinte "hue", qui joue un rôle déterminant.
  • L'idée d'un module "RGB" vient évidemment à l'esprit, avec a minima un module :
    • White Balance : qui permettrait une retouche de la balance des blancs par exemple pour "réchauffer les parties à l'ombre", ou permettre le mélange de deux éclairages par exemple "lumière du jour" et "Tungsten". Ce module doit être placé juste après "demosaic".

Le module "white balance" vise deux objectifs :

  • permettre la retouche locale de la Balance des blancs (évident!)
  • tester de nouveaux algorithmes de Balance des blancs automatique :
    • en usage local, pour essayer de "dégrossir" les réglages
    • en usage général (full image), afin d'obtenir de meilleurs résultats que l'algorithme actuel. Bien sûr on va me rétorquer qu'il faudrait une branche spécifique "White balance", mais j'essaie de faire d'une pierre deux coups.

Pour mémoire en 2012 et 2013, il m'avait été demandé, de mettre en place la balance des blancs itérative "Auto Robust WB[1]". A l'époque avec un autre développeur nous avons passé beaucoup de temps pour un résultat assez peu satisfaisant... d'où l'abandon. Depuis, fort de cette expérience j'ai repris le travail mais à l'envers ! Maintenant - si je ne me suis pas trompé - l'algorithme fonctionne. J'ai profité de cette possibilité (actuellement uniquement pour des images RAW), pour rechercher dans la littérature universitaire, d'autres algorithmes auto. J'ai trouvé et mis au point deux nouveaux algorihmes :

  • "auto edge[2]" : l'idée ici est de créer un masque d’accentuation pour permettre de renforcer les parties de l'images où il y a des détails par rapport aux aplats.
  • "auto standard deviation[3]" : l'image (ou la partie d'image pour le mode local) est divisée en 12 zones. Pour chacune on calcule moyenne et écarts type, puis on assemble le résultat.

Un troisième algorithme semble prometteur "Color by correlation[4]", mais je me heurte à quelques difficultés...

J'ai ajouté la notion de "Color appearance" pour prendre en compte :

  • les mêmes principes concernant la répartition de la luminance - gamma sRGB - utilisé dans le code de Rawtherapee
  • CAT02 pour prendre en compte la notion "equal energy" liée à la perception des couleurs par l’œil.

A titre de rappel, la balance des blancs automatique est un problème mathématique totalement indéterminé. Il est possible d'avoir des algorithmes plus ou moins performants (et aussi plus ou moins rapides ou lents), mais en aucun cas le résultat sera parfait ! Pourquoi est-ce impossible ? Si on se réfère aux principes de la gestion des couleurs [[5]], il est nécessaire de connaitre à la fois l'objet coloré, l'illuminant et l'observateur. Il y a au moins 2 familles d'inconnues. De plus l'environnement de prise de vue n'est pas connu et influe sur la perception (CIECAM) ainsi que l'environnement de traitement et de visualisation. Donc, mission quasi impossible !

Bien sûr il me sera dit "cela ne fonctionne pas", ou "on ne se raccorde pas avec le 'preview'". Cela fonctionne ! Et il est plus qu'évident que atteindre le preview est par définition quasi impossible... (différences ombres , soleil, illuminants différents, etc.) en dehors de la pertinence de l'algorithme.

L'objectif du module "White balance" est de tester les algorithmes, au total il y en a 7 et le triple (au moins) si on prend en compte le "gamma sRGB" et "Cat02". En effet pour contourner les obstacles d'il y a 5 ans, j'ai utilisé au lieu de l'image avant demosaic, l'image juste après demosaic, sur laquelle on peut ou non appliquer le "gamma sRGB" et ou "cat02", pour se retrouver dans les mêmes conditions qu'en usage normal (sinon bien sûr sans "White Balance" et sans profil "ICC ou DCP").

L'idéal est de tester sur de nombreuse images les divers algorithmes "auto", aussi bien :

  • en mode local (est-ce utile, est une utopie ?... je le pense !)
  • en mode "full image", en plaçant le spot au centre de l'image et en déplaçant les limites de la zone locale, aux limites de l'image totale : quel(s) algorithme retenir et implanter en mode "full image" (peut être 1 ou 2 en plus de l'actuel qu'il faut garder pour compatibilité).

Quels défis à résoudre?

Plusieurs problèmes généraux sont à résoudre afin d'obtenir un fonctionnement fluide :

  • permettre un nombre quasi illimité de points de contrôles;
  • adapter les algorithmes locaux aux problèmes d'échelle, car beaucoup d'algorithmes tiennent compte de la taille de l'image - donc de la zone traitée. Cet aspect est fondamental, notamment avec les courbes qui agissent sur toute l'image;
  • minimiser l'occupation mémoire et les temps de traitement en sortie JPG et TIF;
  • permettre des mises à jour logicielles faciles en cas d’évolution des algorithmes ou d'évolution du nombre de méthodes ;
  • optimiser les écarts entre "preview" et sortie JPG / TIF;
  • etc.

Pour chaque point de contrôle :

  • permettre selon le cas, une action dans la zone sélectionnée ou à l'extérieur de la zone sélectionnée;
  • permettre selon le cas une détection de forme pour délimiter l'action;
  • assurer une transition entre le cœur de la zone traitée et le reste de l'image;
  • etc.

Actuellement, les points de contrôles sont opérationnels, pour le mode Lab, et pour les méthodes suivantes:

  1. Color and light : lightness, chrominance, contraste en mode normal avec deux courbe L=f(L), L=f(H), C=f(C), H=f(H) et inverse ;
  2. Exposure : en mode normal
  3. Vibrance : en mode normal
  4. Blur and Noise : en mode normal et inverse;
  5. Retinex : en mode normal et inverse, maintenant avec gestion de la courbe "transmission gain";
  6. Sharpening : en mode normal et inverse;
  7. Contrast By Detail Levels : en mode normal;
  8. Denoise : en mode normal.

Principes généraux

L'Objet spot

Comme je l'ai évoqué, le système utilisé est proche de celui mis au point par Nik Software, avec de grandes différences :

  • chaque spot, peut être considéré comme un objet qui comporte plusieurs champ - à ce jour environ 70, constitués de curseurs, courbes, points de contrôles,... - ;
  • chaque champ, regroupé en paquets peut être ou non activé, et peut avoir des valeurs variables selon sa nature ;
  • les paquets sont des ensembles cohérents pour l'utilisateur : color & light, contrast, blurr, retinex, sharpening, tone-mapping, contrast by detail level, denoise ;
  • le nombre de "spots objets" peut varier de 2 à 500 ;
  • les données des "spots objets" sont stockées dans un fichier texte "mip";
  • les "spots objets" sont gérés - création, modification, suivi - dans une boucle "for";
  • il n'y a pas de duplication de code.


Le découpage en quatre zones - l’aperçu de la zone spot

Lorsque l’utilisateur sélectionne un point de contrôle,l’image à l’écran montre:

  • un centre, constitué d'un cercle dont on peut faire varier : a) le diamètre, b) la position avec la souris ou les curseurs;
  • quatre lignes horizontales ou verticales dont on peut faire varier les positions avec la souris ou les curseurs.
  • si vous sélectionnez en "Preferences" / "General" / "Local adjustements", en cochant la case "Show spot delimiters", vous obtiendrez une approximation de la zone concernée par le spot et ses réglages. Attention, je ne suis pas arrivé à un travail propre avec la fonction "arc / ellipse / scale" de la bibliothèque graphique Cairo; j'ai donc opté pour chaque "quart" à une pseudo ellipse obtenue par 3 courbes de Bézier se raccordant entre elles. Dans la majorité des cas l'approximation est satisfaisante...Pour permettre une sélection plus facile j'ai été amené à accroître la taille des 4 lignes horizontales et verticales qui sélectionnent la taille du spot (les courbes de Bézier sont inactives!).

On aboutit à 4 zones, dont on ne peut faire varier l'orientation (angle d'inclinaison obligatoirement à zéro). Ces 4 zones ont chacun de leurs sommets reliés par une ellipse imaginaire.

Il est possible de pointer les limites des zones en dehors de la zone "preview".

A terme, il doit être possible, même si l'utilité me semble discutable du fait de l'algorithme de détection de forme, de remplacer l'ellipse, par une courbe tracée à l'aide de la souris, à condition que la transformée homothétique de la courbe n'ait pas d'intersection avec la courbe originale. Cette "amélioration" intellectuellement satisfaisante, ne devrait être que d'un apport négligeable - dans le cas des U-points. Néanmoins il sera toujours possible de faire coexister les actuels U-points avec des contrôles par"lasso" de type Photoshop (c).

Les références teinte, chroma, luminance et le principe de l'algorithme en mode "normal"

Afin de mettre en œuvre un algorithme performant de détection de forme :

  • la zone du cercle central, sert de référence. En fonction du diamètre choisi par l'utilisateur, le système calcule, la moyenne de la teinte (hue), de la chroma, et de la luminance.
  • le choix du diamètre de la zone centrale dépend de l'usage. Par exemple pour un feuillage, l'utilisateur aura intérêt à choisir une valeur faible afin de ne sélectionner que le vert du feuillage; à l'inverse pour la peau l'utilisateur aura intérêt à accroître le diamètre afin d'éviter les prises en compte de données parasites (bruit, cils, etc.).
  • pour chaque quart, et en fonction du curseur "scope", le système prend en compte :
  1. en premier lieu de l'écart de teinte entre la zone centrale et le pixel courant ;
  2. puis, un algorithme complexe, s'appuyant sur la notion de deltaE (différence perçue entre 2 couleurs prenant en compte, la teinte, la chroma et la luminance), atténue l'action en fonction de l'écart entre la zone centrale et le pixel courant.
  3. la modification d'action utilise soit une loi linéaire, soit une loi parabolique selon le cas.

Ceci va permettre de différencier l'action selon les critères énoncés ci-dessus, comme par exemple, si le cercle central se trouve dans un feuillage, de limiter l'action à l'ensemble du feuillage sans toucher à l'arrière plan (ce qui est impossible avec un lasso). De plus si un autre feuillage se situe dans la zone couverte, celui-ci sera également concernés par la modification.

  • l'action sur le curseur transition va permettre de faire varier l'action : si le curseur est réglé sur 50, la moitié (linéaire) de la zone concernée verra une application à 100% de l'effet, puis une transition agira régressivement jusqu'aux limites de la zone.
  • si on accroît la valeur de "scope", progressivement l’ensemble de la zone sélectionnée est prise en compte quelque soit la couleur, la chroma et la luminance.
  • si on réduit la valeur de "scope",l'action se limitera aux pixels très proches (en termes de deltaE) de la zone de référence.

L'algorithme de détection de forme est opérationnel en mode "normal" - son implantation en mode inverse n'a pas de sens - pour tous les modules excepté Denoise.

Cet algorithme va avoir ses performances accrues, si l'utilisateur choisit : "Quality Enhanced" ou "Qualty enhanced + chroma denoise". Ce second choix apporte une très légère réduction du bruit de chroma afin de supprimer les artefacts possibles liés à l'utilisation de "enhanced" (à noter dans le cas + chroma denoise, un accroissement des besoins en mémoire et du temps de traitement).

L'algorithme utilise toutes ses capacités, si les valeurs de "scope" sont inférieures à 20.

Le fonctionnement en mode inverse

Lorsqu'il est proposé, le fonctionnement en mode inverse est extrêmement simplifié, seul le curseur "transition" permet de moduler l'action.

Nombre maximum de points de contrôle

Par défaut le nombre de points de contrôle est de 8. Vous pouvez choisir n'importe quelle valeur entre 2 et 499. Pour cela il suffit de changer la variable Nspot dans le fichier "option"; par exemple Nspot=12. Il est indispensable de relancer Rawtherapee après cette modification.

L'algorithme 'super'

La clef du "succès" (si on peut utiliser ce terme) tient à l'algorithme présent depuis fin janvier 2017. je vais l'expliciter de manière simplifiée :

  1. pour la partie des données concernées par la zone sélectionnée, on applique une fonction courbe "traditionnelle" ou un curseur classique, ou la fonction de transfert normale (Retinex, Tone mapping, CBDL);
  2. puis on réalise une conversion de la LUT ou de la fonction de transfert , en un équivalent "slider", en séparant les valeurs positives et négatives, afin d'avoir une représentation de la fonction comme une multitude de "sliders" (autant qu'il y a de pixels concernés) dans l'intervalle -100, 0, +100
  3. on passe ces données à la fonction de reconnaissance de forme - celle des 4 zones. On détecte pour chaque pixel l'écart de teinte, chroma et luma par rapport à la référence. On établit des équations de variations linéaire selon le cas de la luminance (L = f(L)) ou de la chroma (C=f(C) ou des fonctions de transfert).
  4. puis on applique diverses corrections pour tenir compte de l'environnement, ciel, peau,...
  5. enfin, on applique une correction (avec seuil et itérations)pour ne pas corriger (ou le faire faiblement selon le choix de l'utilisateur), les tons gris ou neutres qui sont dans la même teinte que la référence (mais avec une chroma faible).
  6. ces paramètres sont ensuite pondérés en fonction, de la forme (ellipse) et de la zone de transition.
  7. bien sûr les réglages des paramètres qualité "Global quality", ont leur importance, notamment dans les images légèrement bruitées - le bruit chromatique est considéré par l'algorithme comme de la même couleur que le spot. Il faut donc avoir la possibilité de le supprimer, d'où la sélection "enhanced + chroma denoise" (il est possible que ce réglage soit insuffisant, agir en conséquence sur "Denoise local" si nécessaire).

Cet algorithme nouveau ('super') semble généralement fonctionner, mais dans le cas où le spot est sur une zone gris - neutre ou l'action sur des zones à faible gradient, l'algorithme peut être pris en défaut, dans ce cas utiliser l'ancien (quand c'est possible !!), car pour Retinex, Tone Mapping, CBDL je n'ai pas offert ce choix par souci de simplification)

Réduction des artefacts et l'algorithme "Global quality"

Par défaut, "Global quality" est à "Enhanced + chroma denoise". Certes cela augmente les temps de traitements, mais globalement c'est préférable. Vous pouvez, si vous trouvez les temps de rafraichissement long, choisir "enhance" ou "standard" et examiner l'image...

  • 2 curseurs permettent de réduire les artefacts et améliorer le rendu de l'algorithme. Ils agissent en fonction de la chroma, dans les tons gris neutres. Pour désactiver complètement l'effet il suffit de mettre "iterations = 0". Ces curseurs permettent, d'une part de réduire les artefacts et, d'autre part d'agir sur le rendu de l'image. L'action est possible pour "Color Light", "Exposure", "Retinex", "Vibrance", "Tone Mapping" et "Contrast by details levels".
  • lorsque les images sont bruitées, même légèrement (beaucoup d’images sont bruitées sans que cela soit gênant par exemple les ciels, les nuages,...), les algorithmes sont "trompés", ne pas hésiter à laisser activé "Global quality = enhanced + chroma denoise" et (quelquefois) activer "denoise local" et agir très légèrement sur les curseurs (y compris luminance).
  • dans certaines circonstances, par exemple avec Tone-mapping, le système de réduction d'artefacts peut générer des artefacts. Dans ce cas, mettre le slider "iterations" à 0.

Vous pouvez choisir la valeur par défaut de "Global Quality", par exemple si vos images sont très peu bruitées, et ainsi réduire notablement les temps de traitement. Pour cela, aller dans "Preferences", "Performance and Quality", "Local adjustements" et choisir entre Les 3 propositions. C'est ce choix qui sera proposé par défaut à l'utilisateur pour chaque nouveau "Spot", bien sûr il est possible ensuite de modifier ce choix, en sélectionnant la combo-box "Global Quality"

Les fichiers *.mip - les principes de l’algorithme multipoints

Afin de permettre le fonctionnement - enregistrement des valeurs pour chaque point de contrôle - un fichier de type texte, assez proche des fichiers pp3 est enregistré à deux endroits possibles :

  • à côté du fichier à traiter. Si par exemple vous traitez le fichier ASC4509.NEF, un fichier ASC4509.NEF.mip sera enregistré dans le même dossier. Si vous choisissez cet emplacement, vous pourrez ouvrir plusieurs sessions pour un même fichier image, si celui-ci est présent dans des dossiers différents. Par contre, le nom des dossiers et du "path" doit obligatoirement n'avoir que des caractères ASCII...sinon plantage.
  • dans le dossier "mip", à l'intérieur du dossier "cache" (via un "hash number MD5" qui identifie le fichier). Valeur par défaut. Si vous choisissez cet emplacement, si le fichier image est présent dans plusieurs dossiers, il y aura plusieurs fichiers mip. Cette option permet d'utiliser des dossiers et "path" avec des caractères NON ASCII.
  • le choix entre ces emplacements est possible à partir de : Preferences / Image processing / Mip Profiles

Ce fichier mip contient les données qui seront ensuite passées au programme, via d'une part les processus de type "procparams" et d'autre part des LUT qui permettent le fonctionnement en mode zoom. Lors de la mise à jour d'une nouvelle version, il pourra dans certains cas être demandé d'effacer les fichiers *.mip (voire le cache) afin d'éviter un crash. Pour cela vous pouvez aller dans "Preferences" / "Files browser", puis "Clear mip" et / ou "clear pp3" - si bien sûr vous avez positionné "mip" et "pp3" dans le cache, sinon il faudra exécuter cette opération manuellement dans le dossier courant. La présence d'anciennes versions de fichiers "mip" ou de "pp3" peut amener de l'instabilité voire un crash du système.

Architecture du système

Lorsque je me suis "aventuré" vers la possibilité d'un système multipoints sans calques, sans masques,...il était obligatoire de refuser de dupliquer le code. Comment envisager par exemple pour 10 points de contrôles, 10 codes GUI, et autant de code dans Rtengine. Après réflexion, l’idée est venue d'avoir un fichier mis à jour en temps réel - c'est à dire qui suit les modifications faites par l'utilisateur - de l’historique des actions / modifications.

Bien sûr, les variables utilisées par Rawtherapee, au niveau de l'interface GUI, et par la suite dans l'ensemble du code via "params", sont de type divers:

  • numériques : entier, float, double,...
  • booléenne
  • choix (menus pour "méthodes") de type string
  • courbes via des "vectors" de type double a dimension dynamique.
  • ...

Conversion des données

La première étape - afin de simplifier ensuite la gestion des données - est de convertir toutes ces données en entiers. Dans quelques cas cela peut aboutir à une très légère perte de précision, qui de mon point de vue est tout à fait négligeable.

  • Cette opération est très simple pour les valeurs numériques, même si elle peut aboutir dans certains cas (la teinte - Hue - s'exprime en radians dans l’intervalle -Pi + Pi) par une double transformation "float * 100 et / 100" pour garder la précision.
  • Elle est logique pour les opérations booléennes et les méthodes.
  • Par contre elle s'est avérée complexe pour les courbes. Les valeurs à stocker dans le fichier texte sont de type vector<double> soit un tableau dynamique de valeurs numériques. Probablement il doit y avoir un moyen "plus simple" en utilisant les fonctions qui sont utilisées dans "Procparams", mais je ne suis pas arrivé à les mettre en œuvre. J'ai contourné l'obstacle en :
  1. transformant les valeurs doubles en entier avec 3 chiffres significatifs - ce qui est largement suffisant
  2. puis en convertissant le "vector" en une chaine de caractère de longueur variable
  3. la lecture et l'écriture de cette chaine et sa conversion en "vector" se faisant dynamiquement par une fonction appropriée ("strcurv_data"). A noter que cette fonction permet de modifier des courbes jusqu'à une limite de 16 points d'inflexion (Courbe de Beziers) pour la courbe plate, et 32 pour la diagonale, ce qui devrait être suffisant. Si c'était insuffisant (??) il est possible (via une perte de compatibilité) d'accroître ce nombre.

Quelques éléments sur les courbes

L'implémentation des courbes a été complexe, au delà de ce qui est écrit ci-dessus, notamment :

  1. chaque courbe doit obligatoirement avoir une fonction reset - resize() à chaque itération;
  2. ce qui implique des curiosités au niveau de leur description, par exemple la courbe diagonale est initialisée avec 5 points, alors qu'elle a l'air "vide". C'est indispensable au bon fonctionnement. Mais ceci a pour conséquence que cette courbe est toujours ouverte / active. Donc cela implique si on veut éviter des consommations de temps en mode "preview" que l'utilisateur "active" la courbe en activant la combobox "curves". Cette même activation est aussi nécessaire pour les courbes L=f(H) et C=f(C). Bien sûr, on se serait tenté de penser qu'il suffit d'activer le mode "enabled" de la fonction "courbes" (linéaire), mais après de nombreux essais cette démarche est infructueuse!
  3. tout au long des procédures, il est obligatoire de mettre "clear" chaque valeur de "params" pour les courbes, chaque LUT, pour chaque itération et ensuite via "vector" de réattribuer les bonnes valeurs courantes à "params courbe".

Stockage et utilisation dynamique des données

Une fois les données converties :

  • elles sont stockées dans un fichier texte
  • chacune est référencée dans un tableau dynamique à deux dimensions :
  1. dataspot[x][y], pour les valeurs numériques, booléenne et les méthodes, où 'x' représente l'indice représentatif de la variable, par exemple '9' correspond à 'Lightness', et 'y' représente le point de contrôle courant. La valeur '0' représente la valeur courante en cours d'utilisation (celle stockée dans 'params").
  2. retistr[y], llstr[y], lhstr[y] et ccstr(y) pour les variables de type "curve" (aujourd'hui il n'y a que 4 variables celle utilisée dans "Retinex" local, et celles dans "Color and light" (L=f(L), C=f(C) et L=f(H)), mais il est assez facile d'en ajouter), avec 'y' comme ci-dessus.

Ce stockage et utilisation - nous reviendrons plus loin sur l'algorithme lecture / écriture dynamique - convient aisément pour le fichier Improccoordinator.cc (support de la gestion courante - Preview) et Simpleprocess.cc (sortie TIF / JPG), mais ne peut convenir, pour Dcrop.cc et la vision partielle de l'image (les fameux pipeline de Rawtherapee).

Pour ce cas (zoom - Preview) il a fallu imaginer autre chose, qui assure en temps réel la synchronisation des modifications. J'ai utilisé des LUT, dans le cas actuel, à chaque donnée référencée dans les tableaux ci dessus est associé une LUTi(z), avec z=500 entrées possibles (500 correspond à la limite informatique du nombre de points de contrôles...qu'on peut très facilement accroitre ou réduire). 'z' pour les LUTi correspond à 'y' pour dataspot. Une LUTi avec 25000 (arbitraire) entrées est utilisée pour "retistr", "llstr", "lhstr", "ccstr", pour garder en mémoire (sous forme d'un entier) chaque valeur du 'Vector' de la courbe (il peut y en avoir jusque 69).

Au cours du traitement, des échanges sont réalisés entre: params, les tableaux dynamiques et les LUTi. Les valeurs utilisées par Dcrop.cc sont liées dynamiquement aux tableaux dynamiques par parent->.

Processus d'échanges et stockage des données dynamiques

Sans entrer dans une description fastidieuse, je resterais aux principes généraux :

  1. lecture du fichier "mip" pour lire la version et orienter les mises à jour
  2. première écriture du fichier "mip" s'il n'existe pas
  3. stockage des données dans les LUTi et les tableaux dynamiques à partir des valeurs stockées dans "Params" (valeurs index 0)
  4. première mise à jour interactive avec le GUI via une fonction de transfert entre Rtengine et locallab.cc (aloListener->localretChanged). Cette fonction fait partie des 3 nécessaires pour obtenir un fonctionnement correct.
  5. lecture du fichier texte "mip" et stockage des données dans les tableaux dynamiques (valeurs index ==> y) - selon le nombre de points de contrôle
  6. Création d'une boucle - selon le nombre de points de contrôle- où à partir des valeurs stockées dans les variables tableaux dynamique, les LUTi (nécessaires à Dcrop) et les valeurs de Params sont actualisées.
  7. Appel de la fonction "Lab_local" qui contient les algorithmes de contrôle de chaque point (luminance, Sharp, retinex, denoise, etc.)
  8. deuxième mise à jour interactive avec le GUI via une autre fonction de transfert entre Rtengine et locallab.cc
  9. puis traitement du point de contrôle courant, en récupérant les valeurs index (0) des tableaux dynamiques. Ces valeurs sont attribuées à : 1) params, 2) LUTi, 3) valeurs index en cours
  10. Appel de la fonction "Lab_local" pour le point courant.
  11. sauvegarde du fichier "mip"

A noter que si l'utilisateur, modifie une courbe, amplitude ou nombre de points d'inflexion, une troisième mise à jour interactive est réalisée pour mettre en conformité l’ensemble des données en fonction des événements.

Quelques fantaisies incontournables

Bien sûr, tout à l'air simple, mais le système ne fonctionne que, si et seulement si, toutes les données sont dynamiquement mises à jour.

J'ai beaucoup essayé, tâtonné, pour aboutir à une solution qui fonctionne...certes curieuse; il y a probablement un moyen plus "informatique" de traiter cela, mais à ce stade, j'ai fait comme décrit ci-dessus et ci-après.

Les 3 échanges entre Rtengine et le GUI se font notamment avec 3 variables qui ne servent à rien dans le programme - sinon à mettre à jour:

  1. "anbspot" qui prend les valeurs forcées 0 ou 1
  2. "cTgainshaperab" (curve), dont je fais osciller une valeur entre 0.70 et 0.90
  3. "retrab" qui oscille autour de 500.

J'ai ajouté 3 variables (sous forme de "sliders") - hueref, chromaref, lumaref, totalement invisibles à l'utilisateur, mais qui servent à rafraichir le système en temps réel, pour permettre la bonne prise en compte des valeurs "spot" de référence.

Les appels aux changements de ces 3 variables amènent la stabilité au système et une mise à jour en temps réel. Il ne devrait pas être nécessaire d’accroitre le nombre de ces variables "fantaisistes"

De plus j'ai été amené à empiriquement mettre des temporisations, pour laisser le temps au temps... C'est notamment le cas pour la modification de la courbe par l’utilisateur (amplitude, nombre de points d'inflexion).

Bien sûr ces variables sont invisibles pour l'utilisateur, sinon dans l'historique !

Quelques particularités du mode local (par rapport à Lab adjustements)

Voici quelques informations qui peuvent intéresser l'utilisateur. Ces informations sont souvent des particularités du mode local

Color and Light

  • Les algorithmes utilisés pour la luminance et le contraste sont différents de ceux utilisés par "Lab adjustements", ce qui peut amener quelques différences de rendu.
  • L'algorithme de luminance est réalisé de telle manière que en dessous de -90 et jusque -100 pour "lightness", il est possible d'accroître la "darkness" de l'image, pratiquement jusqu'à obtenir une valeur de luminance proche de 0. Si vous souhaitez accentuer cet effet, réduisez également la chominance et accroissez "scope".
  • Le mode inverse, peut servir pour l'essentiel, à réaliser des cadres dégradés. Dans ce cas, si vous sélectionnez -100 pour "lightness", et réduisez la chrominance, la "bordure" sera noire.
  • pour la luminance et le contraste (curseur), vous avez le choix entre 2 algorithmes : le premier (par défaut) est très proche de ce qui était présent jusque là, le second activé par "Lightness Contrast super" est proche de celui utilisé en courbe L=F(L) "super"
  • Une courbe L=f(L) et une C=f(C) permet de moduler la luminance ou la chrominance pour chaque point de contrôle en fonction de la luminance ou de la chrominance. Pour les rendre actives, il est nécessaire d'activer la combobox "curves".
  • Une courbe L=f(H) permet de moduler la luminance pour chaque point de contrôle en fonction de la teinte. Pour la rendre active, il faut activer la checkbox "curves type".
  • Une courbe H=f(H) permet de moduler la teinte pour chaque point de contrôle en fonction de la teinte. Pour la rendre active, il faut activer la checkbox "curves type".

Courbe L=f(L)

  • deux choix sont offerts : a) Normal, les courbes - notamment la plus complexe à gérer L=f(L) utilise un algorithme proche de celui utilisé avec les curseurs (mode Normal); b) Super, utilise un nouvel algorithme que je pense très performant (le résultat m'a même surpris à la première utilisation).
  • ne pas hésiter selon le cas, à activer dans certains cas "Global quality" = enhanced et enhanced + chroma denoise"

Attention, lorsque le spot est située dans une zone grise, ou des zones assez uniformes, les artefacts avec le nouvel algorithme (L=F(L) super, et Lightness Contrast super) peuvent être impossible à supprimer, dans ce cas privilégier les 2 anciennes versions.

Exposure

Ce module "ressemble" à celui en mode global RGB, mais :

  • il fonctionne entièrement en mode L*a*b*, d'où des différences de rendu;
  • il n'a pas les curseurs "lightness, chroma et contraste" dont les fonctions sont déjà présentes dans "Color and Light"
  • il y a une seule courbe "contraste", similaire à celle de L=F(L) présente dans "Color and Light". Il est évident que le rendu de cette courbe est différent de "Tonecurve" qui agit en mode RGB. Vous pouvez si vous le souhaitez activer les 2 courbes L=f(L) dans "Color and Light" et "Exposure"


Blur and Noise

Blur n'est actif que si Radius supérieur ou égal à 2.

En réduisant notablement la valeur par défaut de "scope" et en agissant éventuellement sur "Luminance only" il est possible d'obtenir des flous différenciés selon la teinte.

Vibrance

Module similaire à celui du menu principal.

Retinex

Le nombre de réglages est réduit, par rapport au mode standard. D'autre part, "Retinex local" agit en fin de processus contrairement au mode standard qui est au début du processus Raw. Depuis la version mip 10002, la courbe "transmission gain" est spécifique à chaque point de contrôle.

Tone mapping

Attention aux artefacts lorsque les aplats (ciels, zones grises...) sont d'une teinte similaire au point de contrôle. Dans le cas d'artefacts, mettre le curseur "iterations" de "Reduce artefacts - improve algorithm" à zéro.

Sharpening

Seul le mode "RL deconvolution" est proposé.

Contrast By Detail Levels

  • 5 niveaux au lieu de 6 pour le mode pleine image.
  • pas de curseurs pour la gestion de la peau; le système utilisé par les points de contrôle le remplace.

Denoise

  • par rapport au mode pleine image, seul l'outil wavelet est utilisé: donc pas de fonction de Fourier, ni de medians
  • moins de curseurs et de courbes
  • par contre, vous pouvez différencier l'action sur la luminance et la chrominance en fonction de la grosseur du bruit - fine ou coarse.

Temps de traitement et utilisation de la mémoire

Lorsqu'on utilise la sortie JPG ou TIF, et pour le mode "normal", l'algorithme n'effectue les calculs que pour la zone délimitée. En ce sens les temps de traitement et l'occupation mémoire sont réduits. Bien sûr le temps de traitement va dépendre du nombre de points de contrôles, de leur taille, et du type de traitement.

Si on exclue "Denoise" et "Sharp", les temps de traitement sont de l'ordre de quelques dixièmes de seconde par point de contrôle, et le besoin en mémoire de l'ordre de quelques centaines de M.

Deux réglages agissent fortement sur les temps de traitement et le besoin en mémoire :

  • denoise qui ajoute selon la taille du point de contrôle de l'ordre de 1 seconde et 1 M de mémoire.
  • quality enhanced and chroma denoise, qui ajoute environ selon le point de contrôle de l'ordre de 0.5 secondes et 0.6 M.

Onglet Preferences

J'ai regroupé ici, les réglages (repris par ailleurs sur cette page) accessibles depuis "Preferences"

  • si vous sélectionnez en "Preferences" / "General" / "Local adjustements", en cochant la case "Show spot delimiters", vous obtiendrez une approximation de la zone concernée par le spot et ses réglages
  • Vous pouvez choisir la valeur par défaut de "Global Quality", par exemple si vos images sont très peu bruitées, et ainsi réduire notablement les temps de traitement.Pour cela, aller dans "Preferences", "Performance and Quality", "Local adjustements" et choisir entre Les 3 propositions. C'est ce choix qui sera proposé par défaut à l'utilisateur pour chaque nouveau "Spot", bien sûr il est possible ensuite de modifier ce choix, en sélectionnant la combo-box "Global Quality"
  • Fichiers "mip":
    • le choix de l'emplacement est possible à partir de : Preferences / Image processing / Mip Profiles
    • effacement : aller dans "Preferences" / "Files browser", puis "Clear mip" et / ou "clear pp3" - si bien sûr vous avez positionné "mip" et "pp3" dans le cache, sinon il faudra exécuter cette opération manuellement dans le dossier courant. La présence d'anciennes versions de fichiers "mip" ou de "pp3" peut amener de l'instabilité voire un crash du système.

Évolutions

En dehors des habituelles mises aux points, bug, améliorations, réglages, interface, etc. Il serait souhaitable :

  • d'améliorer le GUI, pour pouvoir créer / sélectionner / modifier chaque point de contrôle.
  • rendre possible, mais ce n'est pas spécifique à "Locallab", la mise en mémoire des "expanders" (ouvert / fermé).


En termes "informatique", il devrait être possible pour accroître la lisibilité et la maintenance, d'intégrer l'ensemble du code fichiers *.mip qui actuellement sont linéairement intégrés à Improccoordinator.cc, dcrop.cc et simpleprocess.cc à des procédures "void", à l'exemple de rgbproc.cc