Issue 2059: better demosaicing and ca autocorrect performance with extreme white balances. This patch also adds a missing colortemp parameter that DCP color correction needs (forgot in the dcp 1987 patch)

This commit is contained in:
torger
2013-11-20 19:59:14 +01:00
parent 43869ed883
commit a8d6f1a534
10 changed files with 91 additions and 42 deletions

View File

@@ -123,7 +123,7 @@ void Crop::update (int todo) {
if (skip==1 && params.dirpyrDenoise.enabled)
parent->ipf.RGB_denoise(origCrop, origCrop, parent->imgsrc->isRAW(), /*Roffset,*/ params.dirpyrDenoise, params.defringe, parent->imgsrc->getDirPyrDenoiseExpComp());
}
parent->imgsrc->convertColorSpace(origCrop, params.icm, params.raw);
parent->imgsrc->convertColorSpace(origCrop, params.icm, parent->currWB, params.raw);
}
// transform

View File

@@ -77,7 +77,7 @@ class ImageSource : public InitialImage {
// true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource
virtual bool isWBProviderReady () =0;
virtual void convertColorSpace (Imagefloat* image, ColorManagementParams cmp, RAWParams raw) =0;// DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images
virtual void convertColorSpace (Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw) =0;// DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images
virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) =0;
virtual ColorTemp getWB () =0;
virtual ColorTemp getSpotWB (std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal) =0;

View File

@@ -239,7 +239,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
if (scale==1 && params.dirpyrDenoise.enabled)
ipf.RGB_denoise(orig_prev, orig_prev, imgsrc->isRAW(), params.dirpyrDenoise, params.defringe, imgsrc->getDirPyrDenoiseExpComp());
}
imgsrc->convertColorSpace(orig_prev, params.icm, params.raw);
imgsrc->convertColorSpace(orig_prev, params.icm, currWB, params.raw);
ipf.firstAnalysis (orig_prev, &params, vhist16, imgsrc->getGamma());
}
@@ -783,7 +783,7 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
params.wb.temperature = currWB.getTemp ();
params.wb.green = currWB.getGreen ();
imgsrc->getImage (currWB, 0, im, pp, ppar.hlrecovery, ppar.icm, ppar.raw);
imgsrc->convertColorSpace(im, ppar.icm, params.raw);
imgsrc->convertColorSpace(im, ppar.icm, currWB, params.raw);
Image16* im16 = im->to16();
delete im;
im16->saveTIFF (fname,16,true);

View File

@@ -47,7 +47,7 @@ RawImage::~RawImage()
/* Similar to dcraw scale_colors for coeff. calculation, but without actual pixels scaling.
* need pixels in data[][] available
*/
void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblack_)
void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblack_, bool forceAutoWB)
{
unsigned row, col, x, y, c, sum[8];
@@ -60,7 +60,7 @@ void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblac
cblack_[c] = (float) this->get_cblack(c);
pre_mul_[c] = this->get_pre_mul(c);
}
if ( this->get_cam_mul(0) == -1 ) {
if ( this->get_cam_mul(0) == -1 || forceAutoWB) {
memset(dsum, 0, sizeof dsum);
for (row = 0; row < H; row += 8)
for (col = 0; col < W ; col += 8) {

2
rtengine/rawimage.h Normal file → Executable file
View File

@@ -90,7 +90,7 @@ public:
~RawImage();
int loadRaw (bool loadData=true, bool closeFile=true);
void get_colorsCoeff( float* pre_mul_, float* scale_mul_, float* cblack_ );
void get_colorsCoeff( float* pre_mul_, float* scale_mul_, float* cblack_, bool forceAutoWB );
void set_prefilters(){
if (isBayer() && get_colors() == 3) {
prefilters = filters;

View File

@@ -215,9 +215,9 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
rm = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b;
gm = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b;
bm = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b;
rm = camwb_red / rm;
gm = camwb_green / gm;
bm = camwb_blue / bm;
rm = refwb_red / rm;
gm = refwb_green / gm;
bm = refwb_blue / bm;
/*float mul_lum = 0.299*rm + 0.587*gm + 0.114*bm;
rm /= mul_lum;
@@ -425,7 +425,7 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
//colorSpaceConversion (image, cmp, raw, embProfile, camProfile, xyz_cam, (static_cast<const ImageData*>(getMetaData()))->getCamera());
}
void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, RAWParams raw) {
void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw) {
colorSpaceConversion (image, cmp, wb, raw, embProfile, camProfile, imatrices.xyz_cam, (static_cast<const ImageData*>(getMetaData()))->getCamera());
}
@@ -874,19 +874,68 @@ int RawImageSource::load (Glib::ustring fname, bool batch) {
camProfile = iccStore->createFromMatrix (imatrices.xyz_cam, false, "Camera");
inverse33 (imatrices.xyz_cam, imatrices.cam_xyz);
// First we get the "as shot" ("Camera") white balance and store it
float pre_mul[4];
ri->get_colorsCoeff( pre_mul, scale_mul, c_black);//modify for black level
camwb_red = ri->get_pre_mul(0) / pre_mul[0];
camwb_green = ri->get_pre_mul(1) / pre_mul[1];
camwb_blue = ri->get_pre_mul(2) / pre_mul[2];
initialGain = 1.0 / min(pre_mul[0], pre_mul[1], pre_mul[2]);
ri->get_colorsCoeff( pre_mul, scale_mul, c_black, false);//modify for black level
double camwb_red = ri->get_pre_mul(0) / pre_mul[0];
double camwb_green = ri->get_pre_mul(1) / pre_mul[1];
double camwb_blue = ri->get_pre_mul(2) / pre_mul[2];
double cam_r = imatrices.rgb_cam[0][0]*camwb_red + imatrices.rgb_cam[0][1]*camwb_green + imatrices.rgb_cam[0][2]*camwb_blue;
double cam_g = imatrices.rgb_cam[1][0]*camwb_red + imatrices.rgb_cam[1][1]*camwb_green + imatrices.rgb_cam[1][2]*camwb_blue;
double cam_b = imatrices.rgb_cam[2][0]*camwb_red + imatrices.rgb_cam[2][1]*camwb_green + imatrices.rgb_cam[2][2]*camwb_blue;
camera_wb = ColorTemp (cam_r, cam_g, cam_b, 1.); // as shot WB
ColorTemp ReferenceWB;
double ref_r, ref_g, ref_b;
{
// ...then we re-get the constants but now with auto which gives us better demosaicing and CA auto-correct
// performance for strange white balance settings (such as UniWB)
ri->get_colorsCoeff( pre_mul, scale_mul, c_black, true);
refwb_red = ri->get_pre_mul(0) / pre_mul[0];
refwb_green = ri->get_pre_mul(1) / pre_mul[1];
refwb_blue = ri->get_pre_mul(2) / pre_mul[2];
initialGain = 1.0 / min(pre_mul[0], pre_mul[1], pre_mul[2]);
ref_r = imatrices.rgb_cam[0][0]*refwb_red + imatrices.rgb_cam[0][1]*refwb_green + imatrices.rgb_cam[0][2]*refwb_blue;
ref_g = imatrices.rgb_cam[1][0]*refwb_red + imatrices.rgb_cam[1][1]*refwb_green + imatrices.rgb_cam[1][2]*refwb_blue;
ref_b = imatrices.rgb_cam[2][0]*refwb_red + imatrices.rgb_cam[2][1]*refwb_green + imatrices.rgb_cam[2][2]*refwb_blue;
ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1.);
}
if (settings->verbose) {
printf("Raw As Shot White balance: temp %f, tint %f\n", camera_wb.getTemp(), camera_wb.getGreen());
printf("Raw Reference (auto) white balance: temp %f, tint %f, multipliers [%f %f %f | %f %f %f]\n", ReferenceWB.getTemp(), ReferenceWB.getGreen(), ref_r, ref_g, ref_b, refwb_red, refwb_blue, refwb_green);
}
/*{
// Test code: if you want to test a specific white balance
ColorTemp d50wb = ColorTemp(5000.0, 1.0, 1.0, "Custom");
double rm,gm,bm,r,g,b;
d50wb.getMultipliers(r, g, b);
camwb_red = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b;
camwb_green = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b;
camwb_blue = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b;
double pre_mul[3], dmax = 0;
pre_mul[0] = ri->get_pre_mul(0) / camwb_red;
pre_mul[1] = ri->get_pre_mul(1) / camwb_green;
pre_mul[2] = ri->get_pre_mul(2) / camwb_blue;
for (int c = 0; c < 3; c++) {
if (dmax < pre_mul[c])
dmax = pre_mul[c];
}
for (int c = 0; c < 3; c++) {
pre_mul[c] /= dmax;
}
camwb_red *= dmax;
camwb_green *= dmax;
camwb_blue *= dmax;
for (int c = 0; c < 3; c++) {
int sat = ri->get_white(c) - ri->get_cblack(c);
scale_mul[c] = pre_mul[c] * 65535.0 / sat;
}
scale_mul[3] = pre_mul[1] * 65535.0 / (ri->get_white(3) - ri->get_cblack(3));
initialGain = 1.0 / min(pre_mul[0], pre_mul[1], pre_mul[2]);
}*/
wb = ColorTemp (cam_r, cam_g, cam_b, 1.);
ri->set_prefilters();
@@ -2224,15 +2273,15 @@ void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) {
if (ri->isBayer()) {
for (int j=start; j<end; j++) {
if (ri->ISGREEN(i,j)) tmphistogram[CLIP((int)(camwb_green*rawData[i][j]))>>histcompr]+=4;
else if (ri->ISRED(i,j)) tmphistogram[CLIP((int)(camwb_red* rawData[i][j]))>>histcompr]+=4;
else if (ri->ISBLUE(i,j)) tmphistogram[CLIP((int)(camwb_blue* rawData[i][j]))>>histcompr]+=4;
if (ri->ISGREEN(i,j)) tmphistogram[CLIP((int)(refwb_green*rawData[i][j]))>>histcompr]+=4;
else if (ri->ISRED(i,j)) tmphistogram[CLIP((int)(refwb_red* rawData[i][j]))>>histcompr]+=4;
else if (ri->ISBLUE(i,j)) tmphistogram[CLIP((int)(refwb_blue* rawData[i][j]))>>histcompr]+=4;
}
} else {
for (int j=start; j<end; j++) {
tmphistogram[CLIP((int)(camwb_red* rawData[i][3*j+0]))>>histcompr]++;
tmphistogram[CLIP((int)(camwb_green*rawData[i][3*j+1]))>>histcompr]+=2;
tmphistogram[CLIP((int)(camwb_blue* rawData[i][3*j+2]))>>histcompr]++;
tmphistogram[CLIP((int)(refwb_red* rawData[i][3*j+0]))>>histcompr]++;
tmphistogram[CLIP((int)(refwb_green*rawData[i][3*j+1]))>>histcompr]+=2;
tmphistogram[CLIP((int)(refwb_blue* rawData[i][3*j+2]))>>histcompr]++;
}
}
}
@@ -2433,9 +2482,9 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) {
// return ColorTemp (pow(avg_r/rn, 1.0/6.0)*img_r, pow(avg_g/gn, 1.0/6.0)*img_g, pow(avg_b/bn, 1.0/6.0)*img_b);
double reds = avg_r/rn * camwb_red;
double greens = avg_g/gn * camwb_green;
double blues = avg_b/bn * camwb_blue;
double reds = avg_r/rn * refwb_red;
double greens = avg_g/gn * refwb_green;
double blues = avg_b/bn * refwb_blue;
redAWBMul = rm = imatrices.rgb_cam[0][0]*reds + imatrices.rgb_cam[0][1]*greens + imatrices.rgb_cam[0][2]*blues;
greenAWBMul = gm = imatrices.rgb_cam[1][0]*reds + imatrices.rgb_cam[1][1]*greens + imatrices.rgb_cam[1][2]*blues;
@@ -2560,9 +2609,9 @@ void RawImageSource::getRowStartEnd (int x, int &start, int &end) {
return ColorTemp (equal);
}
else {
reds = reds/rn * camwb_red;
greens = greens/rn * camwb_green;
blues = blues/rn * camwb_blue;
reds = reds/rn * refwb_red;
greens = greens/rn * refwb_green;
blues = blues/rn * refwb_blue;
double rm = imatrices.rgb_cam[0][0]*reds + imatrices.rgb_cam[0][1]*greens + imatrices.rgb_cam[0][2]*blues;
double gm = imatrices.rgb_cam[1][0]*reds + imatrices.rgb_cam[1][1]*greens + imatrices.rgb_cam[1][2]*blues;

View File

@@ -72,14 +72,14 @@ class RawImageSource : public ImageSource {
MyMutex getImageMutex; // locks getImage
int W, H;
ColorTemp wb;
ColorTemp camera_wb;
ProgressListener* plistener;
float scale_mul[4]; // multiplier for each color
float c_black[4]; // copy of cblack Dcraw for black level
float cblacksom[4];
double camwb_red;
double camwb_green;
double camwb_blue;
double refwb_red;
double refwb_green;
double refwb_blue;
double rgb_cam[3][3];
double cam_rgb[3][3];
double xyz_cam[3][3];
@@ -153,7 +153,7 @@ class RawImageSource : public ImageSource {
void scaleColors (int winx,int winy,int winw,int winh, const RAWParams &raw);// raw for cblack
void getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw);
ColorTemp getWB () { return wb; }
ColorTemp getWB () { return camera_wb; }
void getAutoWBMultipliers (double &rm, double &gm, double &bm);
ColorTemp getSpotWB (std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, int tran, double equal);
bool isWBProviderReady () { return rawData; }
@@ -174,7 +174,7 @@ class RawImageSource : public ImageSource {
void getAutoExpHistogram (LUTu & histogram, int& histcompr);
void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw);
void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, RAWParams raw);
void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw);
//static void colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName);
static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, ColorTemp &wb, cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName) {
colorSpaceConversion (im, cmp, wb, 0.0f, embedded, camprofile, cam, camName);

View File

@@ -125,7 +125,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if (params.dirpyrDenoise.enabled) {
ipf.RGB_denoise(baseImg, baseImg, imgsrc->isRAW(), params.dirpyrDenoise, params.defringe, imgsrc->getDirPyrDenoiseExpComp());
}
imgsrc->convertColorSpace(baseImg, params.icm, params.raw);
imgsrc->convertColorSpace(baseImg, params.icm, currWB, params.raw);
// perform first analysis
LUTu hist16 (65536);

2
rtengine/stdimagesource.cc Normal file → Executable file
View File

@@ -211,7 +211,7 @@ void StdImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, Pre
image->vflip();
}
void StdImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, RAWParams raw) {
void StdImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw) {
colorSpaceConversion (image, cmp, embProfile, img->getSampleFormat());
}

View File

@@ -65,7 +65,7 @@ class StdImageSource : public ImageSource {
void setProgressListener (ProgressListener* pl) { plistener = pl; }
void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, RAWParams raw);// RAWParams raw will not be used for non-raw files (see imagesource.h)
void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb, RAWParams raw);// RAWParams raw will not be used for non-raw files (see imagesource.h)
static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat);
//static void colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded);