Un modèle aléatoire pour le grain photographique

Pista negra El 4 agosto 2020  - Escrito por  Julie Delon, Alasdair Newson Ver los comentarios

De nos jours, de nombreux photographes et réalisateurs considèrent toujours que la photographie numérique n’a pas le charme de la pellicule argentique, et cherchent à traiter leurs images pour retrouver, entre autres, l’aspect granuleux de la pellicule traditionnelle. Dans cet article, nous allons voir comment un modèle aléatoire tout simple permet d’imiter le rendu du grain sur des images numériques, et comment on peut le simuler numériquement.

L’apparition de la photographie numérique avant le tournant du millénaire a changé la manière dont on prend, gère, stocke, transmet et «consomme» des images. Malgré les nombreux avantages du format numérique, des photographes et réalisateurs continuent à préférer la pellicule argentique, pour des raisons artistiques. Ainsi, Quentin Tarantino n’hésite pas à déclarer lors du festival de Cannes 2014 que «la projection digitale... est la mort du cinéma tel que je le connais» [Smi14].

La figure suivante, due à Rob Taylor-Case, représente les différentes couches d’une pellicule argentique.

PNG - 306.1 KB

Cette pellicule a une spécificité : elle contient du grain, une texture créée par les agrégats (amas) de particules photosensibles qui la constituent. A l’échelle microscopique, le négatif analogique peut donc être représenté comme une image en noir et blanc (sans niveau de gris) : soit une particule est présente et la lumière est bloquée, soit il n’y a pas de particule et la lumière passe. Ces particules ou cristaux sont microscopiques, ils font quelques micromètres ($10^{-6}m$), les humains ne peuvent donc pas les percevoir en regardant une photographie ou un négatif : ce que nous voyons, ce sont des moyennes locales de cette densité de grains.

Imiter le grain. Des logiciels dédiés aux photographes (Dxo FilmPack par exemple) proposent de reproduire la texture de grain des images argentiques sur des images numériques. Pour cela, ils scannent des négatifs d’images argentiques, et tentent d’appliquer la texture de grain obtenue sur des images numériques. Les résultats sont donc déterministes, dans le sens où si le grain est appliqué deux fois sur la même image, nous obtiendrons le même résultat. Ce manque d’aléa est un défaut lorsqu’on veut appliquer ce type d’approche à des vidéos. De plus, la qualité du résultat dépend directement de la qualité du scan de l’image de grain.

Dans cet article, nous allons voir que l’effet du grain sur une image peut être reproduit simplement grâce à un modèle aléatoire, appelé modèle booléen [1].

Le processus photographique

Le processus photographique argentique est divisé en deux étapes. Lors de la prise de vue, les cristaux photosensibles de la pellicule sont exposés à la lumière, et leur interaction avec les photons les rend «développables». Lors du développement photographique, ces cristaux ayant interagi avec la lumière sont transformés en grains d’argent solides. Le résultat est le négatif photographique, qui est à nouveau exposé à la lumière et développé en «positif» sur du papier photosensible. Une illustration est proposée ci-dessus : à gauche la scène, à droite le négatif et au milieu le positif. Le zoom en bas à droite des images correspond à la zone près de l’oeil encadrée en rouge.

JPEG - 1018.1 KB

Un moyen de modéliser le processus photographique mathématiquement est de considérer que les grains sont des ensembles fermés et bornés du plan. Le négatif serait donc une image constituée d’un fond blanc sur lequel on aurait jeté ces ensembles noirs.

Le modèle booléen homogène

Pour définir un modèle booléen homogène du plan $\mathbb{R}^2$, il faut d’abord définir ce qu’on appelle un processus ponctuel de Poisson homogène d’intensité $\lambda$ [2] du plan. C’est un ensemble aléatoire de points du plan $\{x_1,x_2,x_3\dots\}$, qui vérifie les deux propriétés suivantes :

  1. le nombre de points qui tombent dans une région $A$ d’aire $|A|$ suit une loi de Poisson [3] de paramètre $\lambda \times |A|$,
  2. les nombres de points tombant dans des ensembles disjoints du plan sont indépendants.

Les points $x_i$ représentent les centres de nos grains. On choisit un rayon $r$ positif, et on définit alors notre modèle booléen comme l’ensemble aléatoire

$Z = B(x_1) \cup B(x_2) \cup B(x_3) \cup \dots$

où $B(x)$ est un disque de rayon $r$ centré en $x$. On utilise ici des disques pour simplifier mais on pourrait les remplacer par des ensembles aléatoires plus généraux.

Cet ensemble $Z$ est aléatoire (dépend du hasard) car les positions des points $x_i$ le sont. Visuellement, on peut se le représenter comme un ensemble de disques blancs jetés aléatoirement sur un fond noir, comme ci-dessous.

JPEG - 161.8 KB

On peut montrer que la proportion de la surface du plan recouverte par les disques blancs vaut

$1 - e^{-\lambda \pi r^2}.$

Plus le rayon des disques est grand et plus l’intensité $\lambda$ est
élevée, plus cette proportion est proche de $1$.

Le bloc replié ci-dessous propose une explication de cette formule, sa lecture demande des notions un peu plus avancées que le reste de l’article.

Surface du plan recouverte par un modèle booléen

Soit $Z$ notre modèle booléen du plan constitué de boules de rayon $r$
$Z = B(x_1) \cup B(x_2) \cup B(x_3) \cup \dots$.

Tout d’abord, remarquons que la probabilité qu’un point $x$ du plan soit dans l’ensemble $Z$ ne dépend pas de la position de $x$, car notre ensemble aléatoire de points est stationnaire (ses propriétés statistiques sont invariantes par translation). Donc pour tout $x$, la probabilité que $x$ soit dans $Z$ est égale à la probabilité que l’origine $o$ du plan soit dans $Z$.

Toujours grâce à cette propriété de stationnarité, la proportion du plan recouverte par les disques blancs peut être calculée comme l’aire moyenne de l’intersection entre $Z$ et le carré $[0,1]\times[0,1]$.

Soit $C$ ce carré, alors, en notant $\mathbf{1}_Z$ la fonction sur $\mathbb{R}^2$ qui vaut $1$ sur l’ensemble $Z$ et $0$ partout ailleurs, on a

$\mathbb{E}[|Z \cap C|] = \mathbb{E}[\int_C \mathbf{1}_Z(x)dx] = \int_C \mathbb{E}[\mathbf{1}_Z(x)] dx = \int_C \mathbb{P}[x\in Z] dx = |C| \mathbb{P}[o\in Z] = \mathbb{P}[o\in Z].$

La proportion $p$ du plan recouverte par les disques blancs est donc égale à la probabilité que l’ensemble aléatoire $Z$ contienne l’origine $o$ du plan.
Remarquons maintenant que l’origine appartient à $Z$ si et seulement si au moins un point de l’ensemble $\{x_1,x_2,x_3\dots\}$ tombe dans la boule $B(o)$ centrée en $o$ de rayon $r$. Or, on a vu que le nombre de points de ce processus ponctuel tombant dans $B(o)$ suivait une loi de Poisson de paramètre $\lambda$ fois la surface de la boule, donc $\lambda \pi r^2$. La probabilité $p$ qu’au moins un point de l’ensemble aléatoire $\{x_1,x_2,x_3\dots\}$ tombe dans la boule $B(o)$ valant $1$ moins la probabilité qu’aucun des points ne tombe dans la boule, on a $p = 1 - e^{-\lambda \pi r^2}$.

Ce modèle booléen est utilisé pour représenter le grain à l’échelle microscopique. On peut déjà noter qu’une particularité de ce modèle est sa tendance à créer un effet visuel d’amas de grains, très important pour le réalisme de reproduction du grain argentique. Ce modèle est également assez facile à simuler numériquement à l’aide d’un ordinateur.

Comment utiliser le modèle booléen pour imiter le grain argentique sur une image ?

Une image numérique en niveau de gris est une matrice dont chaque entrée représente un pixel et contient une valeur de gris, généralement entre $0$ et $255$ (pour une image codée sur 8 bits), comme illustré ci-dessous.

PNG - 241.2 KB

Une image couleur n’est rien d’autre que 3 images en niveau de gris, correspondant aux canaux vert, rouge et bleu.

Normalisation.

Supposons que l’on observe une image numérique en niveau de gris et qu’on souhaite en créer une version avec du grain. On commence par normaliser l’image : on divise toutes ses valeurs par une valeur légèrement supérieure à $M$, où $M$ est le niveau de gris maximum apparaissant dans l’image. On peut alors décrire l’image par l’ensemble de ses pixels $u(0,0),\dots,u(m-1,n-1)$ si l’image possède $m$ lignes et $n$ colonnes. Chaque valeur est un nombre entre $0$ et $1$. On exclut la valeur 1 car elle ne sera pas physiquement réalisable par notre modèle booléen : il faudrait en effet une infinité de grains pour être certain qu’ils couvrent tout le plan.

Un modèle booléen homogène par morceaux.

Pour simuler un «négatif argentique» de notre image numérique $u$, on simule un modèle booléen $Z$ sur le rectangle $[0,m)\times [0,n)$ [4], le rectangle de sommets $(0,0)$, $(n,0)$, $(m,n)$ et $(0,m)$. Ce sous ensemble est divisé en carrés : le carré $[k,k+1)\times[j,j+1)$ correspond au «pixel» $(k,j)$ de l’image $u$.
On remplit chacun de ces carrés selon un modèle booléen homogène (avec un rayon $r$ beaucoup plus petit que $1$, par exemple $0.05$) dont on choisit l’intensité afin d’obtenir la bonne moyenne, définie par $u(k,j)$ sur le
carré $(k,j)$, c’est-à-dire de sommets $(k,j)$, $(k+1,j)$, $(k+1,j+1)$ et
$(k,j+1)$ [5]. On obtient ainsi
une image définie en chaque point du rectangle et non plus carré
par carré.
On montre ci-dessous une figure montrant la réalisation d’un tel modèle booléen pour une image à 4 pixels.

PNG - 629.1 KB

Filtrer l’image positive.

Une réalisation de ce modèle booléen nous donne une image binaire, c’est-à-dire composée uniquement de noir et de blanc, qui vaut $1$ sur l’ensemble $Z$ et $0$ partout ailleurs. Mathématiquement, on la note $\mathbf{1}_Z$ et on l’appelle l’indicatrice de l’ensemble $Z$. Elle est définie partout sur l’ensemble $[0,m)\times [0,n)$. On peut la voir comme notre positif argentique (le négatif serait $1 - \mathbf{1}_Z$).

Une étape importante du processus photographique n’a pas encore été modélisée : l’étape dite d’exposition pendant laquelle le négatif est projeté sur du papier photosensible. Lors de cette étape, le film négatif est illuminé et la lumière passe à travers un objectif agrandisseur qui la projette sur le papier. Le passage de la lumière à travers cet objectif introduit un flou dans l’image projetée : chaque point du négatif illuminé devient une petite tache symétrique sur le papier. On parle de filtrage optique.

Mathématiquement, ce filtrage optique s’écrit comme une opération dite de convolution, notée $*$ ici, entre notre image $\mathbf{1}_Z$ et un filtre $\psi$. Le résultat $\psi * \mathbf{1}_Z$ est une image définie partout sur $[0,m)\times [0,n)$ et qui n’est plus une image binaire (elle prend des valeurs de gris).

Convolution de $\mathbf{1}_Z$ avec un filtre $\psi$.

Notre image binaire $\mathbf{1}_Z$ et notre filtre $\psi$ sont des fonctions du plan et à valeurs dans $\mathbb{R}$. Lorsqu’on les convole, on obtient une nouvelle fonction du plan à valeurs réelles, qui s’écrit, pour tout point $x$ du plan

$\psi * \mathbf{1}_Z (x) = \int_{\mathbb{R}^2} \mathbf{1}_Z(x-t)\psi(t)dt.$

Attention, il s’agit d’une intégrale double et $t$ désigne une variable de $\mathbb{R}^2$. Si on écrit $x = (x_1,x_2)$ et $t=(t_1,t_2)$, l’intégrale vaut

$\psi * \mathbf{1}_Z (x_1,x_2) = \int_{\mathbb{R}} \int_{\mathbb{R}}\mathbf{1}_Z(x_1-t_1,x_2-t_2)\psi(t_1,t_2)dt_1dt_2.$

On voit que la valeur de la nouvelle fonction en $x$ est une moyenne des valeurs de l’image $\mathbf{1}_Z$ autour du point $x$, pondérée par le filtre $\psi$, ce qui donne une version floue de notre image binaire $\mathbf{1}_Z$.

Discrétisation.

Pour obtenir une image finale sous forme numérique, notre image continue $\psi * \mathbf{1}_Z$ définie sur $[0,m)\times [0,n)$ doit ensuite être discrétisée sur une grille. Cette grille n’a pas nécessairement à être la même que celle de l’image $u$ de départ. Par exemple, elle peut être deux fois plus fine : à chaque pixel de l’image d’entrée correspondront quatre pixels dans l’image de sortie. On obtient ainsi une image de sortie de résolution (nombre de lignes et nombre de colonnes) différente de celle de l’image de départ.

Algorithme et rendu

Tout cela est bien joli, mais comment fait-on en pratique pour implémenter ce qui précède sur un ordinateur ? On décrit ci-dessous un algorithme permettant ce rendu et nous allons voir que certaines étapes demandent un peu d’astuce.

Comme nous venons de le faire remarquer, si l’on part d’une image numérique d’entrée de taille $m \times n$, rien ne nous oblige à ce que l’image de sortie de l’algorithme soit de même taille. On suppose dans ce qui suit que cette image de sortie est de taille $ms \times ns$, avec $s$ un facteur de zoom entre l’image d’entrée et l’image de sortie. Par exemple $s=2$ donnera une image de sortie avec deux fois plus de lignes et deux fois plus de colonnes, et $s=1$ donnera une image de même taille.

Pour faciliter la lecture, l’algorithme que nous allons décrire est illustré par le schéma ci-dessous.

JPEG - 511.9 KB

1. Calcul des intensités du modèle booléen.

Le début est simple. On rappelle que notre processus de Poisson a une intensité constante sur chaque carré $[k,k+1)\times[j,j+1)$. Pour le carré correspondant au pixel $(k,j)$ de $u$, on calcule donc l’intensité $\lambda(k,j)$ du processus de Poisson de manière à ce que la moyenne du modèle booléen sur ce carré soit égale à $u(k,j)$ [6].

2. Échantillonnage des grains.

On simule ensuite les centres des boules de notre modèle booléen sur chaque pixel. Pour simuler notre processus ponctuel sur le pixel $(k,j)$, on tire d’abord le nombre $p$ de points du processus, selon une loi de Poisson de paramètre $\lambda(k,j)$, puis on tire avec une loi uniforme $p$ points dans le carré $[k,k+1)\times[j,j+1)$. La réalisation de l’ensemble de ces processus peut être stockée sous la forme d’une liste de points $\{x_i\}_{i\in I}$ sur la surface $[0,m)\times [0,n)$, qui représentent les centres des grains de notre modèle $Z$.

3. Evaluation du modèle filtré.

La troisième étape consiste à calculer numériquement la convolution $\psi * \mathbf{1}_Z$ en tout point de notre image de sortie, c’est-à-dire pour chaque centre d’un pixel sur la grille de sortie de taille $ms \times ns$. Le filtre $\psi$ choisi ici est une gaussienne de moyenne nulle et de variance $\sigma^2$. Cette étape est délicate : potentiellement, notre modèle booléen $Z$ peut contenir plusieurs milliards de disques, donc calculer la convolution $\psi * \mathbf{1}_Z$ peut s’avèrer très compliqué numériquement.
Pour rendre les calculs envisageables, une solution consiste à approcher la convolution $\psi * \mathbf{1}_Z$ par simulation de Monte Carlo.

La méthode de Monte Carlo est une méthode numérique pour approcher une intégrale (ici le produit de convolution) à partir d’une somme. Nous pouvons en donner une interprétation intuitive pour notre application. Comme expliqué plus haut, le filtrage optique se traduit par le fait que chaque pixel illuminé de l’image $\mathbf{1}_Z$ a pour image une tache dans l’image projetée. L’intensité de cette tache peut être vue comme une densité de probabilité sur le plan, et est égale à notre filtre $\psi$. La méthode de Monte-Carlo consiste à réinterpréter ce flou en termes probabilistes, un peu comme si on suivait les photons un à un lors de l’étape d’exposition et que les photons étaient décalés de la position $x$ d’un pixel blanc en un point $x-v$, où la déviation $v$ suit la loi de densité de probabilité $\psi$. L’intensité moyenne observée en un point donné $x$ de l’image finale $\psi * \mathbf{1}_Z$ sera la moyenne des valeurs de l’image $\mathbf{1}_Z$ en $x-v$, où $v$ suit toujours cette même loi $\psi$. Or, cette moyenne peut se calculer en tirant des déplacements
aléatoires $v_1, v_2, v_3,....$ de loi $\psi$, et en prenant la moyenne
$(\mathbf{1}_Z(x-v_1)+\mathbf{1}_Z(x-v_2)+...+\mathbf{1}_Z(x-v_N))/N$ pour $N$ grand. C’est une conséquence de la loi des grands nombres. On doit en pratique faire ça pour tous les points $x$ de notre nouvelle grille de taille $ms \times ns$.

On peut voir une illustration de cette approche dans l’image suivante.

Le bloc suivant donne une explication un peu plus poussée mathématiquement de la méthode de Monte Carlo.

Méthode de Monte Carlo pour calculer $\psi * \mathbf{1}_Z$

La méthode de Monte Carlo est une méthode numérique permettant d’approcher la valeur d’une intégrale grâce à une somme. Dans le cas qui nous intéresse ici, on souhaite pour n’importe quel point $x$ de l’image de sortie calculer l’intégrale
$\psi * \mathbf{1}_Z (x) = \iint_{\mathbb{R}^2} \mathbf{1}_Z(x - t)\psi(t)dt.$
La fonction $\psi$ est la densité d’une loi sur $\mathbb{R}^2$, donc cette intégrale est aussi égale à l’espérance $\mathbb{E}[\mathbf{1}_Z (x - V)]$, où $V$ est un vecteur sur $\mathbb{R}^2$ dont la loi a pour densité $\psi$.

Pour approcher cette valeur, on utilise un résultat classique de probabilité, la loi des grands nombres. Supposons que l’on simule des vecteurs 2D $\{v_1,v_2,\dots,v_N\}$ indépendants et de même loi $\psi$. Alors la loi des grands nombres nous dit que lorsque le nombre $N$ augmente, la quantité $(\mathbf{1}_Z(x-v_1)+\mathbf{1}_Z(x-v_2)+...+\mathbf{1}_Z(x-v_N))/N$ tend vers l’espérance $\mathbb{E}[\mathbf{1}_Z (x - V)]$, donc vers l’intégrale que l’on souhaite calculer.

Pour chaque position $x$ où l’on souhaite calculer cette intégrale (en pratique pour chaque position de la grille de sortie de taille $ms \times ns$), on tire donc une liste aléatoire de décalages $\{v_1,v_2,\dots,v_N\}$ suivant une distribution de densité $\psi$. La valeur de sortie en $x$ est alors
$v(x) = \frac 1 N (\mathbf{1}_Z(x-v_1)+\dots +\mathbf{1}_Z(x-v_N) ) .$

On peut ainsi calculer les valeurs $v(x)$ pour tous les $x$ correspondant à la grille de sortie que l’on souhaite pour la nouvelle image.

On décrit plus précisément dans le bloc suivant l’algorithme tel qu’il est implémenté en pratique.

Un algorithme grain par grain efficace

Effectuer la simulation de Monte Carlo précédente de manière naïve, en calculant pour chaque point $x$ de la grille de sortie une série de décalages puis une moyenne, est très peu efficace. Il faut en effet tirer tous les centres des grains, pour chaque pixel de l’image de départ, puis les stocker (ils sont des milliards), et ensuite pour chaque pixel $x$ de la grille de sortie et chaque décalage $v_k$, il faut parcourir cette longue liste des grains pour savoir si $\mathbf{1}_Z(x-v_k)$ vaut 0 ou 1. En guise d’exemple, pour un rayon de grain $r=\frac{1}{40}$ (un pixel étant de taille 1), une image de résolution $2048 \times 2048$, constante égale à 128 partout, on aurait besoin de 35 Giga octets de mémoire pour stocker la liste des positions des grains !

On peut élaborer une approche plus astucieuse pour cette étape, qui évite de garder en mémoire l’ensemble des grains. D’abord, on commence par tirer $N$ décalages aléatoires $\{v_k, k = 1\dots N\}$ et on utilise ces mêmes décalages pour tous les pixels. Ensuite, on crée $N$ images binaires $u_1,\dots,u_N$ intermédiaires (voir le schéma ci-dessus), chaque image correspondant à un des décalages $v_k $. Si l’image numérique d’entrée est de taille $m \times n$, chacune de ces $N$ images intermédiaires est de taille $ms \times ns$ (on rappelle que $s$ est le facteur de zoom entre image d’entrée et image de sortie).

L’algorithme est alors constitué d’une boucle sur les pixels de l’image d’entrée. Pour chacun d’entre eux, on tire successivement des centre de grains $x_i$, et pour chaque grain $x_i$ et chaque image $u_k$, on se contente de référencer tous les pixels de $u_k$ dont les centres sont touchés par le grain centré en $x_i - v_k $. Ces pixels de $u_k$ sont mis à 1 et le grain $x_i$ est ensuite oublié. On répète cela pour tous les grains créés par notre modèle Booléen. A la fin de l’algorithme, il suffit de prendre la moyenne des images $u_1,\dots,u_N$ pour obtenir le résultat de notre simulation de Monte Carlo.

Quelques résultats

Visualisons maintenant quelques résultats de rendu de cet algorithme. Nous partons d’images argentiques qui ont été numérisées, et pour lesquelles le grain a été perdu à la numérisation. L’utilisateur peut régler les paramètres de l’approche afin d’avoir un grain d’aspect qui lui convient : un grain plus ou moins fin, avec plus ou moins d’amas. La taille de grain peut par exemple varier entre 0.02 pixels (très fin) et 0.1 pixels (assez épais).

Ci-dessous, nous montrons deux exemples de rendus à plusieurs échelles de zoom, de plus en plus fines (la valeur de $s$ est de plus en plus grande). L’encadré rouge correspond à la zone de l’image que l’on visualise à l’échelle suivante. A l’échelle la plus fine, on peut clairement voir les grains et l’image binaire sous-jacente.

JPEG - 722.8 KB
JPEG - 1.1 MB

L’algorithme permet de réaliser le rendu à n’importe quelle échelle, donc pour n’importe quelle taille de tirage de sortie. Ce point est très important, car on peut souhaiter faire un tirage de très grande taille.

Remarquons qu’on ne pourrait pas modéliser le grain avec un simple bruit indépendant et identiquement distribué (du bruit blanc) sur les pixels. Dans l’image suivante, divisée en deux parties, on a ajouté du bruit blanc en bas à gauche, alors qu’en haut à droite on a simulé du grain avec l’algorithme décrit ci-dessus.

PNG - 193.4 KB

On voit que le bruit blanc ne permet pas de retrouver les effets d’«amas» de grains.

Observons maintenant le rendu du grain sur une image d’entrée compressée. On part de l’image ci-dessous

PNG - 99.7 KB

Dans cette image d’entrée, les blocs de compression sont clairement visibles, notamment au voisinage de la main. On utilise alors notre simulateur de grain pour créer une nouvelle image. Nous avons l’impression subjective que la qualité et résolution de l’image ont été améliorées. Cette propriété est liée à une technique appelée dithering (ou détramage en français), qui consiste à ajouter du bruit à un signal avant de le quantifier pour éviter de voir apparaître des défauts de quantification.

PNG - 125.8 KB

Comparaison avec d’autres approches

Il existe d’autres méthodes de synthèse de grain de film argentique, et celles-ci sont souvent des méthodes dite «par l’exemple» : elles imitent des pellicules spécifiques. Dans ce type d’approche, on commence par scanner une photographie argentique d’une zone constante, prise avec la pellicule que l’on souhaite imiter, puis on calque cette image scannée sur une l’image numérique à laquelle on veut ajouter du grain. Cette étape de calque n’est pas une simple combinaison linéaire mais c’est une étape déterministe. Il n’y a donc aucune modélisation aléatoire ou générative du grain dans ce type de méthode. Ces approches ont l’avantage d’être simples à utiliser une fois que la photo du grain est obtenue, et par conséquent assez rapides.

Cependant, elles sont limitées par la qualité et la résolution de l’exemple. Notamment, elles ne permettent pas de dépasser la résolution de l’image de grain numérisée, ce qui est problématique si l’on souhaite ajouter du grain à une image ou une vidéo de résolution supérieure. Par ailleurs, ces méthodes ne peuvent pas inventer du grain, elle ne font que recopier le grain scanné. C’est un problème lorsqu’on souhaite les utiliser sur des vidéos, où il faut appliquer des images de grain différentes aux images successives du film.

Dans l’exemple ci-dessous, nous comparons le rendu de l’outil commercial DxO FilmPack (en haut à droite) avec celui de notre approche par modèle booléen (en bas à gauche).

Les paramètres de notre modèle sont choisis afin d’imiter le résultat de FilmPack. On voit que les résultats sont visuellement très similaires. En terme de temps d’exécution, l’outil de FilmPack prend environ une seconde pour une image haute résolution ($2048\times2048$). La méthode aléatoire présentée dans cet article nécessite beaucoup plus de calculs, mais les temps de calculs restent raisonnables avec du matériel adéquat et une programmation sur carte graphique. Voici quelques exemples de temps d’exécution sur un ordinateur équipé d’une GPU Nvidia Tesla T10, et pour plusieurs tailles d’images :

Résolution 256x256 512x512 1024x1024 2048x2048
Temps d’exécution 0.137 s 0.429 s 1.275 s 4.534 s

Pour finir cette présentation, on peut se demander comment appliquer du grain à des images couleur. Un film argentique couleur consiste en plusieurs couches d’émulsion, chacune séparée par un filtre qui permet une interaction avec une seule couleur. Ainsi, on peut faire l’hypothèse que les couches sont indépendantes, et appliquer notre algorithme séparément à chaque canal couleur ! On illustre ci-dessous le résultat de synthèse sur deux images.

JPEG - 530.7 KB
JPEG - 1.5 MB

Si vous voulez aller plus loin et tester le rendu argentique sur vos propres photographies, vous pouvez vous rendre sur ce site, dans l’onglet démo !

Références.
[Newson17CGF] Alasdair Newson, Julie Delon, Bruno Galerne, A Stochastic Film Grain Model for Resolution-Independent Rendering, Comput. Graph. Forum36(8): 684-699 (2017)

[Newson17ipol] Alasdair Newson, Noura Faraj, Bruno Galerne, Julie Delon, Realistic Film Grain Rendering. IPOL Journal 7: 165-183 (2017)

[Smi14] S MITH N. M.: Quentin Tarantino Blasts Digital Projection at Cannes: ’It’s the death of cinema.’, May 2014.

Post-scriptum :

Nous remercions Clotilde Fermanian, Angela Gammella-Mathieu et Jérôme Buzzi pour leurs relectures attentives et leurs commentaires constructifs !

Article édité par Jérôme Buzzi

Notas

[1George Boole (1815-1864) est un mathématicien anglais, en grande partie autodidacte, et l’un des fondateurs de la logique moderne. Il a également beaucoup contribué à la théorie des probabilités.

[2la lettre grecque $\lambda$ désigne ici un nombre réel.

[3Une variable aléatoire $X$ suit loi de Poisson de paramètre $\lambda$ si elle ne prend que des valeurs entières et que $\mathbb{P}[X = k ] = \frac{\lambda ^k }{k ! } e^{-\lambda k}$ pour tout entier naturel $k$.

[4La notation $[a,b)$ désigne l’intervalle des réels entre $a$ (compris) et $b$ (exclu).

[5Pour cela, l’intensité du processus ponctuel sur le carré $[k,k+1)\times[j,j+1)$ est définie par
$\lambda(k,j) =\frac{1}{\pi r^2}\log \left( \frac 1 {1 - u(k,j)}\right)$,
où $u(k,j)$ est la valeur de l’image discrète de départ sur le pixel $(k,j)$ et $r$ est le rayon des disques du modèle booléen.

[6Idem note [2].

Comparte este artículo

Para citar este artículo:

Julie Delon, Alasdair Newson — «Un modèle aléatoire pour le grain photographique» — Images des Mathématiques, CNRS, 2020

Comentario sobre el artículo

Dejar un comentario

Foro sólo para inscritos

Para participar en este foro, debe registrarte previamente. Gracias por indicar a continuación el identificador personal que se le ha suministrado. Si no está inscrito/a, debe inscribirse.

Conexióninscribirse¿contraseña olvidada?

La traducción del sitio del francés al castellano se realiza gracias al apoyo de diversas instituciones de matemáticas de América Latina.