Fixed progress indication for AHD demosaic; code formatted
This commit is contained in:
parent
54bcc00087
commit
eb24ebe041
@ -2350,169 +2350,180 @@ void RawImageSource::border_interpolate(int border, ushort (*image)[4])
|
|||||||
|
|
||||||
void RawImageSource::ahd_demosaic()
|
void RawImageSource::ahd_demosaic()
|
||||||
{
|
{
|
||||||
int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
|
int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
|
||||||
ushort (*pix)[4], (*rix)[3];
|
ushort (*pix)[4], (*rix)[3];
|
||||||
static const int dir[4] = { -1, 1, -TS, TS };
|
static const int dir[4] = { -1, 1, -TS, TS };
|
||||||
unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
|
unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
|
||||||
float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
|
float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
|
||||||
ushort (*rgb)[TS][TS][3];
|
ushort (*rgb)[TS][TS][3];
|
||||||
short (*lab)[TS][TS][3], (*lix)[3];
|
short (*lab)[TS][TS][3], (*lix)[3];
|
||||||
char (*homo)[TS][TS], *buffer;
|
char (*homo)[TS][TS], *buffer;
|
||||||
|
|
||||||
int width=W, height=H;
|
int width=W, height=H;
|
||||||
ushort (*image)[4];
|
ushort (*image)[4];
|
||||||
int colors = 3;
|
int colors = 3;
|
||||||
|
|
||||||
const double xyz_rgb[3][3] = { /* XYZ from RGB */
|
const double xyz_rgb[3][3] = { /* XYZ from RGB */
|
||||||
{ 0.412453, 0.357580, 0.180423 },
|
{ 0.412453, 0.357580, 0.180423 },
|
||||||
{ 0.212671, 0.715160, 0.072169 },
|
{ 0.212671, 0.715160, 0.072169 },
|
||||||
{ 0.019334, 0.119193, 0.950227 } };
|
{ 0.019334, 0.119193, 0.950227 }
|
||||||
const float d65_white[3] = { 0.950456, 1, 1.088754 };
|
};
|
||||||
|
|
||||||
if (plistener) {
|
const float d65_white[3] = { 0.950456, 1, 1.088754 };
|
||||||
plistener->setProgressStr ("Demosaicing...");
|
|
||||||
plistener->setProgress (0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
image = (ushort (*)[4]) calloc (H*W, sizeof *image);
|
if (plistener) {
|
||||||
for (int ii=0; ii<H; ii++)
|
plistener->setProgressStr ("Demosaicing...");
|
||||||
for (int jj=0; jj<W; jj++)
|
plistener->setProgress (0.0);
|
||||||
image[ii*W+jj][fc(ii,jj)] = ri->data[ii][jj];
|
|
||||||
|
|
||||||
for (i=0; i < 0x10000; i++) {
|
|
||||||
r = i / 65535.0;
|
|
||||||
cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
|
|
||||||
}
|
|
||||||
for (i=0; i < 3; i++)
|
|
||||||
for (j=0; j < colors; j++)
|
|
||||||
for (xyz_cam[i][j] = k=0; k < 3; k++)
|
|
||||||
xyz_cam[i][j] += xyz_rgb[i][k] * coeff[k][j] / d65_white[i];
|
|
||||||
|
|
||||||
border_interpolate(5, image);
|
|
||||||
buffer = (char *) malloc (26*TS*TS); /* 1664 kB */
|
|
||||||
//merror (buffer, "ahd_interpolate()");
|
|
||||||
rgb = (ushort(*)[TS][TS][3]) buffer;
|
|
||||||
lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
|
|
||||||
homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
|
|
||||||
|
|
||||||
for (top=2; top < height-5; top += TS-6)
|
|
||||||
for (left=2; left < width-5; left += TS-6) {
|
|
||||||
|
|
||||||
/* Interpolate green horizontally and vertically: */
|
|
||||||
for (row = top; row < top+TS && row < height-2; row++) {
|
|
||||||
col = left + (FC(row,left) & 1);
|
|
||||||
for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
|
|
||||||
pix = image + row*width+col;
|
|
||||||
val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
|
|
||||||
- pix[-2][c] - pix[2][c]) >> 2;
|
|
||||||
rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
|
|
||||||
val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
|
|
||||||
- pix[-2*width][c] - pix[2*width][c]) >> 2;
|
|
||||||
rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(plistener) plistener->setProgress (0.33);
|
|
||||||
/* Interpolate red and blue, and convert to CIELab: */
|
|
||||||
for (d=0; d < 2; d++)
|
|
||||||
for (row=top+1; row < top+TS-1 && row < height-3; row++)
|
|
||||||
for (col=left+1; col < left+TS-1 && col < width-3; col++) {
|
|
||||||
pix = image + row*width+col;
|
|
||||||
rix = &rgb[d][row-top][col-left];
|
|
||||||
lix = &lab[d][row-top][col-left];
|
|
||||||
if ((c = 2 - FC(row,col)) == 1) {
|
|
||||||
c = FC(row+1,col);
|
|
||||||
val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
|
|
||||||
- rix[-1][1] - rix[1][1] ) >> 1);
|
|
||||||
rix[0][2-c] = CLIP(val);
|
|
||||||
val = pix[0][1] + (( pix[-width][c] + pix[width][c]
|
|
||||||
- rix[-TS][1] - rix[TS][1] ) >> 1);
|
|
||||||
} else
|
|
||||||
val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
|
|
||||||
+ pix[+width-1][c] + pix[+width+1][c]
|
|
||||||
- rix[-TS-1][1] - rix[-TS+1][1]
|
|
||||||
- rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
|
|
||||||
rix[0][c] = CLIP(val);
|
|
||||||
c = FC(row,col);
|
|
||||||
rix[0][c] = pix[0][c];
|
|
||||||
xyz[0] = xyz[1] = xyz[2] = 0.5;
|
|
||||||
FORCC {
|
|
||||||
xyz[0] += xyz_cam[0][c] * rix[0][c];
|
|
||||||
xyz[1] += xyz_cam[1][c] * rix[0][c];
|
|
||||||
xyz[2] += xyz_cam[2][c] * rix[0][c];
|
|
||||||
}
|
|
||||||
xyz[0] = cbrt[CLIP((int) xyz[0])];
|
|
||||||
xyz[1] = cbrt[CLIP((int) xyz[1])];
|
|
||||||
xyz[2] = cbrt[CLIP((int) xyz[2])];
|
|
||||||
lix[0][0] = 64 * (116 * xyz[1] - 16);
|
|
||||||
lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
|
|
||||||
lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(plistener) plistener->setProgress (0.5);
|
|
||||||
/* Build homogeneity maps from the CIELab images: */
|
|
||||||
memset (homo, 0, 2*TS*TS);
|
|
||||||
for (row=top+2; row < top+TS-2 && row < height-4; row++) {
|
|
||||||
tr = row-top;
|
|
||||||
for (col=left+2; col < left+TS-2 && col < width-4; col++) {
|
|
||||||
tc = col-left;
|
|
||||||
for (d=0; d < 2; d++) {
|
|
||||||
lix = &lab[d][tr][tc];
|
|
||||||
for (i=0; i < 4; i++) {
|
|
||||||
ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
|
|
||||||
abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
|
|
||||||
+ SQR(lix[0][2]-lix[dir[i]][2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
|
|
||||||
MAX(ldiff[1][2],ldiff[1][3]));
|
|
||||||
abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
|
|
||||||
MAX(abdiff[1][2],abdiff[1][3]));
|
|
||||||
for (d=0; d < 2; d++)
|
|
||||||
for (i=0; i < 4; i++)
|
|
||||||
if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
|
|
||||||
homo[d][tr][tc]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(plistener) plistener->setProgress (0.8);
|
|
||||||
/* Combine the most homogenous pixels for the final result: */
|
|
||||||
for (row=top+3; row < top+TS-3 && row < height-5; row++) {
|
|
||||||
tr = row-top;
|
|
||||||
for (col=left+3; col < left+TS-3 && col < width-5; col++) {
|
|
||||||
tc = col-left;
|
|
||||||
for (d=0; d < 2; d++)
|
|
||||||
for (hm[d]=0, i=tr-1; i <= tr+1; i++)
|
|
||||||
for (j=tc-1; j <= tc+1; j++)
|
|
||||||
hm[d] += homo[d][i][j];
|
|
||||||
if (hm[0] != hm[1])
|
|
||||||
FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
|
|
||||||
else
|
|
||||||
FORC3 image[row*width+col][c] =
|
|
||||||
(rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(plistener) plistener->setProgress (1.0);
|
|
||||||
free (buffer);
|
image = (ushort (*)[4]) calloc (H*W, sizeof *image);
|
||||||
red = new unsigned short*[H];
|
for (int ii=0; ii<H; ii++)
|
||||||
for (int i=0; i<H; i++) {
|
for (int jj=0; jj<W; jj++)
|
||||||
red[i] = new unsigned short[W];
|
image[ii*W+jj][fc(ii,jj)] = ri->data[ii][jj];
|
||||||
for (int j=0; j<W; j++)
|
|
||||||
red[i][j] = image[i*W+j][0];
|
for (i=0; i < 0x10000; i++) {
|
||||||
}
|
r = i / 65535.0;
|
||||||
green = new unsigned short*[H];
|
cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
|
||||||
for (int i=0; i<H; i++) {
|
}
|
||||||
green[i] = new unsigned short[W];
|
|
||||||
for (int j=0; j<W; j++)
|
for (i=0; i < 3; i++)
|
||||||
green[i][j] = image[i*W+j][1];
|
for (j=0; j < colors; j++)
|
||||||
}
|
for (xyz_cam[i][j] = k=0; k < 3; k++)
|
||||||
blue = new unsigned short*[H];
|
xyz_cam[i][j] += xyz_rgb[i][k] * coeff[k][j] / d65_white[i];
|
||||||
for (int i=0; i<H; i++) {
|
|
||||||
blue[i] = new unsigned short[W];
|
border_interpolate(5, image);
|
||||||
for (int j=0; j<W; j++)
|
buffer = (char *) malloc (26*TS*TS); /* 1664 kB */
|
||||||
blue[i][j] = image[i*W+j][2];
|
//merror (buffer, "ahd_interpolate()");
|
||||||
}
|
rgb = (ushort(*)[TS][TS][3]) buffer;
|
||||||
free (image);
|
lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
|
||||||
|
homo = (char (*)[TS][TS]) (buffer + 24*TS*TS);
|
||||||
|
|
||||||
|
// helper variables for progress indication
|
||||||
|
int n_tiles = ((height-7 + (TS-7))/(TS-6)) * ((width-7 + (TS-7))/(TS-6));
|
||||||
|
int tile = 0;
|
||||||
|
|
||||||
|
for (top=2; top < height-5; top += TS-6)
|
||||||
|
for (left=2; left < width-5; left += TS-6) {
|
||||||
|
|
||||||
|
/* Interpolate green horizontally and vertically: */
|
||||||
|
for (row = top; row < top+TS && row < height-2; row++) {
|
||||||
|
col = left + (FC(row,left) & 1);
|
||||||
|
for (c = FC(row,col); col < left+TS && col < width-2; col+=2) {
|
||||||
|
pix = image + row*width+col;
|
||||||
|
val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2
|
||||||
|
- pix[-2][c] - pix[2][c]) >> 2;
|
||||||
|
rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
|
||||||
|
val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2
|
||||||
|
- pix[-2*width][c] - pix[2*width][c]) >> 2;
|
||||||
|
rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interpolate red and blue, and convert to CIELab: */
|
||||||
|
for (d=0; d < 2; d++)
|
||||||
|
for (row=top+1; row < top+TS-1 && row < height-3; row++)
|
||||||
|
for (col=left+1; col < left+TS-1 && col < width-3; col++) {
|
||||||
|
pix = image + row*width+col;
|
||||||
|
rix = &rgb[d][row-top][col-left];
|
||||||
|
lix = &lab[d][row-top][col-left];
|
||||||
|
if ((c = 2 - FC(row,col)) == 1) {
|
||||||
|
c = FC(row+1,col);
|
||||||
|
val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c]
|
||||||
|
- rix[-1][1] - rix[1][1] ) >> 1);
|
||||||
|
rix[0][2-c] = CLIP(val);
|
||||||
|
val = pix[0][1] + (( pix[-width][c] + pix[width][c]
|
||||||
|
- rix[-TS][1] - rix[TS][1] ) >> 1);
|
||||||
|
} else
|
||||||
|
val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c]
|
||||||
|
+ pix[+width-1][c] + pix[+width+1][c]
|
||||||
|
- rix[-TS-1][1] - rix[-TS+1][1]
|
||||||
|
- rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2);
|
||||||
|
rix[0][c] = CLIP(val);
|
||||||
|
c = FC(row,col);
|
||||||
|
rix[0][c] = pix[0][c];
|
||||||
|
xyz[0] = xyz[1] = xyz[2] = 0.5;
|
||||||
|
FORCC {
|
||||||
|
xyz[0] += xyz_cam[0][c] * rix[0][c];
|
||||||
|
xyz[1] += xyz_cam[1][c] * rix[0][c];
|
||||||
|
xyz[2] += xyz_cam[2][c] * rix[0][c];
|
||||||
|
}
|
||||||
|
xyz[0] = cbrt[CLIP((int) xyz[0])];
|
||||||
|
xyz[1] = cbrt[CLIP((int) xyz[1])];
|
||||||
|
xyz[2] = cbrt[CLIP((int) xyz[2])];
|
||||||
|
lix[0][0] = 64 * (116 * xyz[1] - 16);
|
||||||
|
lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
|
||||||
|
lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build homogeneity maps from the CIELab images: */
|
||||||
|
memset (homo, 0, 2*TS*TS);
|
||||||
|
for (row=top+2; row < top+TS-2 && row < height-4; row++) {
|
||||||
|
tr = row-top;
|
||||||
|
for (col=left+2; col < left+TS-2 && col < width-4; col++) {
|
||||||
|
tc = col-left;
|
||||||
|
for (d=0; d < 2; d++) {
|
||||||
|
lix = &lab[d][tr][tc];
|
||||||
|
for (i=0; i < 4; i++) {
|
||||||
|
ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]);
|
||||||
|
abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1])
|
||||||
|
+ SQR(lix[0][2]-lix[dir[i]][2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
leps = MIN(MAX(ldiff[0][0],ldiff[0][1]),
|
||||||
|
MAX(ldiff[1][2],ldiff[1][3]));
|
||||||
|
abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
|
||||||
|
MAX(abdiff[1][2],abdiff[1][3]));
|
||||||
|
for (d=0; d < 2; d++)
|
||||||
|
for (i=0; i < 4; i++)
|
||||||
|
if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps)
|
||||||
|
homo[d][tr][tc]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Combine the most homogenous pixels for the final result: */
|
||||||
|
for (row=top+3; row < top+TS-3 && row < height-5; row++) {
|
||||||
|
tr = row-top;
|
||||||
|
for (col=left+3; col < left+TS-3 && col < width-5; col++) {
|
||||||
|
tc = col-left;
|
||||||
|
for (d=0; d < 2; d++)
|
||||||
|
for (hm[d]=0, i=tr-1; i <= tr+1; i++)
|
||||||
|
for (j=tc-1; j <= tc+1; j++)
|
||||||
|
hm[d] += homo[d][i][j];
|
||||||
|
if (hm[0] != hm[1])
|
||||||
|
FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c];
|
||||||
|
else
|
||||||
|
FORC3 image[row*width+col][c] =
|
||||||
|
(rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tile++;
|
||||||
|
if(plistener) {
|
||||||
|
plistener->setProgress((double)tile / n_tiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(plistener) plistener->setProgress (1.0);
|
||||||
|
free (buffer);
|
||||||
|
red = new unsigned short*[H];
|
||||||
|
for (int i=0; i<H; i++) {
|
||||||
|
red[i] = new unsigned short[W];
|
||||||
|
for (int j=0; j<W; j++)
|
||||||
|
red[i][j] = image[i*W+j][0];
|
||||||
|
}
|
||||||
|
green = new unsigned short*[H];
|
||||||
|
for (int i=0; i<H; i++) {
|
||||||
|
green[i] = new unsigned short[W];
|
||||||
|
for (int j=0; j<W; j++)
|
||||||
|
green[i][j] = image[i*W+j][1];
|
||||||
|
}
|
||||||
|
blue = new unsigned short*[H];
|
||||||
|
for (int i=0; i<H; i++) {
|
||||||
|
blue[i] = new unsigned short[W];
|
||||||
|
for (int j=0; j<W; j++)
|
||||||
|
blue[i][j] = image[i*W+j][2];
|
||||||
|
}
|
||||||
|
free (image);
|
||||||
}
|
}
|
||||||
#undef TS
|
#undef TS
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user