1. Interprétation et simulation d'une image CFA

<< | Liste des exercices | Dématriçage par interpolation bilinéaire >>

Interprétation d'une image CFA

L'image acquise par une caméra numérique couleur mono-CCD est dite Image CFA. En chaque pixel de cette image, un seul niveau de composante couleur est disponible (soit $R$, soit $G$, soit $B$), selon la disposition du CFA (matrice de filtres monochromatiques) placée en amont du capteur. Le CFA le plus répandu est celui de Bayer, qui comporte deux fois plus de filtres $G$ que de filtres $R$ et $B$. C'est celui que nous utilisons dans ce TP.

Voici une image couleur d'une scène et une image CFA correspondante.

  1. Quelle est la disposition du filtre CFA qui a été utilisée pour générer l'image CFA ci-dessus (donner les 3x3 premiers filtres, de coordonnées $(x,y) \in \{0,1,2\}^2$) ?

Simulation d'une image CFA à partir d'une image couleur

Afin d'évaluer la qualité du dématriçage, on compare souvent l'image estimée à l'image couleur de référence. Pour cela,

  • à partir de l'image couleur de référence, on simule l'image CFA en échantillonnant les composante selon une certaine disposition de CFA ;
  • on réalise le dématriçage de l'image CFA pour obtenir une image estimée ;
  • on compare l'image estimée à l'image de référence en utilisant un critère de qualité.

Nous allons écrire un plugin ImageJ compute_cfa.java permettant de simuler une image CFA à partir d'une image couleur, pour un filtre Bayer choisi par l'utilisateur parmi toutes les dispositions possibles. En voici la trame :

import ij.*;
import ij.plugin.filter.*;
import ij.process.*;
import ij.gui.*;

public class compute_cfa implements PlugInFilter {

    ImagePlus imp;	// Fenêtre contenant l'image de référence
    int width;		// Largeur de la fenêtre
    int height;		// Hauteur de la fenêtre

    public int setup(String arg, ImagePlus imp) {/* à compléter*/}
    public void run(ImageProcessor ip) {/* cf. ci-dessous*/}
    ImageProcessor cfa(int row_order) {/* cf. ci-dessous*/}	//Génère l'image CFA
}

La définition de l'interface se fait dans la méthode run :

public void run(ImageProcessor ip) {

    // Lecture des dimensions de la fenêtre
    width = imp.getWidth();
    height = imp.getHeight();

    // Dispositions possibles pour le CFA
    String[] orders = {"R-G-R", "B-G-B", "G-R-G", "G-B-G"};

    // Définition de l'interface
    GenericDialog dia = new GenericDialog("Génération de l'image CFA...", IJ.getInstance());
    dia.addChoice("Début de première ligne :", orders, orders[2]);
    dia.showDialog();

    // Lecture de la réponse de l'utilisateur
    if (dia.wasCanceled()) return;
    int order = dia.getNextChoiceIndex();

    // Génération de l'image CFA
    /* à compléter */
}

La méthode cfa se charge de générer l'image CFA en fonction de l'ordre des filtres sur la première ligne de l'image. Par exemple, la notation G-R-G se lit $G_{0,0}$, $R_{1,0}$ et $G_{2,0}$ (ne pas confondre avec la notation {GRG} utilisée en cours pour désigner une disposition interne à l'image). Pour cette disposition G-R-G par exemple, la méthode cfa s'écrit :

ImageProcessor cfa(int row_order) {

    // Image couleur de référence et ses dimensions
    ImageProcessor ip = imp.getProcessor();
    width = imp.getWidth();
    height = imp.getHeight();

    int pixel_value = 0;	// Valeur du pixel source
    ImageProcessor cfa_ip = new ByteProcessor(width,height);	// Image CFA générée

    // Échantillons G
    for (int y=0; y<height; y+=2) {
        for (int x=0; x<width; x+=2) {
            pixel_value = ip.getPixel(x,y);
            int green = (int)(pixel_value & 0x00ff00)>>8;
            cfa_ip.putPixel(x,y,green);
        }
    }
    for (int y=1; y<height; y+=2) {
        for (int x=1; x<width; x+=2) {
            pixel_value = ip.getPixel(x,y);
            int green = (int)(pixel_value & 0x00ff00)>>8;
            cfa_ip.putPixel(x,y,green);
        }
    }
    // Échantillons R
    for (int y=0; y<height; y+=2) {
        for (int x=1; x<width; x+=2) {
            pixel_value = ip.getPixel(x,y);
            int red = (int)(pixel_value & 0xff0000)>>16;
            cfa_ip.putPixel(x,y,red);
        }
    }
    // Échantillons B
    for (int y=1; y<height; y+=2) {
        for (int x=0; x<width; x+=2) {
            pixel_value = ip.getPixel(x,y);
            int blue = (int)(pixel_value & 0x0000ff);
            cfa_ip.putPixel(x,y,blue);
        }
    }

    return cfa_ip;
}
  1. Compléter la méthode run pour générer puis afficher l'image CFA, en ne considérant que la disposition G-R-G dans un premier temps. Dans le compte-rendu, décrire les lignes ajoutées et présenter le résultat obtenu en le justifiant.

Exercice optionnel

  1. Compléter la méthode cfa pour qu'elle prenne en compte les quatre dispositions possibles de CFA, et adapter la méthode run en conséquence.