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.
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;