Décodage de la matrice de BAYER

Les images RAW sont une empreinte du capteur de l'appareil photo. Chaque pixel est une cellule captant une des couleurs rouge, verte ou bleue. Sur les lignes paires, on a alternativement, une cellule Verte et une cellule Rouge. Sur les lignes impaires, une bleue et une verte.

Matrice de Bayer

Le principe du décodage est de transformer un tableau de valeurs 16 bits en trois tableaux pour les trois différentes couleurs. Au passage, vous pouvez remarquer la soustraction des offsets et darks et la division par le flat.

Dans le code suivant, seul les lignes concernant le dematricage sont presentes :

 // Decodage matrice de bayer 
  for (y=0;y<im.height;y++)
    {
      for (x=0;x<im.width;x++)
	{
	  cas=x%2 + (y % 2)*10;
	  // si x pair et y pair 0
	  // si x pair et y impair 10
	  // si x impair et y pair 1
	  // si x impair et y impair 11
 
	  count = y*im.width+ x;
	  v = im.buffer[count*2]+256*im.buffer[count*2+1];
 
	  //offset et dark
	  off = offset->buffer[count*2]+256*offset->buffer[count*2+1];
	  dar = dark->buffer[count*2]+256*dark->buffer[count*2+1];
	  fla = flat->buffer[count*2]+256*flat->buffer[count*2+1];
	  v = (int)((v-off-dar)*flatMoy/fla);
 
	  if (v<0) v=0;
 
	  if (cas ==0) 
	    {
	      R[count]=v;
	    }
 
	  if ((cas ==10)||(cas ==1))
	    {
	      G[count]=v;
	      // On calcul la moyenne au passage pour le vert
	      moyenne += v;
	      m2+= v*v;
	      mMax=max(mMax,v);
	    }
	  if (cas ==11) B[count]=v;
 
	}
    }

Dans une deuxième passe, nous allons compléter les trous par la moyenne des valeurs connues. Cela est fait pour les trois couleurs.

    for (x=0;x<im.width;x++)
      {
	cas=x%2 + (y % 2)*10;
	count = y*im.width+ x;
	// si x pair et y pair 0
	// si x pair et y impair 10
	// si x impair et y pair 1
	// si x impair et y impair 11
	if (cas==0)
	  {
	    // Calcul du vert
	    nG=0;
	    vG=0;
	    if (x>0)             { vG += G[y*im.width+ x-1]; nG++;}
	    if (x<(im.width-1))  { vG += G[y*im.width+ x+1]; nG++;}
	    if (y>0)             { vG += G[(y-1)*im.width+ x]; nG++;}
	    if (y<(im.height-1)) { vG += G[(y+1)*im.width+x]; nG++;}
	    G[count]=vG/nG;
	    // Calcul du bleu
	    nB=0;
	    vB=0;
 
	    if ((x>0) &&( y>0)) {  vB += B[(y-1)*im.width+x-1]; nB++;}
	    if ((x<(im.width-1))&& (y>0))  { vB += B[(y-1)*im.width+ x+1]; nB++;}
	    if ((x>0)  && ( y<(im.height-1))) { vB += B[(y+1)*im.width+ x-1]; nB++;}
	    if ((x<(im.width-1))&& (y<(im.height-1)))  { vB += B[(y+1)*im.width+ x+1]; nB++;}
	    B[count]=vB/nB;
	  }
 
	if (cas==1)
	  {
	    // Calcul du rouge
	    nR=0;
	    vR=0;
	    if (x>0)            { vR += R[y*im.width+ x-1]; nR++;}
	    if (x<(im.width-1)) { vR += R[y*im.width+ x+1]; nR++;}
	    R[count]=vR/nR;
	    // Calcul du bleu
	    nB=0;
	    vB=0;
	    if (y>0)              { vB += B[(y-1)*im.width+ x]; nB++;}
	    if (y<(im.height-1))  { vB += B[(y+1)*im.width+ x]; nB++;}
	    B[count]=vB/nB;
	  }
	if (cas==10)
	  {
	    // Calcul du bleu
	    nB=0;
	    vB=0;
	    if (x>0)                { vB += B[y*im.width+ x-1]; nB++;}
	    if (x<(im.width-1))     { vB += B[y*im.width+ x+1]; nB++;}
	    B[count]=vB/nB;
	    // Calcul du rouge
	    nR=0;
	    vR=0;
	    if (y>0)              { vR += R[(y-1)*im.width+ x]; nR++;}
	    if (y<(im.height-1))  { vR += R[(y+1)*im.width+ x]; nR++;}
	    R[count]=vR/nR;
	  }
	if (cas==11)
	  {
	    // Calcul du rouge
	    nR=0;
	    vR=0;
 
	    if ((x>0)&&(y>0))             { vR += R[(y-1)*im.width+ x-1]; nR++;}
	    if ((x>0)&&(y<(im.height-1))) { vR += R[(y+1)*im.width+ x-1]; nR++;}
	    if ((x<(im.width-1))&&(y>0))             { vR += R[(y-1)*im.width+ x+1]; nR++;}
	    if ((x<(im.width-1)) &&(y<(im.height-1))) { vR += R[(y+1)*im.width+ x+1]; nR++;}
	    R[count]=vR/nR;
	    // Calcul du vert
	    nG=0;
	    vG=0;
	    if (x>0)                 { vG += G[y*im.width+ x-1]; nG++;}
	    if (x<(im.width-1))      { vG += G[y*im.width+ x+1]; nG++;}
	    if (y>0)                 { vG += G[(y-1)*im.width+ x]; nG++;}
	    if (y<(im.height-1))     { vG += G[(y+1)*im.width+x]; nG++;}
	    G[count]=vG/nG;
 
	    }
	vR=R[count];
	vG=G[count];
	vB=B[count];
	gen.buffer[count*6+1]=vR/256;
	gen.buffer[count*6]  =vR-gen.buffer[count*6+1]*256;
	gen.buffer[count*6+3]=vG/256;
	gen.buffer[count*6+2]=vG-gen.buffer[count*6+3]*256;
	gen.buffer[count*6+5]=vB/256;
	gen.buffer[count*6+4]=vB-gen.buffer[count*6+5]*256;
 
apa/theorie/matrice_de_bayer.txt · Dernière modification: 2007/08/17 14:44 par davidl
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki