From b95bdb1aea7ef0de3378b06ca46da6b3c2d0e8be Mon Sep 17 00:00:00 2001 From: rom9 <4711834+rom9@users.noreply.github.com> Date: Mon, 10 Jun 2019 22:05:54 +0200 Subject: [PATCH] Linked red and blue exponent adjuster to the green adjuster, in order to maintain the ratio between exponents if the user moves the green adjuster (master). Switched back to vector sort for median calculations: the results of the histogram search function diverge more and more from the simple median calculation as the exponents increase. At 2.0 the test picture is already impossible to WB as the multipliers are too far off (2.78226e+08 histo vs 9.7927e+11 sort), and the normal WB sliders can't compensate for those huge factors. --- rtengine/filmnegativeproc.cc | 25 ++++++++++++++----------- rtgui/filmnegative.cc | 24 ++++++++++++++++++++---- rtgui/filmnegative.h | 2 ++ 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/rtengine/filmnegativeproc.cc b/rtengine/filmnegativeproc.cc index 64f7a697b..948e86957 100644 --- a/rtengine/filmnegativeproc.cc +++ b/rtengine/filmnegativeproc.cc @@ -104,8 +104,8 @@ bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int std::swap(clearVals, denseVals); if (settings->verbose) { - printf("Clear film values: R=%f G=%f B=%f\n", clearVals[0], clearVals[1], clearVals[2]); - printf("Dense film values: R=%f G=%f B=%f\n", denseVals[0], denseVals[1], denseVals[2]); + printf("Clear film values: R=%g G=%g B=%g\n", clearVals[0], clearVals[1], clearVals[2]); + printf("Dense film values: R=%g G=%g B=%g\n", denseVals[0], denseVals[1], denseVals[2]); } float denseGreenRatio = clearVals[1] / denseVals[1]; @@ -119,7 +119,7 @@ bool RawImageSource::getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int newExps[ch] = CLAMP(logBase(clearVals[ch] / denseVals[ch], denseGreenRatio), 0.3f, 3.f); if (settings->verbose) - printf("New exponents: R=%f G=%f B=%f\n", newExps[0], newExps[1], newExps[2]); + printf("New exponents: R=%g G=%g B=%g\n", newExps[0], newExps[1], newExps[2]); return true; } @@ -230,20 +230,23 @@ void RawImageSource::filmNegativeProcess(const procparams::FilmNegativeParams &p float mults[3] = { 1.f }; // Channel normalization multipliers for (int c=0; c<3; c++) { - // Find median values for each channel using a histogram search function - findMinMaxPercentile(&cvs[c][0], cvs[c].size(), 0.5f, medians[c], 0.5f, medians[c], true); - // Determine the channel multipler so that N times the median becomes 65k. This clips away - // the values in the dark border surrounding the negative (due to the film holder, for example), - // the reciprocal of which have blown up to stellar values. - mults[c] = MAX_OUT_VALUE / (medians[c] * 24); + // Find median values for each channel + if(cvs[c].size() > 0) { + std::sort(cvs[c].begin(), cvs[c].end()); + medians[c] = cvs[c].at(cvs[c].size() / 2); + // Determine the channel multipler so that N times the median becomes 65k. This clips away + // the values in the dark border surrounding the negative (due to the film holder, for example), + // the reciprocal of which have blown up to stellar values. + mults[c] = MAX_OUT_VALUE / (medians[c] * 24); + } } t4.set(); if (settings->verbose) { printf("Sample count : %lu, %lu, %lu\n", cvs[0].size(), cvs[1].size(), cvs[2].size()); - printf("Medians : %f %f %f\n", medians[0], medians[1], medians[2] ); - printf("Computed multipliers : %f %f %f\n", mults[0], mults[1], mults[2] ); + printf("Medians : %g %g %g\n", medians[0], medians[1], medians[2] ); + printf("Computed multipliers : %g %g %g\n", mults[0], mults[1], mults[2] ); printf("Median calc time us: %d\n", t4.etime(t3)); } diff --git a/rtgui/filmnegative.cc b/rtgui/filmnegative.cc index bf4c22837..94c6db4dd 100644 --- a/rtgui/filmnegative.cc +++ b/rtgui/filmnegative.cc @@ -34,7 +34,7 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI { auto mkExponentAdjuster = [this](Glib::ustring label, double defaultVal) { - Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 3, 0.01, defaultVal)); //exponent + Adjuster *adj = Gtk::manage(new Adjuster (label, 0.3, 5, 0.001, defaultVal)); //exponent adj->setAdjusterListener (this); if (adj->delay < options.adjusterMaxDelay) { @@ -49,6 +49,9 @@ FilmNegative::FilmNegative () : FoldableToolPanel(this, "filmnegative", M("TP_FI greenExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_GREEN"), 1.0); blueExp = mkExponentAdjuster(M("TP_FILMNEGATIVE_BLUE"), 0.86); + redRatio = redExp->getValue() / greenExp->getValue(); + blueRatio = blueExp->getValue() / greenExp->getValue(); + auto m = ProcEventMapper::getInstance(); EvFilmNegativeEnabled = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_ENABLED"); EvFilmNegativeExponents = m->newEvent(ALL, "HISTORY_MSG_FILMNEGATIVE_EXPONENTS"); @@ -139,10 +142,23 @@ void FilmNegative::enabledChanged() void FilmNegative::adjusterChanged(Adjuster* a, double newval) { - if (listener && getEnabled()) { + if (listener) { if(a == redExp || a == greenExp || a == blueExp) { - listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( - "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); + disableListener(); + if(a == greenExp) { + redExp->setValue(a->getValue() * redRatio); + blueExp->setValue(a->getValue() * blueRatio); + } else if(a == redExp) { + redRatio = newval / greenExp->getValue(); + } else if(a == blueExp) { + blueRatio = newval / greenExp->getValue(); + } + enableListener(); + + if(getEnabled()) { + listener->panelChanged (EvFilmNegativeExponents, Glib::ustring::compose ( + "R=%1 ; G=%2 ; B=%3", redExp->getTextValue(), greenExp->getTextValue(), blueExp->getTextValue())); + } } } } diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index 614e60fb5..5d6c8ce03 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -54,6 +54,8 @@ private: Gtk::ToggleButton* spotbutton; sigc::connection spotConn; + double redRatio, blueRatio; + void editToggled (); public: