White balance auto temperature correlation - improve behavior with non raw files (#6903)

* Improve Itcwb with non-raw files

* Change pre-dev builds wbrefinement

* Change template in pre-dev

* Improvment improccordinator.cc

* Forgotten observer convert

* Reenable wbauto autogrey as 5.8

* Remove wrong code

* Missing getrgbloc references

* Fixed bug due to bias in queu with temperaure correlation issue 6911

* Simpleprocess queue compatibility tif-jpg

* Preserve AWB edits from 5.9

In 5.9 for non-raw files,
   1. RGB grey uses the unit multipliers with temperature bias applied.
   2. Temperature correlation uses the equivalent of temperature 5000,
      green 1, and red/blue equalizer 1.

* Refactor temperature correlation AWB code

* Fix inaccurate RGB grey WB preview after using ITC

The RGB grey automatic white balance algorithm caches the multipliers.
Temperature correlation automatic white balance also caches results to
the same location, but never uses it. This causes the RGB grey method to
produce incorrect results in the editor. Removing the temperature
correlation cache fixes the issue and does not have side-effects.

---------

Co-authored-by: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com>
This commit is contained in:
Desmis
2024-02-01 07:48:07 +01:00
committed by GitHub
parent ce80067380
commit e4087e2fa2
20 changed files with 561 additions and 468 deletions

View File

@@ -518,7 +518,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
}
}
const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen");
// const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen");
if (settings->verbose) {
printf("automethod=%s \n", params->wb.method.c_str());
@@ -534,6 +534,24 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
}
currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer);
int tempnotisraw = 6501;//D65 with Observer 2° - 6473 with Observer 10°
double greennotisraw = 1.;//D65 with Observer 2° - 0.967 with Observer 10°
if (!imgsrc->isRAW() && params->wb.method == "autitcgreen") {
if (params->wb.compat_version == 1) {
// ITCWB compatibility version 1 used 5000 K and observer 10
// degrees for non-raw files.
auto currWBitc = ColorTemp(5000., 1., 1., params->wb.method, StandardObserver::TEN_DEGREES);
currWBitc = currWBitc.convertObserver(params->wb.observer);
tempnotisraw = currWBitc.getTemp();
greennotisraw = currWBitc.getGreen();
} else {
auto currWBitc = imgsrc->getWB();//if jpg TIF with another illuminant
currWBitc = currWBitc.convertObserver(params->wb.observer);
tempnotisraw = currWBitc.getTemp();
greennotisraw = currWBitc.getGreen();
}
}
int dread = 0;
int bia = 1;
@@ -545,7 +563,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
int kmin = 20;
float minhist = 1000000000.f;
float maxhist = -1000.f;
double tempitc = 5000.f;
double greenitc = 1.;
float temp0 = 5000.f;
bool extra = false;
@@ -556,230 +573,21 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
} else if (params->wb.method == "Camera") {
currWB = imgsrc->getWB();
lastAwbauto = ""; //reinitialize auto
} else if (autowb) {
float tem = 5000.f;
float gre = 1.f;
double tempref0bias = 5000.;
tempitc = 5000.f;
bool autowb1 = true;
double green_thres = 0.8;
if (params->wb.method == "autitcgreen") {
currWBitc = imgsrc->getWB();
double greenref = currWBitc.getGreen();
double tempref0bias0 = currWBitc.getTemp();
if (greenref > green_thres && params->wb.itcwb_prim == "srgb") {
forcewbgrey = true;
}
if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88
if (settings->verbose) {
printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref);
}
autowb1 = true;
kcam = 1;
}
if (autowb1) {
//alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera
// kcam = 0;
params->wb.method = "autold";
double rm, gm, bm;
tempitc = 5000.f;
greenitc = 1.;
currWBitc = imgsrc->getWB();
tempref0bias = currWBitc.getTemp();
double greenref = currWBitc.getGreen();
bool pargref = true;
bool pargre = true;
if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params->wb.itcwb_sampling) { //probably camera out to adjust...
imgsrc->getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve);
imgsrc->wbMul2Camera(rm, gm, bm);
imgsrc->wbCamera2Mul(rm, gm, bm);
ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver());
tem = ct.getTemp();
gre = ct.getGreen();
if (gre > 1.3f) {
pargre = false;
}
if (greenref > 1.3f) {
pargref = false;
}
double deltemp = tem - tempref0bias;
if (gre > 1.5f && !forcewbgrey) { //probable wrong value
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value
gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out
} else {
if (!forcewbgrey) {
gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f);
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value
nocam = 0;
} else {//set temp and green to init itcwb algorithm
double grepro = LIM(greenref, green_thres, 1.15);
gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey
if (abs(deltemp) < 400.) { //arbitraries thresholds to refine
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey
if (deltemp > 0.) {
nocam = 1;
} else {
nocam = 2;
}
} else if (abs(deltemp) < 900.) { //other arbitrary threshold
tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey
if (deltemp > 0.) {
nocam = 3;
} else {
nocam = 4;
}
} else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) {
if ((pargre && pargref) || (!pargre && !pargref)) {
tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey
}
if (pargre && !pargref) {
tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey
}
if (!pargre && pargref) {
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey
}
nocam = 5;
} else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) {
if ((pargre && pargref) || (!pargre && !pargref)) {
tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey
}
if (pargre && !pargref) {
tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey
}
if (!pargre && pargref) {
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey
}
nocam = 6;
} else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) {
if (tem >= 4500.f) {
if ((pargre && pargref) || (!pargre && !pargref)) {
tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey
}
if (pargre && !pargref) {
tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey
}
if (!pargre && pargref) {
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey
}
nocam = 7;
} else {
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey
nocam = 8;
}
} else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) {
if (tem >= 10000.f) {
tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey
nocam = 9;
} else {
if ((pargre && pargref) || (!pargre && !pargref)) {
tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey
}
if (pargre && !pargref) {
tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey
}
if (!pargre && pargref) {
tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey
}
nocam = 10;
}
} else {
tem = 0.4 * tem + 0.6 * tempref0bias;
nocam = 11;
}
}
}
tempitc = tem ;
extra = true;
if (settings->verbose) {
printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam);
}
}
}
params->wb.method = "autitcgreen";
}
float greenitc_low = 1.f;
float tempitc_low = 5000.f;
if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) {
} else if (params->wb.method == "autold") {
if (lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) {
double rm, gm, bm;
greenitc = 1.;
currWBitc = imgsrc->getWB();
currWBitc = currWBitc.convertObserver(params->wb.observer);//change the temp/green couple with the same multipliers
double tempref = currWBitc.getTemp() * (1. + params->wb.tempBias);
double greenref = currWBitc.getGreen();
greenitc = greenref;
if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params->wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ?
tempref = tem * (1. + params->wb.tempBias);
greenref = gre;
if (params->wb.compat_version == 1 && !imgsrc->isRAW()) {
// RGB grey compatibility version 1 used the identity
// multipliers plus temperature bias for non-raw files.
rm = gm = bm = 1.;
} else {
}
if(params->wb.itcwb_sampling) {
greenitc_low = greenref;
tempitc_low = tempref;
}
if (settings->verbose && params->wb.method == "autitcgreen") {
printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc);
}
imgsrc->getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve);
if (params->wb.method == "autitcgreen") {
params->wb.temperature = tempitc;
params->wb.green = greenitc;
if(params->wb.itcwb_sampling) {
params->wb.temperature = tempitc_low;
params->wb.green = greenitc_low;
}
currWB = ColorTemp(params->wb.temperature, params->wb.green, 1., params->wb.method, params->wb.observer);
currWB.getMultipliers(rm, gm, bm);
autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, params->wb.tempBias);
imgsrc->getAutoWBMultipliers(rm, gm, bm);
}
if (rm != -1.) {
double bias = params->wb.tempBias;
if (params->wb.method == "autitcgreen") {
bias = 0.;
}
autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, bias);
lastAwbEqual = params->wb.equal;
lastAwbObserver = params->wb.observer;
@@ -791,6 +599,58 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
lastAwbTempBias = 0.0;
lastAwbauto = "";
autoWB.useDefaults(params->wb.equal, params->wb.observer);
}
//double rr,gg,bb;
//autoWB.getMultipliers(rr,gg,bb);
}
currWB = autoWB;
// lastAwbauto = ""; //reinitialize auto
} else if (params->wb.method == "autitcgreen") { //(// autowb) {
double rm;
double gm;
double bm;
imgsrc->getAutoWBMultipliersItcGreen(
*params,
forcewbgrey,
kcam,
greenitc,
extra,
temp0,
delta,
bia,
dread,
nocam,
studgood,
minchrom,
kmin,
minhist,
maxhist,
fh,
fw,
currWB,
tempnotisraw,
greennotisraw,
lastAwbEqual == params->wb.equal && lastAwbObserver == params->wb.observer && lastAwbTempBias == params->wb.tempBias && lastAwbauto == params->wb.method,
autoWB,
rm,
gm,
bm);
if (imgsrc->isRAW() || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) {
if (rm != -1.) {
autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer);
lastAwbEqual = params->wb.equal;
lastAwbObserver = params->wb.observer;
lastAwbTempBias = params->wb.tempBias;
lastAwbauto = params->wb.method;
} else {
lastAwbEqual = -1.;
lastAwbObserver = ColorTemp::DEFAULT_OBSERVER;
lastAwbTempBias = 0.0;
lastAwbauto = "";
autoWB.useDefaults(params->wb.equal, params->wb.observer);
}
}
@@ -822,12 +682,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
int met = 0;
if (awbListener) {
if (params->wb.method == "autitcgreen") {
if (awbListener && params->wb.enabled) {
if (params->wb.method == "autitcgreen" && imgsrc->isRAW()) {//Raw files
if (params->wb.itcwb_sampling) {
dread = 1;
studgood = 1.f;
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, 0, 1, 0, dread, studgood, 0, 0, 0, 0);
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, 0, 1, 0, dread, studgood, 0, 0, 0, 0, AutoWBListener::AWBMode::TEMP_CORRELATION_RAW);
} else {
minchrom = LIM(minchrom, 0.f, 0.9f);
@@ -836,10 +696,19 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
maxhist = std::max(maxhist, 1000.f);
kmin = std::max(kmin, 18);
dread = LIM(dread, 10, 239);
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, minhist, maxhist);
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, minhist, maxhist, AutoWBListener::AWBMode::TEMP_CORRELATION_RAW);
}
} else if (params->wb.method == "autitcgreen" && !imgsrc->isRAW()) {//non raw files
params->wb.temperature = tempnotisraw;
params->wb.green = greennotisraw;
currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer);
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::TEMP_CORRELATION_NON_RAW);//false => hide settings
} else if (params->wb.method == "autold"){
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::RGB_GREY);
} else {
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f);
awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::NONE);
}
}