bugfixes and improvements to AMaZE and CA-autocorrection.
This commit is contained in:
parent
e82026f9f6
commit
184308cf35
@ -5,7 +5,7 @@
|
|||||||
// copyright (c) 2008-2010 Emil Martinec <ejmartin@uchicago.edu>
|
// copyright (c) 2008-2010 Emil Martinec <ejmartin@uchicago.edu>
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// code dated: June 2, 2010
|
// code dated: June 14, 2010
|
||||||
//
|
//
|
||||||
// CA_correct_RT.cc is free software: you can redistribute it and/or modify
|
// CA_correct_RT.cc is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
@ -100,10 +100,8 @@ int RawImageSource::LinEqSolve(int c, int dir, int nDim, float* pfMatr, float* p
|
|||||||
void RawImageSource::CA_correct_RT() {
|
void RawImageSource::CA_correct_RT() {
|
||||||
|
|
||||||
#define TS 256 // Tile size
|
#define TS 256 // Tile size
|
||||||
//#define polyord 4 // max order of fit monomial
|
//#define border 8
|
||||||
//#define numpar 16 // number of fit parameters = SQR(polyord)
|
//#define border2 16
|
||||||
#define border 8
|
|
||||||
#define border2 16
|
|
||||||
|
|
||||||
#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} }
|
#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} }
|
||||||
#define SQR(x) ((x)*(x))
|
#define SQR(x) ((x)*(x))
|
||||||
@ -113,18 +111,20 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
float (*Gtmp);
|
float (*Gtmp);
|
||||||
Gtmp = (float (*)) calloc ((height)*(width), sizeof *Gtmp);
|
Gtmp = (float (*)) calloc ((height)*(width), sizeof *Gtmp);
|
||||||
|
|
||||||
int polyord=2, numpar=4, numblox[3]={0,0,0};
|
static const int border=8;
|
||||||
|
static const int border2=16;
|
||||||
|
int polyord=4, numpar=16, numblox[3]={0,0,0};
|
||||||
|
|
||||||
//static const int border=8;
|
|
||||||
int rrmin, rrmax, ccmin, ccmax;
|
int rrmin, rrmax, ccmin, ccmax;
|
||||||
int top, bottom, left, right, row, col;
|
int top, bottom, left, right, row, col;
|
||||||
int rr, cc, rr1, cc1, c, indx, indx1, i, j, k, m, n, dir;
|
int rr, cc, rr1, cc1, c, indx, indx1, i, j, k, m, n, dir;
|
||||||
|
int areawt[2][3];
|
||||||
int GRBdir[2][3], offset[2][3];
|
int GRBdir[2][3], offset[2][3];
|
||||||
int shifthfloor[3], shiftvfloor[3], shifthceil[3], shiftvceil[3];
|
int shifthfloor[3], shiftvfloor[3], shifthceil[3], shiftvceil[3];
|
||||||
int vblsz, hblsz, vblock, hblock;
|
int vblsz, hblsz, vblock, hblock, vz1, hz1;
|
||||||
//int verbose=1;
|
//int verbose=1;
|
||||||
int res;
|
int res;
|
||||||
int v1=TS, v2=2*TS, v3=3*TS, v4=4*TS;//, p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3;
|
static const int v1=TS, v2=2*TS, v3=3*TS, v4=4*TS;//, p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3;
|
||||||
|
|
||||||
float eps=1e-10; //tolerance to avoid dividing by zero
|
float eps=1e-10; //tolerance to avoid dividing by zero
|
||||||
|
|
||||||
@ -132,13 +132,13 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
float coeff[2][3][3], CAshift[2][3];
|
float coeff[2][3][3], CAshift[2][3];
|
||||||
float polymat[3][2][1296], shiftmat[3][2][36], fitparams[3][2][36];
|
float polymat[3][2][1296], shiftmat[3][2][36], fitparams[3][2][36];
|
||||||
float shifthfrac[3], shiftvfrac[3], temp, p[9];
|
float shifthfrac[3], shiftvfrac[3], temp, p[9];
|
||||||
float gdiff, deltgrb, denom, Ginthfloor, Ginthceil, Gint, gradwt;
|
float gdiff, deltgrb, denom, Ginthfloor, Ginthceil, Gint, RBint, gradwt;
|
||||||
float grbdiffinthfloor, grbdiffinthceil, grbdiffint, grbdiffold;
|
float grbdiffinthfloor, grbdiffinthceil, grbdiffint, grbdiffold;
|
||||||
float blockave[2][3]={{0,0,0},{0,0,0}}, blocksqave[2][3]={{0,0,0},{0,0,0}}, blockdenom[2][3]={{0,0,0},{0,0,0}}, blockvar[2][3];
|
float blockave[2][3]={{0,0,0},{0,0,0}}, blocksqave[2][3]={{0,0,0},{0,0,0}}, blockdenom[2][3]={{0,0,0},{0,0,0}}, blockvar[2][3];
|
||||||
|
float glpfh, glpfv, ghpfh, ghpfv;
|
||||||
|
|
||||||
|
static const float gaussg[5] = {0.171582, 0.15839, 0.124594, 0.083518, 0.0477063};//sig=2.5
|
||||||
static const float gaussg[5] = {0.171582, 0.15839, 0.124594, 0.083518, 0.0477063};
|
static const float gaussrb[3] = {0.332406, 0.241376, 0.0924212};//sig=1.25
|
||||||
static const float gaussrb[3] = {0.332406, 0.241376, 0.0924212};
|
|
||||||
|
|
||||||
//char *buffer1; // vblsz*hblsz*3*2
|
//char *buffer1; // vblsz*hblsz*3*2
|
||||||
//float (*blockshifts)[3][2]; // vblsz*hblsz*3*2
|
//float (*blockshifts)[3][2]; // vblsz*hblsz*3*2
|
||||||
@ -150,10 +150,10 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
float (*rgb)[3]; // TS*TS*12
|
float (*rgb)[3]; // TS*TS*12
|
||||||
float (*grbdiff); // TS*TS*4
|
float (*grbdiff); // TS*TS*4
|
||||||
float (*gshift); // TS*TS*4
|
float (*gshift); // TS*TS*4
|
||||||
float (*ghpfh); // TS*TS*4
|
|
||||||
float (*ghpfv); // TS*TS*4
|
|
||||||
float (*rbhpfh); // TS*TS*4
|
float (*rbhpfh); // TS*TS*4
|
||||||
float (*rbhpfv); // TS*TS*4
|
float (*rbhpfv); // TS*TS*4
|
||||||
|
float (*rblpfh); // TS*TS*4
|
||||||
|
float (*rblpfv); // TS*TS*4
|
||||||
|
|
||||||
|
|
||||||
/* assign working space; this would not be necessary
|
/* assign working space; this would not be necessary
|
||||||
@ -166,14 +166,16 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
rgb = (float (*)[3]) buffer;
|
rgb = (float (*)[3]) buffer;
|
||||||
grbdiff = (float (*)) (buffer + 12*TS*TS);
|
grbdiff = (float (*)) (buffer + 12*TS*TS);
|
||||||
gshift = (float (*)) (buffer + 16*TS*TS);
|
gshift = (float (*)) (buffer + 16*TS*TS);
|
||||||
ghpfh = (float (*)) (buffer + 20*TS*TS);
|
rbhpfh = (float (*)) (buffer + 20*TS*TS);
|
||||||
ghpfv = (float (*)) (buffer + 24*TS*TS);
|
rbhpfv = (float (*)) (buffer + 24*TS*TS);
|
||||||
rbhpfh = (float (*)) (buffer + 28*TS*TS);
|
rblpfh = (float (*)) (buffer + 28*TS*TS);
|
||||||
rbhpfv = (float (*)) (buffer + 32*TS*TS);
|
rblpfv = (float (*)) (buffer + 32*TS*TS);
|
||||||
|
|
||||||
|
if((height+border2)%(TS-border2)==0) vz1=1; else vz1=0;
|
||||||
|
if((width+border2)%(TS-border2)==0) hz1=1; else hz1=0;
|
||||||
|
|
||||||
vblsz=ceil((float)(height+border2)/(TS-border2))+2;
|
vblsz=ceil((float)(height+border2)/(TS-border2)+2+vz1);
|
||||||
hblsz=ceil((float)(width+border2)/(TS-border2))+2;
|
hblsz=ceil((float)(width+border2)/(TS-border2)+2+hz1);
|
||||||
|
|
||||||
/*buffer1 = (char *) malloc(4*vblsz*hblsz*3*2);
|
/*buffer1 = (char *) malloc(4*vblsz*hblsz*3*2);
|
||||||
merror(buffer1,"CA_correct()");
|
merror(buffer1,"CA_correct()");
|
||||||
@ -208,9 +210,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
indx=row*width+col;
|
indx=row*width+col;
|
||||||
indx1=rr*TS+cc;
|
indx1=rr*TS+cc;
|
||||||
rgb[indx1][c] = (ri->data[row][col])/65535.0f;
|
rgb[indx1][c] = (ri->data[row][col])/65535.0f;
|
||||||
|
//rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
blockwt[vblock*hblsz+hblock]=0;
|
|
||||||
//blockwt[vblock*hblsz+hblock]=1;
|
|
||||||
|
|
||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
//fill borders
|
//fill borders
|
||||||
@ -226,6 +227,7 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=ccmin; cc<ccmax; cc++) {
|
for (cc=ccmin; cc<ccmax; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][left+cc])/65535.0f;
|
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][left+cc])/65535.0f;
|
||||||
|
//rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+left+cc][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ccmin>0) {
|
if (ccmin>0) {
|
||||||
@ -240,6 +242,7 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[rr*TS+ccmax+cc][c] = (ri->data[(top+rr)][(width-cc-2)])/65535.0f;
|
rgb[rr*TS+ccmax+cc][c] = (ri->data[(top+rr)][(width-cc-2)])/65535.0f;
|
||||||
|
//rgb[rr*TS+ccmax+cc][c] = (image[(top+rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +252,7 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rr)*TS+cc][c] = (ri->data[border2-rr][border2-cc])/65535.0f;
|
rgb[(rr)*TS+cc][c] = (ri->data[border2-rr][border2-cc])/65535.0f;
|
||||||
|
//rgb[(rr)*TS+cc][c] = (rgb[(border2-rr)*TS+(border2-cc)][c]);//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrmax<rr1 && ccmax<cc1) {
|
if (rrmax<rr1 && ccmax<cc1) {
|
||||||
@ -256,6 +260,7 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+ccmax+cc][c] = (ri->data[(height-rr-2)][(width-cc-2)])/65535.0f;
|
rgb[(rrmax+rr)*TS+ccmax+cc][c] = (ri->data[(height-rr-2)][(width-cc-2)])/65535.0f;
|
||||||
|
//rgb[(rrmax+rr)*TS+ccmax+cc][c] = (image[(height-rr-2)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrmin>0 && ccmax<cc1) {
|
if (rrmin>0 && ccmax<cc1) {
|
||||||
@ -263,6 +268,7 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rr)*TS+ccmax+cc][c] = (ri->data[(border2-rr)][(width-cc-2)])/65535.0f;
|
rgb[(rr)*TS+ccmax+cc][c] = (ri->data[(border2-rr)][(width-cc-2)])/65535.0f;
|
||||||
|
//rgb[(rr)*TS+ccmax+cc][c] = (image[(border2-rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrmax<rr1 && ccmin>0) {
|
if (rrmax<rr1 && ccmin>0) {
|
||||||
@ -270,16 +276,19 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][(border2-cc)])/65535.0f;
|
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][(border2-cc)])/65535.0f;
|
||||||
|
//rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+(border2-cc)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//end of border fill
|
//end of border fill
|
||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
for (j=0; j<2; j++)
|
for (j=0; j<2; j++)
|
||||||
for (k=0; k<3; k++)
|
for (k=0; k<3; k++)
|
||||||
for (c=0; c<3; c+=2) coeff[j][k][c]=0;
|
for (c=0; c<3; c+=2) {
|
||||||
|
coeff[j][k][c]=0;
|
||||||
|
}
|
||||||
//end of initialization
|
//end of initialization
|
||||||
|
|
||||||
|
|
||||||
@ -295,7 +304,6 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
wtl=1/SQR(eps+fabs(rgb[(rr)*TS+cc+1][1]-rgb[(rr)*TS+cc-1][1])+fabs(rgb[(rr)*TS+cc][c]-rgb[(rr)*TS+cc-2][c])+fabs(rgb[(rr)*TS+cc-1][1]-rgb[(rr)*TS+cc-3][1]));
|
wtl=1/SQR(eps+fabs(rgb[(rr)*TS+cc+1][1]-rgb[(rr)*TS+cc-1][1])+fabs(rgb[(rr)*TS+cc][c]-rgb[(rr)*TS+cc-2][c])+fabs(rgb[(rr)*TS+cc-1][1]-rgb[(rr)*TS+cc-3][1]));
|
||||||
wtr=1/SQR(eps+fabs(rgb[(rr)*TS+cc-1][1]-rgb[(rr)*TS+cc+1][1])+fabs(rgb[(rr)*TS+cc][c]-rgb[(rr)*TS+cc+2][c])+fabs(rgb[(rr)*TS+cc+1][1]-rgb[(rr)*TS+cc+3][1]));
|
wtr=1/SQR(eps+fabs(rgb[(rr)*TS+cc-1][1]-rgb[(rr)*TS+cc+1][1])+fabs(rgb[(rr)*TS+cc][c]-rgb[(rr)*TS+cc+2][c])+fabs(rgb[(rr)*TS+cc+1][1]-rgb[(rr)*TS+cc+3][1]));
|
||||||
|
|
||||||
|
|
||||||
//store in rgb array the interpolated G value at R/B grid points using directional weighted average
|
//store in rgb array the interpolated G value at R/B grid points using directional weighted average
|
||||||
rgb[indx][1]=(wtu*rgb[indx-v1][1]+wtd*rgb[indx+v1][1]+wtl*rgb[indx-1][1]+wtr*rgb[indx+1][1])/(wtu+wtd+wtl+wtr);
|
rgb[indx][1]=(wtu*rgb[indx-v1][1]+wtd*rgb[indx+v1][1]+wtl*rgb[indx-1][1]+wtr*rgb[indx+1][1])/(wtu+wtd+wtl+wtr);
|
||||||
}
|
}
|
||||||
@ -303,45 +311,65 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
Gtmp[row*width + col] = rgb[indx][1];
|
Gtmp[row*width + col] = rgb[indx][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
//color difference curvatures
|
|
||||||
for (rr=4; rr < rr1-4; rr++)
|
for (rr=4; rr < rr1-4; rr++)
|
||||||
for (cc=4+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-4; cc+=2, indx+=2) {
|
for (cc=4+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-4; cc+=2, indx+=2) {
|
||||||
|
|
||||||
ghpfv[indx] = 2*rgb[indx][1]-rgb[indx+v2][1]-rgb[indx-v2][1];
|
/*ghpfv = 2*rgb[indx][1]-rgb[indx+v2][1]-rgb[indx-v2][1];
|
||||||
ghpfh[indx] = 2*rgb[indx][1]-rgb[indx+2][1]-rgb[indx-2][1];
|
ghpfh = 2*rgb[indx][1]-rgb[indx+2][1]-rgb[indx-2][1];
|
||||||
rbhpfv[indx] = ghpfv[indx]-(2*rgb[indx][c]-rgb[indx+v2][c]-rgb[indx-v2][c]);
|
rbhpfv[indx] = ghpfv-(2*rgb[indx][c]-rgb[indx+v2][c]-rgb[indx-v2][c]);
|
||||||
rbhpfh[indx] = ghpfh[indx]-(2*rgb[indx][c]-rgb[indx+2][c]-rgb[indx-2][c]);
|
rbhpfh[indx] = ghpfh-(2*rgb[indx][c]-rgb[indx+2][c]-rgb[indx-2][c]);*/
|
||||||
|
|
||||||
|
//ghpfv = fabs(fabs(rgb[indx][1]-rgb[indx+v4][1])+fabs(rgb[indx][1]-rgb[indx-v4][1]) - \
|
||||||
|
fabs(rgb[indx+v4][1]-rgb[indx-v4][1]));
|
||||||
|
//ghpfh = fabs(fabs(rgb[indx][1]-rgb[indx+4][1])+fabs(rgb[indx][1]-rgb[indx-4][1]) - \
|
||||||
|
fabs(rgb[indx+4][1]-rgb[indx-4][1]));
|
||||||
|
rbhpfv[indx] = fabs(fabs(rgb[indx][1]-rgb[indx][1]-(rgb[indx+v4][c]+rgb[indx+v4][c]))+ \
|
||||||
|
fabs(rgb[indx][1]-rgb[indx-v4][1]-(rgb[indx][c]-rgb[indx-v4][c])) - \
|
||||||
|
fabs(rgb[indx+v4][1]-rgb[indx-v4][1]-(rgb[indx+v4][c]-rgb[indx-v4][c])));
|
||||||
|
rbhpfh[indx] = fabs(fabs(rgb[indx][1]-rgb[indx+4][1]-(rgb[indx][c]-rgb[indx+4][c]))+ \
|
||||||
|
fabs(rgb[indx][1]-rgb[indx-4][1]-(rgb[indx][c]-rgb[indx-4][c])) - \
|
||||||
|
fabs(rgb[indx+4][1]-rgb[indx-4][1]-(rgb[indx+4][c]-rgb[indx-4][c])));
|
||||||
|
|
||||||
|
glpfv = 0.25*(2*rgb[indx][1]+rgb[indx+v2][1]+rgb[indx-v2][1]);
|
||||||
|
glpfh = 0.25*(2*rgb[indx][1]+rgb[indx+2][1]+rgb[indx-2][1]);
|
||||||
|
rblpfv[indx] = eps+fabs(glpfv - 0.25*(2*rgb[indx][c]+rgb[indx+v2][c]+rgb[indx-v2][c]));
|
||||||
|
rblpfh[indx] = eps+fabs(glpfh - 0.25*(2*rgb[indx][c]+rgb[indx+2][c]+rgb[indx-2][c]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// along line segments, find the point along each segment that minimizes the color variance
|
// along line segments, find the point along each segment that minimizes the color variance
|
||||||
// averaged over the tile; evaluate for up/down and left/right away from R/B grid point
|
// averaged over the tile; evaluate for up/down and left/right away from R/B grid point
|
||||||
for (rr=4; rr < rr1-4; rr++)
|
for (rr=8; rr < rr1-8; rr++)
|
||||||
for (cc=4+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-4; cc+=2, indx+=2) {
|
for (cc=8+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-8; cc+=2, indx+=2) {
|
||||||
|
|
||||||
|
areawt[0][c]=areawt[1][c]=0;
|
||||||
|
|
||||||
//in linear interpolation, color differences are a quadratic function of interpolation position;
|
//in linear interpolation, color differences are a quadratic function of interpolation position;
|
||||||
//solve for the interpolation position that minimizes color difference variance over the tile
|
//solve for the interpolation position that minimizes color difference variance over the tile
|
||||||
|
|
||||||
//vertical
|
//vertical
|
||||||
gdiff=0.3125*(rgb[indx+TS][1]-rgb[indx-TS][1])+0.09375*(rgb[indx+TS+1][1]-rgb[indx-TS+1][1]+rgb[indx+TS-1][1]-rgb[indx-TS-1][1]);
|
gdiff=0.3125*(rgb[indx+TS][1]-rgb[indx-TS][1])+0.09375*(rgb[indx+TS+1][1]-rgb[indx-TS+1][1]+rgb[indx+TS-1][1]-rgb[indx-TS-1][1]);
|
||||||
gradwt=fabs(0.25*rbhpfv[indx]+0.125*(rbhpfv[indx+2]+rbhpfv[indx-2]) );
|
|
||||||
|
|
||||||
deltgrb=(rgb[indx][c]-rgb[indx][1]);
|
deltgrb=(rgb[indx][c]-rgb[indx][1]);
|
||||||
|
|
||||||
|
gradwt=fabs(0.25*rbhpfv[indx]+0.125*(rbhpfv[indx+2]+rbhpfv[indx-2]) )/(eps+MAX(rblpfv[indx-v2],rblpfv[indx+v2]));
|
||||||
|
|
||||||
coeff[0][0][c] += gradwt*deltgrb*deltgrb;
|
coeff[0][0][c] += gradwt*deltgrb*deltgrb;
|
||||||
coeff[0][1][c] += gradwt*gdiff*deltgrb;
|
coeff[0][1][c] += gradwt*gdiff*deltgrb;
|
||||||
coeff[0][2][c] += gradwt*gdiff*gdiff;
|
coeff[0][2][c] += gradwt*gdiff*gdiff;
|
||||||
|
areawt[0][c]+=1;
|
||||||
|
|
||||||
|
//}
|
||||||
//horizontal
|
//horizontal
|
||||||
gdiff=0.3125*(rgb[indx+1][1]-rgb[indx-1][1])+0.09375*(rgb[indx+1+TS][1]-rgb[indx-1+TS][1]+rgb[indx+1-TS][1]-rgb[indx-1-TS][1]);
|
gdiff=0.3125*(rgb[indx+1][1]-rgb[indx-1][1])+0.09375*(rgb[indx+1+TS][1]-rgb[indx-1+TS][1]+rgb[indx+1-TS][1]-rgb[indx-1-TS][1]);
|
||||||
gradwt=fabs(0.25*rbhpfh[indx]+0.125*(rbhpfh[indx+v2]+rbhpfh[indx-v2]) );
|
|
||||||
|
|
||||||
deltgrb=(rgb[indx][c]-rgb[indx][1]);
|
deltgrb=(rgb[indx][c]-rgb[indx][1]);
|
||||||
|
|
||||||
|
gradwt=fabs(0.25*rbhpfh[indx]+0.125*(rbhpfh[indx+v2]+rbhpfh[indx-v2]) )/(eps+MAX(rblpfh[indx-2],rblpfh[indx+2]));
|
||||||
|
|
||||||
coeff[1][0][c] += gradwt*deltgrb*deltgrb;
|
coeff[1][0][c] += gradwt*deltgrb*deltgrb;
|
||||||
coeff[1][1][c] += gradwt*gdiff*deltgrb;
|
coeff[1][1][c] += gradwt*gdiff*deltgrb;
|
||||||
coeff[1][2][c] += gradwt*gdiff*gdiff;
|
coeff[1][2][c] += gradwt*gdiff*gdiff;
|
||||||
|
areawt[1][c]+=1;
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
// In Mathematica,
|
// In Mathematica,
|
||||||
// f[x_]=Expand[Total[Flatten[
|
// f[x_]=Expand[Total[Flatten[
|
||||||
@ -351,12 +379,21 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (c=0; c<3; c+=2){
|
for (c=0; c<3; c+=2){
|
||||||
for (j=0; j<2; j++) {// vert/hor
|
for (j=0; j<2; j++) {// vert/hor
|
||||||
|
|
||||||
|
if (areawt[j][c]>0) {
|
||||||
CAshift[j][c]=coeff[j][1][c]/coeff[j][2][c];
|
CAshift[j][c]=coeff[j][1][c]/coeff[j][2][c];
|
||||||
blockwt[vblock*hblsz+hblock] = (float)(rr1-8)*(cc1-8)/4 * coeff[j][2][c]/(eps+coeff[j][0][c]) ;
|
blockwt[vblock*hblsz+hblock]= areawt[j][c];//*coeff[j][2][c]/(eps+coeff[j][0][c]) ;
|
||||||
|
} else {
|
||||||
|
CAshift[j][c]=17.0;
|
||||||
|
blockwt[vblock*hblsz+hblock]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//CAshift[j][c]=coeff[j][1][c]/coeff[j][2][c];
|
||||||
|
//blockwt[vblock*hblsz+hblock] = (float)(rr1-8)*(cc1-8)/4 * coeff[j][2][c]/(eps+coeff[j][0][c]) ;
|
||||||
|
|
||||||
//data structure = CAshift[vert/hor][color]
|
//data structure = CAshift[vert/hor][color]
|
||||||
//j=0=vert, 1=hor
|
//j=0=vert, 1=hor
|
||||||
|
|
||||||
|
|
||||||
if ((CAshift[j][c])<0) {
|
if ((CAshift[j][c])<0) {
|
||||||
GRBdir[j][c]=-1;
|
GRBdir[j][c]=-1;
|
||||||
} else {
|
} else {
|
||||||
@ -370,7 +407,6 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
blocksqave[j][c] += SQR(CAshift[j][c]);
|
blocksqave[j][c] += SQR(CAshift[j][c]);
|
||||||
blockdenom[j][c] += 1;
|
blockdenom[j][c] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}//vert/hor
|
}//vert/hor
|
||||||
}//color
|
}//color
|
||||||
|
|
||||||
@ -380,7 +416,6 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
that minimize color difference variances;
|
that minimize color difference variances;
|
||||||
This is the approximate _optical_ location of the R/B pixels */
|
This is the approximate _optical_ location of the R/B pixels */
|
||||||
|
|
||||||
|
|
||||||
for (c=0; c<3; c+=2) {
|
for (c=0; c<3; c+=2) {
|
||||||
//evaluate the shifts to the location that minimizes CA within the tile
|
//evaluate the shifts to the location that minimizes CA within the tile
|
||||||
blockshifts[(vblock)*hblsz+hblock][c][0]=(CAshift[0][c]); //vert CA shift for R/B
|
blockshifts[(vblock)*hblsz+hblock][c][0]=(CAshift[0][c]); //vert CA shift for R/B
|
||||||
@ -388,13 +423,19 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
//data structure: blockshifts[blocknum][R/B][v/h]
|
//data structure: blockshifts[blocknum][R/B][v/h]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//end of diagnostic pass
|
||||||
|
|
||||||
for (j=0; j<2; j++)
|
for (j=0; j<2; j++)
|
||||||
for (c=0; c<3; c+=2) {
|
for (c=0; c<3; c+=2) {
|
||||||
|
if (blockdenom[j][c]) {
|
||||||
blockvar[j][c] = blocksqave[j][c]/blockdenom[j][c]-SQR(blockave[j][c]/blockdenom[j][c]);
|
blockvar[j][c] = blocksqave[j][c]/blockdenom[j][c]-SQR(blockave[j][c]/blockdenom[j][c]);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//end of diagnostic pass
|
//if (verbose) fprintf (stderr,_("tile variances %f %f %f %f \n"),blockvar[0][0],blockvar[1][0],blockvar[0][2],blockvar[1][2] );
|
||||||
|
|
||||||
|
|
||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
@ -447,17 +488,21 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
if (p[4]<0) {GRBdir[dir][c]=-1;} else {GRBdir[dir][c]=1;}
|
if (p[4]<0) {GRBdir[dir][c]=-1;} else {GRBdir[dir][c]=1;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//if (verbose) fprintf (stderr,_("tile vshift hshift (%d %d %4f %4f)...\n"),vblock, hblock, blockshifts[(vblock)*hblsz+hblock][c][0], blockshifts[(vblock)*hblsz+hblock][c][1]);
|
||||||
|
|
||||||
|
|
||||||
//now prepare coefficient matrix
|
//now prepare coefficient matrix
|
||||||
if (SQR(blockshifts[(vblock)*hblsz+hblock][c][0])>4*blockvar[0][c] || SQR(blockshifts[(vblock)*hblsz+hblock][c][1])>4*blockvar[1][c]) continue;
|
if (SQR(blockshifts[(vblock)*hblsz+hblock][c][0])>4.0*blockvar[0][c] || SQR(blockshifts[(vblock)*hblsz+hblock][c][1])>4.0*blockvar[1][c]) continue;
|
||||||
numblox[c] += 1;
|
numblox[c] += 1;
|
||||||
for (dir=0; dir<2; dir++) {
|
for (dir=0; dir<2; dir++) {
|
||||||
for (i=0; i<polyord; i++)
|
for (i=0; i<polyord; i++)
|
||||||
for (j=0; j<polyord; j++) {
|
for (j=0; j<polyord; j++) {
|
||||||
for (m=0; m<polyord; m++)
|
for (m=0; m<polyord; m++)
|
||||||
for (n=0; n<polyord; n++) {
|
for (n=0; n<polyord; n++) {
|
||||||
polymat[c][dir][numpar*(polyord*i+j)+(polyord*m+n)] += (float)pow(vblock,i+m)*pow(hblock,j+n)*blockwt[vblock*hblsz+hblock];
|
polymat[c][dir][numpar*(polyord*i+j)+(polyord*m+n)] += (float)pow((float)vblock,i+m)*pow((float)hblock,j+n)*blockwt[vblock*hblsz+hblock];
|
||||||
}
|
}
|
||||||
shiftmat[c][dir][(polyord*i+j)] += (float)pow(vblock,i)*pow(hblock,j)*blockshifts[(vblock)*hblsz+hblock][c][dir]*blockwt[vblock*hblsz+hblock];
|
shiftmat[c][dir][(polyord*i+j)] += (float)pow((float)vblock,i)*pow((float)hblock,j)*blockshifts[(vblock)*hblsz+hblock][c][dir]*blockwt[vblock*hblsz+hblock];
|
||||||
}//monomials
|
}//monomials
|
||||||
}//dir
|
}//dir
|
||||||
|
|
||||||
@ -478,7 +523,6 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (dir=0; dir<2; dir++) {
|
for (dir=0; dir<2; dir++) {
|
||||||
res = LinEqSolve(c, dir, numpar, polymat[c][dir], shiftmat[c][dir], fitparams[c][dir]);
|
res = LinEqSolve(c, dir, numpar, polymat[c][dir], shiftmat[c][dir], fitparams[c][dir]);
|
||||||
if (res) {
|
if (res) {
|
||||||
//if (verbose) fprintf(stderr,_("problem fitting CA parameters for (c = %d dir = %d)\n"),c,dir);
|
|
||||||
for (i=0; i<numpar; i++) fitparams[c][dir][i]=0;
|
for (i=0; i<numpar; i++) fitparams[c][dir][i]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,6 +531,16 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
//end of initialization for CA correction pass
|
//end of initialization for CA correction pass
|
||||||
|
|
||||||
|
|
||||||
|
blockshifts[(vblock)*hblsz+hblock][0][0] = blockshifts[(vblock)*hblsz+hblock][0][1] = 0;
|
||||||
|
blockshifts[(vblock)*hblsz+hblock][2][0] = blockshifts[(vblock)*hblsz+hblock][2][1] = 0;
|
||||||
|
for (i=0; i<polyord; i++)
|
||||||
|
for (j=0; j<polyord; j++) {
|
||||||
|
blockshifts[(vblock)*hblsz+hblock][0][0] += (float)pow((float)vblock,i)*pow((float)hblock,j)*fitparams[0][0][polyord*i+j];
|
||||||
|
blockshifts[(vblock)*hblsz+hblock][0][1] += (float)pow((float)vblock,i)*pow((float)hblock,j)*fitparams[0][1][polyord*i+j];
|
||||||
|
blockshifts[(vblock)*hblsz+hblock][2][0] += (float)pow((float)vblock,i)*pow((float)hblock,j)*fitparams[2][0][polyord*i+j];
|
||||||
|
blockshifts[(vblock)*hblsz+hblock][2][1] += (float)pow((float)vblock,i)*pow((float)hblock,j)*fitparams[2][1][polyord*i+j];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Main algorithm: Tile loop
|
// Main algorithm: Tile loop
|
||||||
//#pragma omp parallel for shared(image,height,width) private(top,left,indx,indx1) schedule(dynamic)
|
//#pragma omp parallel for shared(image,height,width) private(top,left,indx,indx1) schedule(dynamic)
|
||||||
@ -513,6 +567,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
indx1=rr*TS+cc;
|
indx1=rr*TS+cc;
|
||||||
//rgb[indx1][c] = image[indx][c]/65535.0f;
|
//rgb[indx1][c] = image[indx][c]/65535.0f;
|
||||||
rgb[indx1][c] = (ri->data[row][col])/65535.0f;
|
rgb[indx1][c] = (ri->data[row][col])/65535.0f;
|
||||||
|
//rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation
|
||||||
|
|
||||||
if ((c&1)==0) rgb[indx1][1] = Gtmp[indx];
|
if ((c&1)==0) rgb[indx1][1] = Gtmp[indx];
|
||||||
}
|
}
|
||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
@ -530,6 +586,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=ccmin; cc<ccmax; cc++) {
|
for (cc=ccmin; cc<ccmax; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][left+cc])/65535.0f;
|
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][left+cc])/65535.0f;
|
||||||
|
//rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+left+cc][c])/65535.0f;//for dcraw implementation
|
||||||
|
|
||||||
rgb[(rrmax+rr)*TS+cc][1] = Gtmp[(height-rr-2)*width+left+cc];
|
rgb[(rrmax+rr)*TS+cc][1] = Gtmp[(height-rr-2)*width+left+cc];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -546,6 +604,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[rr*TS+ccmax+cc][c] = (ri->data[(top+rr)][(width-cc-2)])/65535.0f;
|
rgb[rr*TS+ccmax+cc][c] = (ri->data[(top+rr)][(width-cc-2)])/65535.0f;
|
||||||
|
//rgb[rr*TS+ccmax+cc][c] = (image[(top+rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
|
|
||||||
rgb[rr*TS+ccmax+cc][1] = Gtmp[(top+rr)*width+(width-cc-2)];
|
rgb[rr*TS+ccmax+cc][1] = Gtmp[(top+rr)*width+(width-cc-2)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -556,6 +616,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rr)*TS+cc][c] = (ri->data[border2-rr][border2-cc])/65535.0f;
|
rgb[(rr)*TS+cc][c] = (ri->data[border2-rr][border2-cc])/65535.0f;
|
||||||
|
//rgb[(rr)*TS+cc][c] = (rgb[(border2-rr)*TS+(border2-cc)][c]);//for dcraw implementation
|
||||||
|
|
||||||
rgb[(rr)*TS+cc][1] = Gtmp[(border2-rr)*width+border2-cc];
|
rgb[(rr)*TS+cc][1] = Gtmp[(border2-rr)*width+border2-cc];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,6 +626,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+ccmax+cc][c] = (ri->data[(height-rr-2)][(width-cc-2)])/65535.0f;
|
rgb[(rrmax+rr)*TS+ccmax+cc][c] = (ri->data[(height-rr-2)][(width-cc-2)])/65535.0f;
|
||||||
|
//rgb[(rrmax+rr)*TS+ccmax+cc][c] = (image[(height-rr-2)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
|
|
||||||
rgb[(rrmax+rr)*TS+ccmax+cc][1] = Gtmp[(height-rr-2)*width+(width-cc-2)];
|
rgb[(rrmax+rr)*TS+ccmax+cc][1] = Gtmp[(height-rr-2)*width+(width-cc-2)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -572,6 +636,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rr)*TS+ccmax+cc][c] = (ri->data[(border2-rr)][(width-cc-2)])/65535.0f;
|
rgb[(rr)*TS+ccmax+cc][c] = (ri->data[(border2-rr)][(width-cc-2)])/65535.0f;
|
||||||
|
//rgb[(rr)*TS+ccmax+cc][c] = (image[(border2-rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
|
|
||||||
rgb[(rr)*TS+ccmax+cc][1] = Gtmp[(border2-rr)*width+(width-cc-2)];
|
rgb[(rr)*TS+ccmax+cc][1] = Gtmp[(border2-rr)*width+(width-cc-2)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -580,6 +646,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
for (cc=0; cc<border; cc++) {
|
for (cc=0; cc<border; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][(border2-cc)])/65535.0f;
|
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][(border2-cc)])/65535.0f;
|
||||||
|
//rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+(border2-cc)][c])/65535.0f;//for dcraw implementation
|
||||||
|
|
||||||
rgb[(rrmax+rr)*TS+cc][1] = Gtmp[(height-rr-2)*width+(border2-cc)];
|
rgb[(rrmax+rr)*TS+cc][1] = Gtmp[(height-rr-2)*width+(border2-cc)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -588,16 +656,6 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
blockshifts[(vblock)*hblsz+hblock][0][0] = blockshifts[(vblock)*hblsz+hblock][0][1] = 0;
|
|
||||||
blockshifts[(vblock)*hblsz+hblock][2][0] = blockshifts[(vblock)*hblsz+hblock][2][1] = 0;
|
|
||||||
for (i=0; i<polyord; i++)
|
|
||||||
for (j=0; j<polyord; j++) {
|
|
||||||
blockshifts[(vblock)*hblsz+hblock][0][0] += (float)pow(vblock,i)*pow(hblock,j)*fitparams[0][0][polyord*i+j];
|
|
||||||
blockshifts[(vblock)*hblsz+hblock][0][1] += (float)pow(vblock,i)*pow(hblock,j)*fitparams[0][1][polyord*i+j];
|
|
||||||
blockshifts[(vblock)*hblsz+hblock][2][0] += (float)pow(vblock,i)*pow(hblock,j)*fitparams[2][0][polyord*i+j];
|
|
||||||
blockshifts[(vblock)*hblsz+hblock][2][1] += (float)pow(vblock,i)*pow(hblock,j)*fitparams[2][1][polyord*i+j];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (c=0; c<3; c+=2) {
|
for (c=0; c<3; c+=2) {
|
||||||
|
|
||||||
//some parameters for the bilinear interpolation
|
//some parameters for the bilinear interpolation
|
||||||
@ -623,45 +681,47 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
//determine R/B at grid points using color differences at shift point plus interpolated G value at grid point
|
//determine R/B at grid points using color differences at shift point plus interpolated G value at grid point
|
||||||
//but first we need to interpolate G-R/G-B to grid points...
|
//but first we need to interpolate G-R/G-B to grid points...
|
||||||
grbdiff[(rr)*TS+cc]=Gint-rgb[(rr)*TS+cc][c];
|
grbdiff[(rr)*TS+cc]=Gint-rgb[(rr)*TS+cc][c];
|
||||||
|
gshift[(rr)*TS+cc]=Gint;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (rr=8; rr < rr1-8; rr++)
|
for (rr=8; rr < rr1-8; rr++)
|
||||||
for (cc=8+(FC(rr,2)&1), c = FC(rr,cc); cc < cc1-8; cc+=2) {
|
for (cc=8+(FC(rr,2)&1), c = FC(rr,cc), indx=rr*TS+cc; cc < cc1-8; cc+=2, indx+=2) {
|
||||||
//interpolate color difference from optical R/B locations to grid locations
|
|
||||||
|
|
||||||
grbdiffinthfloor=(1-shifthfrac[c]/2)*grbdiff[(rr)*TS+cc]+(shifthfrac[c]/2)*grbdiff[(rr)*TS+cc-2*GRBdir[1][c]];
|
grbdiffold = rgb[indx][1]-rgb[indx][c];
|
||||||
|
|
||||||
|
//interpolate color difference from optical R/B locations to grid locations
|
||||||
|
grbdiffinthfloor=(1-shifthfrac[c]/2)*grbdiff[indx]+(shifthfrac[c]/2)*grbdiff[indx-2*GRBdir[1][c]];
|
||||||
grbdiffinthceil=(1-shifthfrac[c]/2)*grbdiff[(rr-2*GRBdir[0][c])*TS+cc]+(shifthfrac[c]/2)*grbdiff[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]];
|
grbdiffinthceil=(1-shifthfrac[c]/2)*grbdiff[(rr-2*GRBdir[0][c])*TS+cc]+(shifthfrac[c]/2)*grbdiff[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]];
|
||||||
//grbdiffint is bilinear interpolation of G-R/G-B at grid point
|
//grbdiffint is bilinear interpolation of G-R/G-B at grid point
|
||||||
grbdiffint=(1-shiftvfrac[c]/2)*grbdiffinthfloor+(shiftvfrac[c]/2)*grbdiffinthceil;
|
grbdiffint=(1-shiftvfrac[c]/2)*grbdiffinthfloor+(shiftvfrac[c]/2)*grbdiffinthceil;
|
||||||
|
|
||||||
//now determine R/B at grid points using interpolated color differences and interpolated G value at grid point
|
//now determine R/B at grid points using interpolated color differences and interpolated G value at grid point
|
||||||
Gint=rgb[(rr)*TS+cc][1]-grbdiffint;
|
RBint=rgb[indx][1]-grbdiffint;
|
||||||
|
|
||||||
if (fabs(Gint-rgb[(rr)*TS+cc][c])<0.25*(Gint+rgb[(rr)*TS+cc][c])) {
|
if (fabs(RBint-rgb[indx][c])<0.25*(RBint+rgb[indx][c])) {
|
||||||
rgb[(rr)*TS+cc][c]=Gint;
|
if (fabs(grbdiffold)>fabs(grbdiffint) ) {
|
||||||
|
rgb[indx][c]=RBint;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
//gradient weights using difference from G at CA shift points and G at grid points
|
//gradient weights using difference from G at CA shift points and G at grid points
|
||||||
p[0]=1/(eps+fabs(rgb[(rr)*TS+cc][1]-gshift[(rr)*TS+cc]));
|
p[0]=1/(eps+fabs(rgb[indx][1]-gshift[indx]));
|
||||||
p[1]=1/(eps+fabs(rgb[(rr)*TS+cc][1]-gshift[(rr)*TS+cc-2*GRBdir[1][c]]));
|
p[1]=1/(eps+fabs(rgb[indx][1]-gshift[indx-2*GRBdir[1][c]]));
|
||||||
p[2]=1/(eps+fabs(rgb[(rr)*TS+cc][1]-gshift[(rr-2*GRBdir[0][c])*TS+cc]));
|
p[2]=1/(eps+fabs(rgb[indx][1]-gshift[(rr-2*GRBdir[0][c])*TS+cc]));
|
||||||
p[3]=1/(eps+fabs(rgb[(rr)*TS+cc][1]-gshift[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]]));
|
p[3]=1/(eps+fabs(rgb[indx][1]-gshift[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]]));
|
||||||
|
|
||||||
grbdiffint = (p[0]*grbdiff[(rr)*TS+cc]+p[1]*grbdiff[(rr)*TS+cc-2*GRBdir[1][c]]+ \
|
grbdiffint = (p[0]*grbdiff[indx]+p[1]*grbdiff[indx-2*GRBdir[1][c]]+ \
|
||||||
p[2]*grbdiff[(rr-2*GRBdir[0][c])*TS+cc]+p[3]*grbdiff[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]])/(p[0]+p[1]+p[2]+p[3]);
|
p[2]*grbdiff[(rr-2*GRBdir[0][c])*TS+cc]+p[3]*grbdiff[(rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c]])/(p[0]+p[1]+p[2]+p[3]);
|
||||||
|
|
||||||
//there is an assumption that the grid point is no more than 2 pixels from the optical point; perhaps should correct for this???
|
|
||||||
//now determine R/B at grid points using interpolated color differences and interpolated G value at grid point
|
//now determine R/B at grid points using interpolated color differences and interpolated G value at grid point
|
||||||
grbdiffold = rgb[(rr)*TS+cc][1]-rgb[(rr)*TS+cc][c];
|
|
||||||
|
|
||||||
if (fabs(grbdiffold)>fabs(grbdiffint) ) {
|
if (fabs(grbdiffold)>fabs(grbdiffint) ) {
|
||||||
rgb[(rr)*TS+cc][c]=rgb[(rr)*TS+cc][1]-grbdiffint;
|
rgb[indx][c]=rgb[indx][1]-grbdiffint;
|
||||||
}
|
}
|
||||||
if (grbdiffold*grbdiffint<0) {
|
|
||||||
rgb[(rr)*TS+cc][c]=rgb[(rr)*TS+cc][1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if color difference interpolation overshot the correction, just desaturate
|
||||||
|
if (grbdiffold*grbdiffint<0) {
|
||||||
|
rgb[indx][c]=rgb[indx][1]-0.5*(grbdiffold+grbdiffint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,8 +733,11 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
c = FC(row,col);
|
c = FC(row,col);
|
||||||
|
|
||||||
ri->data[row][col] = CLIP((int)(65535.0f*rgb[(rr)*TS+cc][c] + 0.5f));
|
ri->data[row][col] = CLIP((int)(65535.0f*rgb[(rr)*TS+cc][c] + 0.5f));
|
||||||
|
//image[indx][c] = CLIP((int)(65535.0*rgb[(rr)*TS+cc][c] + 0.5));//for dcraw implementation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(plistener) plistener->setProgress(fabs((float)top/height));
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
@ -685,9 +748,8 @@ void RawImageSource::CA_correct_RT() {
|
|||||||
|
|
||||||
|
|
||||||
#undef TS
|
#undef TS
|
||||||
#undef polyord
|
//#undef border
|
||||||
#undef numpar
|
//#undef border2
|
||||||
#undef border
|
|
||||||
#undef PIX_SORT
|
#undef PIX_SORT
|
||||||
#undef SQR
|
#undef SQR
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
static const float arthresh=0.75;
|
static const float arthresh=0.75;
|
||||||
static const float nyqthresh=0.5;//0.5
|
static const float nyqthresh=0.5;//0.5
|
||||||
static const float pmthresh=0.25;//0.25
|
static const float pmthresh=0.25;//0.25
|
||||||
|
static const float lbd=0.66, ubd=1.5;
|
||||||
|
|
||||||
static const float gaussodd[4] = {0.14659727707323927f, 0.103592713382435f, 0.0732036125103057f, 0.0365543548389495f};//gaussian on 5x5 quincunx, sigma=1.2
|
static const float gaussodd[4] = {0.14659727707323927f, 0.103592713382435f, 0.0732036125103057f, 0.0365543548389495f};//gaussian on 5x5 quincunx, sigma=1.2
|
||||||
float gaussgrad[6] = {0.07384411893421103f, 0.06207511968171489f, 0.0521818194747806f, \
|
float gaussgrad[6] = {0.07384411893421103f, 0.06207511968171489f, 0.0521818194747806f, \
|
||||||
@ -78,6 +79,8 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
int bottom, right, row, col;
|
int bottom, right, row, col;
|
||||||
int rr, cc, rr1, cc1, c, indx, indx1, dir, i, j, sgn;
|
int rr, cc, rr1, cc1, c, indx, indx1, dir, i, j, sgn;
|
||||||
|
|
||||||
|
float crse, crnw, crne, crsw, rbse, rbnw, rbne, rbsw, wtse, wtnw, wtsw, wtne;
|
||||||
|
float pmwtalt;
|
||||||
|
|
||||||
float cru, crd, crl, crr;
|
float cru, crd, crl, crr;
|
||||||
float vwt, hwt, Gintv, Ginth;
|
float vwt, hwt, Gintv, Ginth;
|
||||||
@ -86,7 +89,7 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
float sumh, sumv, sumsqh, sumsqv, areawt;
|
float sumh, sumv, sumsqh, sumsqv, areawt;
|
||||||
float nyqtest, vcdvar, hcdvar, hvwtalt, vo, ve, gradp, gradm, gradv, gradh, gradpm, gradhv;
|
float nyqtest, vcdvar, hcdvar, hvwtalt, vo, ve, gradp, gradm, gradv, gradh, gradpm, gradhv;
|
||||||
float vcdvar1, hcdvar1, varwt, diffwt;
|
float vcdvar1, hcdvar1, varwt, diffwt;
|
||||||
float rbvarp, rbvarm, crp, crm, rbp, rbm;
|
float rbvarp, rbvarm;
|
||||||
float gu, gd, gl, gr;
|
float gu, gd, gl, gr;
|
||||||
float gvarh, gvarv;
|
float gvarh, gvarv;
|
||||||
float g[4], f[4];
|
float g[4], f[4];
|
||||||
@ -124,14 +127,17 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
float (*Dgrbpsq1); // TS*TS*4
|
float (*Dgrbpsq1); // TS*TS*4
|
||||||
float (*Dgrbmsq1); // TS*TS*4
|
float (*Dgrbmsq1); // TS*TS*4
|
||||||
float (*cfa); // TS*TS*4
|
float (*cfa); // TS*TS*4
|
||||||
|
float (*pmwt); // TS*TS*4
|
||||||
|
float (*rbp); // TS*TS*4
|
||||||
|
float (*rbm); // TS*TS*4
|
||||||
|
|
||||||
int (*nyquist); // TS*TS*4
|
int (*nyquist); // TS*TS*4
|
||||||
|
|
||||||
|
|
||||||
// assign working space
|
// assign working space
|
||||||
buffer = (char *) malloc(144*TS*TS);
|
buffer = (char *) malloc(156*TS*TS);
|
||||||
//merror(buffer,"amaze_interpolate()");
|
//merror(buffer,"amaze_interpolate()");
|
||||||
memset(buffer,0,144*TS*TS);
|
memset(buffer,0,156*TS*TS);
|
||||||
// rgb array
|
// rgb array
|
||||||
rgb = (float (*)[3]) buffer; //pointers to array
|
rgb = (float (*)[3]) buffer; //pointers to array
|
||||||
delh = (float (*)) (buffer + 12*TS*TS);
|
delh = (float (*)) (buffer + 12*TS*TS);
|
||||||
@ -164,8 +170,11 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
Dgrbpsq1 = (float (*)) (buffer + 128*TS*TS);
|
Dgrbpsq1 = (float (*)) (buffer + 128*TS*TS);
|
||||||
Dgrbmsq1 = (float (*)) (buffer + 132*TS*TS);
|
Dgrbmsq1 = (float (*)) (buffer + 132*TS*TS);
|
||||||
cfa = (float (*)) (buffer + 136*TS*TS);
|
cfa = (float (*)) (buffer + 136*TS*TS);
|
||||||
|
pmwt = (float (*)) (buffer + 140*TS*TS);
|
||||||
|
rbp = (float (*)) (buffer + 144*TS*TS);
|
||||||
|
rbm = (float (*)) (buffer + 148*TS*TS);
|
||||||
|
|
||||||
nyquist = (int (*)) (buffer + 140*TS*TS);
|
nyquist = (int (*)) (buffer + 152*TS*TS);
|
||||||
|
|
||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
@ -227,6 +236,8 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
indx=row*width+col;
|
indx=row*width+col;
|
||||||
indx1=rr*TS+cc;
|
indx1=rr*TS+cc;
|
||||||
rgb[indx1][c] = (ri->data[row][col])/65535.0f;
|
rgb[indx1][c] = (ri->data[row][col])/65535.0f;
|
||||||
|
//rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation
|
||||||
|
|
||||||
cfa[indx1] = rgb[indx1][c];
|
cfa[indx1] = rgb[indx1][c];
|
||||||
}
|
}
|
||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
@ -236,7 +247,6 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
for (cc=ccmin; cc<ccmax; cc++) {
|
for (cc=ccmin; cc<ccmax; cc++) {
|
||||||
c = FC(rr,cc);
|
c = FC(rr,cc);
|
||||||
rgb[rr*TS+cc][c] = rgb[(32-rr)*TS+cc][c];
|
rgb[rr*TS+cc][c] = rgb[(32-rr)*TS+cc][c];
|
||||||
cfa[rr*TS+cc] = rgb[rr*TS+cc][c];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrmax<rr1) {
|
if (rrmax<rr1) {
|
||||||
@ -244,7 +254,7 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
for (cc=ccmin; cc<ccmax; cc++) {
|
for (cc=ccmin; cc<ccmax; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][left+cc])/65535.0f;
|
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][left+cc])/65535.0f;
|
||||||
cfa[(rrmax+rr)*TS+cc] = rgb[(rrmax+rr)*TS+cc][c];
|
//rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+left+cc][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ccmin>0) {
|
if (ccmin>0) {
|
||||||
@ -252,7 +262,6 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
for (cc=0; cc<16; cc++) {
|
for (cc=0; cc<16; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[rr*TS+cc][c] = rgb[rr*TS+32-cc][c];
|
rgb[rr*TS+cc][c] = rgb[rr*TS+32-cc][c];
|
||||||
cfa[rr*TS+cc] = rgb[rr*TS+cc][c];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ccmax<cc1) {
|
if (ccmax<cc1) {
|
||||||
@ -260,17 +269,17 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
for (cc=0; cc<16; cc++) {
|
for (cc=0; cc<16; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[rr*TS+ccmax+cc][c] = (ri->data[(top+rr)][(width-cc-2)])/65535.0f;
|
rgb[rr*TS+ccmax+cc][c] = (ri->data[(top+rr)][(width-cc-2)])/65535.0f;
|
||||||
cfa[rr*TS+ccmax+cc] = rgb[rr*TS+ccmax+cc][c];
|
//rgb[rr*TS+ccmax+cc][c] = (image[(top+rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//also fill the image corners
|
//also, fill the image corners
|
||||||
if (rrmin>0 && ccmin>0) {
|
if (rrmin>0 && ccmin>0) {
|
||||||
for (rr=0; rr<16; rr++)
|
for (rr=0; rr<16; rr++)
|
||||||
for (cc=0; cc<16; cc++) {
|
for (cc=0; cc<16; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rr)*TS+cc][c] = (ri->data[32-rr][32-cc])/65535.0f;
|
rgb[(rr)*TS+cc][c] = (ri->data[32-rr][32-cc])/65535.0f;
|
||||||
cfa[(rr)*TS+cc] = rgb[(rr)*TS+cc][c];
|
//rgb[(rr)*TS+cc][c] = (rgb[(32-rr)*TS+(32-cc)][c]);//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrmax<rr1 && ccmax<cc1) {
|
if (rrmax<rr1 && ccmax<cc1) {
|
||||||
@ -278,23 +287,23 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
for (cc=0; cc<16; cc++) {
|
for (cc=0; cc<16; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+ccmax+cc][c] = (ri->data[(height-rr-2)][(width-cc-2)])/65535.0f;
|
rgb[(rrmax+rr)*TS+ccmax+cc][c] = (ri->data[(height-rr-2)][(width-cc-2)])/65535.0f;
|
||||||
cfa[(rrmax+rr)*TS+ccmax+cc] = rgb[(rrmax+rr)*TS+ccmax+cc][c];
|
//rgb[(rrmax+rr)*TS+ccmax+cc][c] = (image[(height-rr-2)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrmin>0 && ccmax<cc1) {
|
if (rrmin>0 && ccmax<cc1) {
|
||||||
for (rr=0; rr<16; rr++)
|
for (rr=0; rr<16; rr++)
|
||||||
for (cc=0; cc<16; cc++) {
|
for (cc=0; cc<16; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rr)*TS+ccmax+cc][c] = (ri->data[(rr)][(width-cc-2)])/65535.0f;
|
rgb[(rr)*TS+ccmax+cc][c] = (ri->data[(32-rr)][(width-cc-2)])/65535.0f;
|
||||||
cfa[(rr)*TS+ccmax+cc] = rgb[(rr)*TS+ccmax+cc][c];
|
//rgb[(rr)*TS+ccmax+cc][c] = (image[(32-rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rrmax<rr1 && ccmin>0) {
|
if (rrmax<rr1 && ccmin>0) {
|
||||||
for (rr=0; rr<16; rr++)
|
for (rr=0; rr<16; rr++)
|
||||||
for (cc=0; cc<16; cc++) {
|
for (cc=0; cc<16; cc++) {
|
||||||
c=FC(rr,cc);
|
c=FC(rr,cc);
|
||||||
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][cc])/65535.0f;
|
rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][(32-cc)])/65535.0f;
|
||||||
cfa[(rrmax+rr)*TS+cc] = rgb[(rrmax+rr)*TS+cc][c];
|
//rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+(32-cc)][c])/65535.0f;//for dcraw implementation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,10 +358,10 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
rbint[indx]=0;
|
rbint[indx]=0;
|
||||||
|
|
||||||
//color ratios in each cardinal direction
|
//color ratios in each cardinal direction
|
||||||
cru = cfa[indx-v1]*(eps+dirwts[indx-v2][0]+dirwts[indx][0])/(eps+dirwts[indx-v2][0]*cfa[indx]+dirwts[indx][0]*cfa[indx-v2]);
|
cru = cfa[indx-v1]*(dirwts[indx-v2][0]+dirwts[indx][0])/(dirwts[indx-v2][0]*cfa[indx]+dirwts[indx][0]*cfa[indx-v2]);
|
||||||
crd = cfa[indx+v1]*(eps+dirwts[indx+v2][0]+dirwts[indx][0])/(eps+dirwts[indx+v2][0]*cfa[indx]+dirwts[indx][0]*cfa[indx+v2]);
|
crd = cfa[indx+v1]*(dirwts[indx+v2][0]+dirwts[indx][0])/(dirwts[indx+v2][0]*cfa[indx]+dirwts[indx][0]*cfa[indx+v2]);
|
||||||
crl = cfa[indx-1]*(eps+dirwts[indx-2][1]+dirwts[indx][1])/(eps+dirwts[indx-2][1]*cfa[indx]+dirwts[indx][1]*cfa[indx-2]);
|
crl = cfa[indx-1]*(dirwts[indx-2][1]+dirwts[indx][1])/(dirwts[indx-2][1]*cfa[indx]+dirwts[indx][1]*cfa[indx-2]);
|
||||||
crr = cfa[indx+1]*(eps+dirwts[indx+2][1]+dirwts[indx][1])/(eps+dirwts[indx+2][1]*cfa[indx]+dirwts[indx][1]*cfa[indx+2]);
|
crr = cfa[indx+1]*(dirwts[indx+2][1]+dirwts[indx][1])/(dirwts[indx+2][1]*cfa[indx]+dirwts[indx][1]*cfa[indx+2]);
|
||||||
|
|
||||||
guha=cfa[indx-v1]+0.5*(cfa[indx]-cfa[indx-v2]);
|
guha=cfa[indx-v1]+0.5*(cfa[indx]-cfa[indx-v2]);
|
||||||
gdha=cfa[indx+v1]+0.5*(cfa[indx]-cfa[indx+v2]);
|
gdha=cfa[indx+v1]+0.5*(cfa[indx]-cfa[indx+v2]);
|
||||||
@ -398,17 +407,21 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
if (hcdaltvar<hcdvar) hcd[indx]=hcdalt[indx];
|
if (hcdaltvar<hcdvar) hcd[indx]=hcdalt[indx];
|
||||||
if (vcdaltvar<vcdvar) vcd[indx]=vcdalt[indx];
|
if (vcdaltvar<vcdvar) vcd[indx]=vcdalt[indx];
|
||||||
|
|
||||||
//bound the interpolation in regions of high saturation
|
//bound the interpolation for large HA correction
|
||||||
if (c&1) {
|
if (c&1) {
|
||||||
Ginth = -hcd[indx]+cfa[indx];//R or B
|
Ginth = -hcd[indx]+cfa[indx];//R or B
|
||||||
Gintv = -vcd[indx]+cfa[indx];//B or R
|
Gintv = -vcd[indx]+cfa[indx];//B or R
|
||||||
if (hcd[indx] < (0.33*(Ginth+cfa[indx]))) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];
|
//if (hcd[indx] < (0.33*(Ginth+cfa[indx]))) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];
|
||||||
if (vcd[indx] < (0.33*(Gintv+cfa[indx]))) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx];
|
//if (vcd[indx] < (0.33*(Gintv+cfa[indx]))) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx];
|
||||||
|
hcd[indx]=-LIM(Ginth,lbd*MIN(cfa[indx-1],cfa[indx+1]),ubd*MAX(cfa[indx-1],cfa[indx+1]))+cfa[indx];
|
||||||
|
vcd[indx]=-LIM(Gintv,lbd*MIN(cfa[indx-v1],cfa[indx+v1]),ubd*MAX(cfa[indx-v1],cfa[indx+v1]))+cfa[indx];
|
||||||
} else {
|
} else {
|
||||||
Ginth = hcd[indx]+cfa[indx];
|
Ginth = hcd[indx]+cfa[indx];
|
||||||
Gintv = vcd[indx]+cfa[indx];
|
Gintv = vcd[indx]+cfa[indx];
|
||||||
if (hcd[indx] < (-0.33*(Ginth+cfa[indx]))) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];
|
//if (hcd[indx] < (-0.33*(Ginth+cfa[indx]))) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];
|
||||||
if (vcd[indx] < (-0.33*(Gintv+cfa[indx]))) vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx];
|
//if (vcd[indx] < (-0.33*(Gintv+cfa[indx]))) vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx];
|
||||||
|
hcd[indx]=LIM(Ginth,0.9*MIN(cfa[indx-1],cfa[indx+1]),1.1*MAX(cfa[indx-1],cfa[indx+1]))-cfa[indx];
|
||||||
|
vcd[indx]=LIM(Gintv,0.9*MIN(cfa[indx-v1],cfa[indx+v1]),1.1*MAX(cfa[indx-v1],cfa[indx+v1]))-cfa[indx];
|
||||||
}
|
}
|
||||||
vcdsq[indx] = SQR(vcd[indx]);
|
vcdsq[indx] = SQR(vcd[indx]);
|
||||||
hcdsq[indx] = SQR(hcd[indx]);
|
hcdsq[indx] = SQR(hcd[indx]);
|
||||||
@ -592,7 +605,7 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
// diagonal interpolation correction
|
// diagonal interpolation correction
|
||||||
for (rr=8; rr<TS-8; rr++)
|
/*for (rr=8; rr<TS-8; rr++)
|
||||||
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<TS-8; cc+=2,indx+=2) {
|
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<TS-8; cc+=2,indx+=2) {
|
||||||
|
|
||||||
|
|
||||||
@ -623,44 +636,105 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
|
|
||||||
|
|
||||||
if (gradpm-gradhv<pmthresh) continue;
|
if (gradpm-gradhv<pmthresh) continue;
|
||||||
|
pmwt[indx]=1;
|
||||||
|
}
|
||||||
|
|
||||||
//otherwise do diagonal interpolation correction
|
for (rr=8; rr<TS-8; rr++)
|
||||||
|
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<TS-8; cc+=2,indx+=2) {
|
||||||
|
|
||||||
for (dir=0; dir<5; dir++){
|
areawt=(pmwt[indx-v2]+pmwt[indx-m1]+pmwt[indx+p1]+ \
|
||||||
indx1 = indx + nbr[dir];
|
pmwt[indx-2]+pmwt[indx]+pmwt[indx+2]+ \
|
||||||
if (rbint[indx1]) continue;
|
pmwt[indx-p1]+pmwt[indx+m1]+pmwt[indx+v2]);
|
||||||
|
//if most of your neighbors are named pmwt, it's likely that you're one too
|
||||||
|
if (areawt>3) pmwt[indx]=1;
|
||||||
|
//or not
|
||||||
|
if (areawt<2) pmwt[indx]=0;
|
||||||
|
}*/
|
||||||
|
|
||||||
rbvarp = eps + (gausseven[0]*(Dgrbpsq1[indx1-v1]+Dgrbpsq1[indx1-1]+Dgrbpsq1[indx1+1]+Dgrbpsq1[indx1+v1]) + \
|
for (rr=8; rr<TS-8; rr++)
|
||||||
gausseven[1]*(Dgrbpsq1[indx1-v2-1]+Dgrbpsq1[indx1-v2+1]+Dgrbpsq1[indx1-2-v1]+Dgrbpsq1[indx1+2-v1]+ \
|
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<TS-8; cc+=2,indx+=2) {
|
||||||
Dgrbpsq1[indx1-2+v1]+Dgrbpsq1[indx1+2+v1]+Dgrbpsq1[indx1+v2-1]+Dgrbpsq1[indx1+v2+1]));
|
|
||||||
rbvarp -= SQR( (gausseven[0]*(Dgrbp1[indx1-v1]+Dgrbp1[indx1-1]+Dgrbp1[indx1+1]+Dgrbp1[indx1+v1]) + \
|
|
||||||
gausseven[1]*(Dgrbp1[indx1-v2-1]+Dgrbp1[indx1-v2+1]+Dgrbp1[indx1-2-v1]+Dgrbp1[indx1+2-v1]+ \
|
rbvarp = eps + (gausseven[0]*(Dgrbpsq1[indx-v1]+Dgrbpsq1[indx-1]+Dgrbpsq1[indx+1]+Dgrbpsq1[indx+v1]) + \
|
||||||
Dgrbp1[indx1-2+v1]+Dgrbp1[indx1+2+v1]+Dgrbp1[indx1+v2-1]+Dgrbp1[indx1+v2+1])));
|
gausseven[1]*(Dgrbpsq1[indx-v2-1]+Dgrbpsq1[indx-v2+1]+Dgrbpsq1[indx-2-v1]+Dgrbpsq1[indx+2-v1]+ \
|
||||||
rbvarm = eps + (gausseven[0]*(Dgrbmsq1[indx1-v1]+Dgrbmsq1[indx1-1]+Dgrbmsq1[indx1+1]+Dgrbmsq1[indx1+v1]) + \
|
Dgrbpsq1[indx-2+v1]+Dgrbpsq1[indx+2+v1]+Dgrbpsq1[indx+v2-1]+Dgrbpsq1[indx+v2+1]));
|
||||||
gausseven[1]*(Dgrbmsq1[indx1-v2-1]+Dgrbmsq1[indx1-v2+1]+Dgrbmsq1[indx1-2-v1]+Dgrbmsq1[indx1+2-v1]+ \
|
//rbvarp -= SQR( (gausseven[0]*(Dgrbp1[indx-v1]+Dgrbp1[indx-1]+Dgrbp1[indx+1]+Dgrbp1[indx+v1]) + \
|
||||||
Dgrbmsq1[indx1-2+v1]+Dgrbmsq1[indx1+2+v1]+Dgrbmsq1[indx1+v2-1]+Dgrbmsq1[indx1+v2+1]));
|
gausseven[1]*(Dgrbp1[indx-v2-1]+Dgrbp1[indx-v2+1]+Dgrbp1[indx-2-v1]+Dgrbp1[indx+2-v1]+ \
|
||||||
rbvarm -= SQR( (gausseven[0]*(Dgrbm1[indx1-v1]+Dgrbm1[indx1-1]+Dgrbm1[indx1+1]+Dgrbm1[indx1+v1]) + \
|
Dgrbp1[indx-2+v1]+Dgrbp1[indx+2+v1]+Dgrbp1[indx+v2-1]+Dgrbp1[indx+v2+1])));
|
||||||
gausseven[1]*(Dgrbm1[indx1-v2-1]+Dgrbm1[indx1-v2+1]+Dgrbm1[indx1-2-v1]+Dgrbm1[indx1+2-v1]+ \
|
rbvarm = eps + (gausseven[0]*(Dgrbmsq1[indx-v1]+Dgrbmsq1[indx-1]+Dgrbmsq1[indx+1]+Dgrbmsq1[indx+v1]) + \
|
||||||
Dgrbm1[indx1-2+v1]+Dgrbm1[indx1+2+v1]+Dgrbm1[indx1+v2-1]+Dgrbm1[indx1+v2+1])));
|
gausseven[1]*(Dgrbmsq1[indx-v2-1]+Dgrbmsq1[indx-v2+1]+Dgrbmsq1[indx-2-v1]+Dgrbmsq1[indx+2-v1]+ \
|
||||||
|
Dgrbmsq1[indx-2+v1]+Dgrbmsq1[indx+2+v1]+Dgrbmsq1[indx+v2-1]+Dgrbmsq1[indx+v2+1]));
|
||||||
|
//rbvarm -= SQR( (gausseven[0]*(Dgrbm1[indx-v1]+Dgrbm1[indx-1]+Dgrbm1[indx+1]+Dgrbm1[indx+v1]) + \
|
||||||
|
gausseven[1]*(Dgrbm1[indx-v2-1]+Dgrbm1[indx-v2+1]+Dgrbm1[indx-2-v1]+Dgrbm1[indx+2-v1]+ \
|
||||||
|
Dgrbm1[indx-2+v1]+Dgrbm1[indx+2+v1]+Dgrbm1[indx+v2-1]+Dgrbm1[indx+v2+1])));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#########################################
|
||||||
|
|
||||||
//diagonal color ratios
|
//diagonal color ratios
|
||||||
crp=(cfa[indx1-p1]+cfa[indx1+p1])/(eps+cfa[indx1]+0.5*(cfa[indx1-p2]+cfa[indx1+p2]));
|
crse=2*(cfa[indx+m1])/(eps+cfa[indx]+(cfa[indx+m2]));
|
||||||
crm=(cfa[indx1-m1]+cfa[indx1+m1])/(eps+cfa[indx1]+0.5*(cfa[indx1-m2]+cfa[indx1+m2]));
|
crnw=2*(cfa[indx-m1])/(eps+cfa[indx]+(cfa[indx-m2]));
|
||||||
|
crne=2*(cfa[indx+p1])/(eps+cfa[indx]+(cfa[indx+p2]));
|
||||||
|
crsw=2*(cfa[indx-p1])/(eps+cfa[indx]+(cfa[indx-p2]));
|
||||||
|
|
||||||
//assign B/R at R/B sites
|
//assign B/R at R/B sites
|
||||||
if (fabs(1-crp)<arthresh) {rbp=cfa[indx1]*crp;}
|
if (fabs(1-crse)<arthresh) {rbse=cfa[indx]*crse;}//use this if more precise diag interp is necessary
|
||||||
else {rbp=0.5*(cfa[indx1]+cfa[indx1-p1]+cfa[indx1+p1])-0.25*(cfa[indx1-p2]+cfa[indx1+p2]);}
|
else {rbse=(cfa[indx+m1])+0.5*(cfa[indx]-cfa[indx+m2]);}
|
||||||
if (fabs(1-crm)<arthresh) {rbm=cfa[indx1]*crm;}
|
if (fabs(1-crnw)<arthresh) {rbnw=cfa[indx]*crnw;}
|
||||||
else {rbm=0.5*(cfa[indx1]+cfa[indx1-m1]+cfa[indx1+p1])-0.25*(cfa[indx1-m2]+cfa[indx1+m2]);}
|
else {rbnw=(cfa[indx-m1])+0.5*(cfa[indx]-cfa[indx-m2]);}
|
||||||
|
if (fabs(1-crne)<arthresh) {rbne=cfa[indx]*crne;}
|
||||||
|
else {rbne=(cfa[indx+p1])+0.5*(cfa[indx]-cfa[indx+p2]);}
|
||||||
|
if (fabs(1-crsw)<arthresh) {rbsw=cfa[indx]*crsw;}
|
||||||
|
else {rbsw=(cfa[indx-p1])+0.5*(cfa[indx]-cfa[indx-p2]);}
|
||||||
|
|
||||||
|
/*rbse=(cfa[indx+TS+1])+0.5*(cfa[indx]-cfa[indx+2*TS+2]);
|
||||||
|
rbnw=(cfa[indx-TS-1])+0.5*(cfa[indx]-cfa[indx-2*TS-2]);
|
||||||
|
rbne=(cfa[indx-TS+1])+0.5*(cfa[indx]-cfa[indx-2*TS+2]);
|
||||||
|
rbsw=(cfa[indx+TS-1])+0.5*(cfa[indx]-cfa[indx+2*TS-2]);*/
|
||||||
|
|
||||||
|
wtse= eps+delm[indx]+delm[indx+m1]+delm[indx+m2];//same as for wtu,wtd,wtl,wtr
|
||||||
|
wtnw= eps+delm[indx]+delm[indx-m1]+delm[indx-m2];
|
||||||
|
wtne= eps+delp[indx]+delp[indx+p1]+delp[indx+p2];
|
||||||
|
wtsw= eps+delp[indx]+delp[indx-p1]+delp[indx-p2];
|
||||||
|
|
||||||
|
|
||||||
if (2*rbp < cfa[indx1]) {rbp=ULIM(rbp,cfa[indx1-p1],cfa[indx1+p1]);}
|
rbm[indx] = (wtse*rbnw+wtnw*rbse)/(wtse+wtnw);
|
||||||
if (2*rbm < cfa[indx1]) {rbm=ULIM(rbm,cfa[indx1-m1],cfa[indx1+m1]);}
|
rbp[indx] = (wtne*rbsw+wtsw*rbne)/(wtne+wtsw);
|
||||||
|
|
||||||
rbint[indx1] = 0.5*(cfa[indx1] + (rbp*rbvarm+rbm*rbvarp)/(rbvarp+rbvarm));//this is R+B, interpolated
|
pmwt[indx] = rbvarm/(rbvarp+rbvarm);
|
||||||
//rbint[indx1] = 0.5*(cfa[indx1] + (rbp*(1-pmwt[indx1])+rbm*pmwt[indx1]));//this is R+B, interpolated
|
|
||||||
|
//drbintp[indx] = SQR(rbne-rbsw);
|
||||||
|
//drbintm[indx] = SQR(rbnw-rbse);
|
||||||
|
|
||||||
|
//#########################################
|
||||||
|
|
||||||
|
//if (2*rbp[indx] < cfa[indx]) {rbp[indx] = ULIM(rbp[indx] ,cfa[indx-p1],cfa[indx+p1]);}
|
||||||
|
//if (2*rbm[indx] < cfa[indx]) {rbm[indx] = ULIM(rbm[indx] ,cfa[indx-m1],cfa[indx+m1]);}
|
||||||
|
rbp[indx] = LIM(rbp[indx] , lbd*MIN(cfa[indx-p1],cfa[indx+p1]), ubd*MAX(cfa[indx-p1],cfa[indx+p1]));
|
||||||
|
rbm[indx] = LIM(rbm[indx] , lbd*MIN(cfa[indx-m1],cfa[indx+m1]), ubd*MAX(cfa[indx-m1],cfa[indx+m1]));
|
||||||
|
|
||||||
|
//rbint[indx] = 0.5*(cfa[indx] + (rbp*rbvarm+rbm*rbvarp)/(rbvarp+rbvarm));//this is R+B, interpolated
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (rr=8; rr<TS-8; rr++)
|
||||||
|
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<TS-8; cc+=2,indx+=2) {
|
||||||
|
|
||||||
|
//first ask if one gets more directional discrimination from nearby B/R sites
|
||||||
|
pmwtalt = 0.25*(pmwt[indx-m1]+pmwt[indx+p1]+pmwt[indx-p1]+pmwt[indx+m1]);
|
||||||
|
vo=fabs(0.5-pmwt[indx]);
|
||||||
|
ve=fabs(0.5-pmwtalt);
|
||||||
|
if (vo<ve) {pmwt[indx]=pmwtalt;}//a better result was obtained from the neighbors
|
||||||
|
rbint[indx] = 0.5*(cfa[indx] + rbm[indx]*(1-pmwt[indx]) + rbp[indx]*pmwt[indx]);//this is R+B, interpolated
|
||||||
|
}
|
||||||
|
|
||||||
|
for (rr=8; rr<TS-8; rr++)
|
||||||
|
for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc; cc<TS-8; cc+=2,indx+=2) {
|
||||||
|
|
||||||
|
//if (fabs(0.5-pmwt[indx])<fabs(0.5-hvwt[indx])/*+0.5*pmthresh*/) continue;
|
||||||
|
|
||||||
}//end of populating neighbor B/R values
|
|
||||||
//now interpolate G vertically/horizontally using R+B values
|
//now interpolate G vertically/horizontally using R+B values
|
||||||
//unfortunately, since G interpolation cannot be done diagonally this may lead to color shifts
|
//unfortunately, since G interpolation cannot be done diagonally this may lead to color shifts
|
||||||
//color ratios for G interpolation
|
//color ratios for G interpolation
|
||||||
@ -680,14 +754,25 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
if (fabs(1-crr)<arthresh) {gr=rbint[indx]*crr;}
|
if (fabs(1-crr)<arthresh) {gr=rbint[indx]*crr;}
|
||||||
else {gr=cfa[indx+1]+0.5*(rbint[indx]-rbint[indx+2]);}
|
else {gr=cfa[indx+1]+0.5*(rbint[indx]-rbint[indx+2]);}
|
||||||
|
|
||||||
|
//gu=rbint[indx]*cru;
|
||||||
|
//gd=rbint[indx]*crd;
|
||||||
|
//gl=rbint[indx]*crl;
|
||||||
|
//gr=rbint[indx]*crr;
|
||||||
|
|
||||||
//interpolated G via adaptive weights of cardinal evaluations
|
//interpolated G via adaptive weights of cardinal evaluations
|
||||||
Gintv = (dirwts[indx-v1][0]*gd+dirwts[indx+v1][0]*gu)/(dirwts[indx+v1][0]+dirwts[indx-v1][0]);
|
Gintv = (dirwts[indx-v1][0]*gd+dirwts[indx+v1][0]*gu)/(dirwts[indx+v1][0]+dirwts[indx-v1][0]);
|
||||||
Ginth = (dirwts[indx-1][1]*gr+dirwts[indx+1][1]*gl)/(dirwts[indx-1][1]+dirwts[indx+1][1]);
|
Ginth = (dirwts[indx-1][1]*gr+dirwts[indx+1][1]*gl)/(dirwts[indx-1][1]+dirwts[indx+1][1]);
|
||||||
|
|
||||||
if (rbint[indx]-2*Ginth > (0.33*(2*Ginth+rbint[indx]))) Ginth=ULIM(Ginth,cfa[indx-1],cfa[indx+1]);
|
//if (rbint[indx]-2*Ginth > (0.33*(2*Ginth+rbint[indx]))) Ginth=ULIM(Ginth,cfa[indx-1],cfa[indx+1]);
|
||||||
if (rbint[indx]-2*Gintv > (0.33*(2*Gintv+rbint[indx]))) Gintv=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1]);
|
//if (rbint[indx]-2*Gintv > (0.33*(2*Gintv+rbint[indx]))) Gintv=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1]);
|
||||||
|
Ginth=LIM(Ginth, lbd*MIN(cfa[indx-1],cfa[indx+1]), ubd*MAX(cfa[indx-1],cfa[indx+1]));
|
||||||
|
Gintv=LIM(Gintv, lbd*MIN(cfa[indx-v1],cfa[indx+v1]), ubd*MAX(cfa[indx-v1],cfa[indx+v1]));
|
||||||
|
|
||||||
|
//Galt[indx] = Ginth*(1-hvwt[indx]) + Gintv*hvwt[indx];
|
||||||
rgb[indx][1] = Ginth*(1-hvwt[indx]) + Gintv*hvwt[indx];
|
rgb[indx][1] = Ginth*(1-hvwt[indx]) + Gintv*hvwt[indx];
|
||||||
|
Dgrb[indx][0] = rgb[indx][1]-cfa[indx];
|
||||||
|
|
||||||
|
rgb[indx][2-FC(rr,cc)]=2*rbint[indx]-cfa[indx];
|
||||||
}
|
}
|
||||||
//end of diagonal interpolation correction
|
//end of diagonal interpolation correction
|
||||||
//t2_diag += clock() - t1_diag;
|
//t2_diag += clock() - t1_diag;
|
||||||
@ -744,6 +829,12 @@ void RawImageSource::amaze_demosaic_RT() {
|
|||||||
green[row][col] = CLIP((int)(65535.0f*rgb[indx][1] + 0.5f));
|
green[row][col] = CLIP((int)(65535.0f*rgb[indx][1] + 0.5f));
|
||||||
blue[row][col] = CLIP((int)(65535.0f*rgb[indx][2] + 0.5f));
|
blue[row][col] = CLIP((int)(65535.0f*rgb[indx][2] + 0.5f));
|
||||||
|
|
||||||
|
//for dcraw implementation
|
||||||
|
//for (c=0; c<3; c++){
|
||||||
|
// image[indx][c] = CLIP((int)(65535.0f*rgb[rr*TS+cc][c] + 0.5f));
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//end of main loop
|
//end of main loop
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user