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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, ¶ms, 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);
|
||||
|
||||
@@ -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
2
rtengine/rawimage.h
Normal file → Executable 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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
2
rtengine/stdimagesource.cc
Normal file → Executable 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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user