From b3714b3181c439c55dfc6e13815afac89fbc256d Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 8 Jun 2019 18:56:43 +0200 Subject: [PATCH] Improve TM with normalize luminance - improve skip for Retinex --- rtdata/languages/default | 1 + rtengine/iplocallab.cc | 30 ++++++++++++++++++++++++++++++ rtengine/ipretinex.cc | 13 +++++++++---- rtengine/procevents.h | 1 + rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtengine/refreshmap.cc | 3 ++- rtgui/locallab.cc | 38 ++++++++++++++++++++++++++++++++++++++ rtgui/locallab.h | 5 +++++ rtgui/paramsedited.cc | 7 +++++++ rtgui/paramsedited.h | 1 + 11 files changed, 99 insertions(+), 5 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 8984d170e..ff72a0b4e 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -940,6 +940,7 @@ HISTORY_MSG_693;Local - Retinex threshold HISTORY_MSG_694;Local - Retinex Laplacian threshold HISTORY_MSG_695;Local - Soft method HISTORY_MSG_696;Local - Retinex Normalize +HISTORY_MSG_697;Local - TM Normalize HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 8929c7643..73adad551 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -236,6 +236,7 @@ struct local_params { bool invrad; bool invret; bool equret; + bool equtm; bool invshar; bool actsp; float str; @@ -580,6 +581,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall int local_sensisf = locallab.spots.at(sp).sensisf; bool inverseex = locallab.spots.at(sp).inversex; bool inversesh = locallab.spots.at(sp).inverssh; + bool equiltm = locallab.spots.at(sp).equiltm; bool equilret = locallab.spots.at(sp).equilret; bool inverserad = false; // Provision @@ -687,6 +689,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.invrad = inverserad; lp.invret = inverseret; lp.equret = equilret; + lp.equtm = equiltm; lp.invshar = inversesha; lp.str = str; lp.shrad = sharradius; @@ -2622,6 +2625,30 @@ void ImProcFunctions::transit_shapedetect(int senstype, const LabImage *bufexpor gaussianBlur(originalmask->b, origblurmask->b, bfw, bfh, radius); } } + + if(lp.equtm && senstype == 8) {//normalize luminance for Tone mapping + float *datain = new float[bfh * bfw]; + float *data = new float[bfh * bfw]; + +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = ystart; y < yend; y++) + for (int x = xstart; x < xend; x++) { + datain[(y - ystart) * bfw + (x - xstart)] = original->L[y][x]; + data[(y - ystart)* bfw + (x - xstart)] = bufexporig->L[y - ystart][x - xstart]; + } + normalize_mean_dt(data, datain, bfh * bfw); +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int y = ystart; y < yend; y++) + for (int x = xstart; x < xend; x++) { + bufexporig->L[y - ystart][x - xstart] = data[(y - ystart) * bfw + x - xstart]; + } + delete [] datain; + delete [] data; + } #ifdef _OPENMP #pragma omp parallel if (multiThread) @@ -5770,6 +5797,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o // itera = 5; } ImProcFunctions::EPDToneMaplocal(sp, bufgb.get(), tmp1.get(), itera, sk);//iterate to 0 calculate with edgstopping, improve result, call=1 dcrop we can put iterate to 5 + + + /* //to reactivate if we change transit_shapedetct parameters #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 84c8b80ef..71e2b2e33 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -887,12 +887,17 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b // scal // variance vart //not too bad proposition + float divsca = 1.f; + if(scal >=3) divsca = sqrt(scal / 3.f); + if (skip >= 4) { - nei = (int)(nei / (1.5f * skip) + 2.f)/ sqrt(scal / 3.f); - vart *= skip; + //nei = (int)(0.1f * nei + 2.f); //not too bad + nei = (int)(nei / (1.5f * skip))/ divsca; + vart *= sqrt(skip); } else if (skip > 1 && skip < 4) { - nei = (int)(nei / skip + 3.f) / sqrt(scal / 3.f); - vart *= skip; + //nei = (int)(0.3f * nei + 2.f); + nei = (int)(nei / skip) / divsca; + vart *= sqrt(skip); } int moderetinex = 0; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 65663ba5f..2e74f229a 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -723,6 +723,7 @@ enum ProcEventCode { Evlocallablaplace = 693, EvlocallabsoftMethod = 694, Evlocallabequilret = 695, + Evlocallabequiltm = 696, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index cfc7850b4..0e959e352 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2468,6 +2468,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : sensitm(19), softradiustm(0.0), amount(95.), + equiltm(true), // Retinex expreti(false), retinexMethod("high"), @@ -2684,6 +2685,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && sensitm == other.sensitm && softradiustm == other.softradiustm && amount == other.amount + && equiltm == other.equiltm // Retinex && expreti == other.expreti && retinexMethod == other.retinexMethod @@ -3859,6 +3861,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).CCmaskreticurve, "Locallab", "CCmaskretiCurve_" + std::to_string(i), spot.CCmaskreticurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).LLmaskreticurve, "Locallab", "LLmaskretiCurve_" + std::to_string(i), spot.LLmaskreticurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).HHmaskreticurve, "Locallab", "HHmaskretiCurve_" + std::to_string(i), spot.HHmaskreticurve, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).equiltm, "Locallab", "Equiltm_" + std::to_string(i), spot.equiltm, keyFile); // Retinex saveToKeyfile(!pedited || pedited->locallab.spots.at(i).expreti, "Locallab", "Expreti_" + std::to_string(i), spot.expreti, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).retinexMethod, "Locallab", "retinexMethod_" + std::to_string(i), spot.retinexMethod, keyFile); @@ -5169,6 +5172,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Sensitm_" + std::to_string(i), pedited, spot.sensitm, spotEdited.sensitm); assignFromKeyfile(keyFile, "Locallab", "Softradiustm_" + std::to_string(i), pedited, spot.softradiustm, spotEdited.softradiustm); assignFromKeyfile(keyFile, "Locallab", "Amount_" + std::to_string(i), pedited, spot.amount, spotEdited.amount); + assignFromKeyfile(keyFile, "Locallab", "Equiltm_" + std::to_string(i), pedited, spot.equiltm, spotEdited.equiltm); // Retinex assignFromKeyfile(keyFile, "Locallab", "Expreti_" + std::to_string(i), pedited, spot.expreti, spotEdited.expreti); assignFromKeyfile(keyFile, "Locallab", "retinexMethod_" + std::to_string(i), pedited, spot.retinexMethod, spotEdited.retinexMethod); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index f8267d7b9..2d50ab1e0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1069,6 +1069,7 @@ struct LocallabParams { int sensitm; double softradiustm; double amount; + bool equiltm; // Retinex bool expreti; Glib::ustring retinexMethod; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index ca346937a..e86043029 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -722,7 +722,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, //Evlocallablimd LUMINANCECURVE, //Evlocallablaplace LUMINANCECURVE, //EvlocallabsoftMethod - LUMINANCECURVE // Evlocallabequilret + LUMINANCECURVE, // Evlocallabequilret + LUMINANCECURVE // Evlocallabequiltm }; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index a19147b1b..4147a7c5b 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -224,6 +224,8 @@ Locallab::Locallab(): pastSatTog(Gtk::manage(new Gtk::CheckButton(M("TP_VIBRANCE_PASTSATTOG")))), // Blur & Noise activlum(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ACTIV")))), + //TM + equiltm(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_EQUIL")))), // Retinex equilret(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_EQUIL")))), inversret(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVERS")))), @@ -814,10 +816,12 @@ Locallab::Locallab(): softradiustm->setAdjusterListener(this); if(showtooltip) estop->set_tooltip_text(M("TP_LOCALLAB_TONEMAPESTOP_TOOLTIP")); if(showtooltip) rewei->set_tooltip_text(M("TP_LOCALLAB_TONEMAPESTOP_TOOLTIP")); + equiltmConn = equiltm->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::equiltmChanged)); ToolParamBlock* const tmBox = Gtk::manage(new ToolParamBlock()); // tmBox->pack_start(*amount);//to use if we change transit_shapedetect parameters tmBox->pack_start(*stren); + tmBox->pack_start(*equiltm); tmBox->pack_start(*gamma); tmBox->pack_start(*satur); tmBox->pack_start(*estop); @@ -2142,6 +2146,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).sensitm = sensitm->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).softradiustm = softradiustm->getValue(); pp->locallab.spots.at(pp->locallab.selspot).amount = amount->getValue(); + pp->locallab.spots.at(pp->locallab.selspot).equiltm = equiltm->get_active(); // Retinex pp->locallab.spots.at(pp->locallab.selspot).expreti = expreti->getEnabled(); @@ -2369,6 +2374,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).sensitm = pe->locallab.spots.at(pp->locallab.selspot).sensitm || sensitm->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).softradiustm = pe->locallab.spots.at(pp->locallab.selspot).softradiustm || softradiustm->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).amount = pe->locallab.spots.at(pp->locallab.selspot).amount || amount->getEditedState(); + pe->locallab.spots.at(pp->locallab.selspot).equiltm = pe->locallab.spots.at(pp->locallab.selspot).equiltm || !equiltm->get_inconsistent(); // Retinex pe->locallab.spots.at(pp->locallab.selspot).expreti = pe->locallab.spots.at(pp->locallab.selspot).expreti || !expreti->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).retinexMethod = pe->locallab.spots.at(pp->locallab.selspot).retinexMethod || retinexMethod->get_active_text() != M("GENERAL_UNCHANGED"); @@ -2591,6 +2597,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).amount = pedited->locallab.spots.at(pp->locallab.selspot).amount || amount->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).enaretiMask = pedited->locallab.spots.at(pp->locallab.selspot).enaretiMask || !enaretiMask->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).enaretiMasktmap = pedited->locallab.spots.at(pp->locallab.selspot).enaretiMasktmap || !enaretiMasktmap->get_inconsistent(); + pedited->locallab.spots.at(pp->locallab.selspot).equiltm = pedited->locallab.spots.at(pp->locallab.selspot).equiltm || !equiltm->get_inconsistent(); // Retinex pedited->locallab.spots.at(pp->locallab.selspot).expreti = pedited->locallab.spots.at(pp->locallab.selspot).expreti || !expreti->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).retinexMethod = pedited->locallab.spots.at(pp->locallab.selspot).retinexMethod || retinexMethod->get_active_text() != M("GENERAL_UNCHANGED"); @@ -3497,6 +3504,33 @@ void Locallab::inversshaChanged() } } +void Locallab::equiltmChanged() +{ + // printf("inversretChanged\n"); + + if (multiImage) { + if (equiltm->get_inconsistent()) { + equiltm->set_inconsistent(false); + equiltmConn.block(true); + equiltm->set_active(false); + equiltmConn.block(false); + } + } + + + if (getEnabled() && exptonemap->getEnabled()) { + if (listener) { + if (inversret->get_active()) { + listener->panelChanged(Evlocallabequiltm, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(Evlocallabequiltm, M("GENERAL_DISABLED")); + } + } + } +} + + + void Locallab::equilretChanged() { // printf("inversretChanged\n"); @@ -5167,6 +5201,7 @@ void Locallab::enableListener() activlumConn.block(false); // Tone Mapping enabletonemapConn.block(false); + equiltmConn.block(false); // Retinex enableretiConn.block(false); retinexMethodConn.block(false); @@ -5225,6 +5260,7 @@ void Locallab::disableListener() activlumConn.block(true); // Tone Mapping enabletonemapConn.block(true); + equiltmConn.block(true); // Retinex enableretiConn.block(true); retinexMethodConn.block(true); @@ -5395,6 +5431,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con sensitm->setValue(pp->locallab.spots.at(index).sensitm); softradiustm->setValue(pp->locallab.spots.at(index).softradiustm); amount->setValue(pp->locallab.spots.at(index).amount); + equiltm->set_active(pp->locallab.spots.at(index).equiltm); // Retinex expreti->setEnabled(pp->locallab.spots.at(index).expreti); @@ -5653,6 +5690,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con sensitm->setEditedState(spotState->sensitm ? Edited : UnEdited); softradiustm->setEditedState(spotState->softradiustm ? Edited : UnEdited); amount->setEditedState(spotState->amount ? Edited : UnEdited); + equiltm->set_inconsistent(multiImage && !spotState->equiltm); // Retinex expreti->set_inconsistent(!spotState->expreti); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index 9204babfb..f1b2c7601 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -260,6 +260,9 @@ private: // Blur & Noise Gtk::CheckButton* const activlum; sigc::connection activlumConn; + //Tone mapping + Gtk::CheckButton* const equiltm; + sigc::connection equiltmConn; // Retinex Gtk::CheckButton* const equilret; sigc::connection equilretConn; @@ -355,6 +358,8 @@ private: void pastsattog_toggled(); // Blur & Noise void activlumChanged(); + //TM + void equiltmChanged(); // Retinex void equilretChanged(); void inversretChanged(); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 44c8a0e9a..cfd75f93c 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1058,6 +1058,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).sensitm = locallab.spots.at(j).sensitm && pSpot.sensitm == otherSpot.sensitm; locallab.spots.at(j).softradiustm = locallab.spots.at(j).softradiustm && pSpot.softradiustm == otherSpot.softradiustm; locallab.spots.at(j).amount = locallab.spots.at(j).amount && pSpot.amount == otherSpot.amount; + locallab.spots.at(j).equiltm = locallab.spots.at(j).equiltm && pSpot.equiltm == otherSpot.equiltm; // Retinex locallab.spots.at(j).expreti = locallab.spots.at(j).expreti && pSpot.expreti == otherSpot.expreti; locallab.spots.at(j).retinexMethod = locallab.spots.at(j).retinexMethod && pSpot.retinexMethod == otherSpot.retinexMethod; @@ -3036,6 +3037,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).gamma = mods.locallab.spots.at(i).gamma; } + if (locallab.spots.at(i).equiltm) { + toEdit.locallab.spots.at(i).equiltm = mods.locallab.spots.at(i).equiltm; + } + if (locallab.spots.at(i).estop) { toEdit.locallab.spots.at(i).estop = mods.locallab.spots.at(i).estop; } @@ -4431,6 +4436,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : sensitm(v), softradiustm(v), amount(v), + equiltm(v), // Retinex expreti(v), retinexMethod(v), @@ -4644,6 +4650,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) sensitm = v; softradiustm = v; amount = v; + equiltm = v; // Retinex expreti = v; retinexMethod = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3af85e2cc..712cea64c 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -485,6 +485,7 @@ public: bool sensitm; bool softradiustm; bool amount; + bool equiltm; // Retinex bool expreti; bool retinexMethod;