From 60b3341f3a540ca4b7668fdede8436d3b06c5c48 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 8 Sep 2015 07:14:59 +0200 Subject: [PATCH] GUI enhancement for DeHaze --- rtdata/languages/default | 4 ++ rtengine/dcrop.cc | 3 +- rtengine/imagesource.h | 4 +- rtengine/improccoordinator.cc | 10 ++-- rtengine/improccoordinator.h | 7 ++- rtengine/ipdehaz.cc | 46 +++++++++++++++-- rtengine/rawimagesource.cc | 4 +- rtengine/rawimagesource.h | 4 +- rtengine/rtengine.h | 9 ++++ rtengine/simpleprocess.cc | 4 +- rtgui/dehaz.cc | 97 ++++++++++++++++++++++++++++++++++- rtgui/dehaz.h | 20 +++++++- rtgui/toolpanelcoord.cc | 1 + 13 files changed, 192 insertions(+), 21 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 86962a8c0..c09a3f279 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1552,6 +1552,10 @@ TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones TP_LABCURVE_LCREDSK_TIP;If enabled, the LC Curve affects only red and skin-tones.\nIf disabled, it applies to all tones. TP_LABCURVE_RSTPROTECTION;Red and skin-tones protection TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve. +TP_DEHAZ_MLABEL;Restored haze-free Min=%1 Max=%2 +TP_DEHAZ_MLABEL_TOOLTIP;Should be near of min=0 max=32768\nRestored image with no mixture +TP_DEHAZ_TLABEL;TR m=%1 M=%2 Me=%3 Si=%4 Tm=%5 TM=%6 +TP_DEHAZ_TLABEL_TOOLTIP;Transmission map result\nm=Mini M=Maxi used by Variance\nMe=Mean Si=Sigma\nTm=Min TM=Max of Transmission map TP_DEHAZ_STR;Strength TP_DEHAZ_STR_TOOLTIP;Mixture in proportion to the original image and that obtained by Retinex algoritm TP_DEHAZ_RETIN;Complete Retinex algoritm diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index be7f76302..58a48abed 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -158,7 +158,7 @@ void Crop::update (int todo) int heiIm = parent->fh; bool needstransform = parent->ipf.needsTransform(); - + if (todo & (M_INIT | M_LINDENOISE)) { MyMutex::MyLock lock(parent->minit); // Also used in improccoord @@ -305,7 +305,6 @@ void Crop::update (int todo) if(parent->adnListener) { parent->adnListener->noiseTilePrev (centerTile_X[poscenterX], centerTile_Y[poscenterY], CenterPreview_X, CenterPreview_Y, crW, trafw * skip); } - // I have tried "blind" some solutions..to move review ...but GUI is not my truc ! // int W,H; // cropgl->cropMoved (centerTile_X[poscenterX],centerTile_Y[poscenterY] , W, H); diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index de4bdbe8d..cb8a36f7d 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -70,13 +70,13 @@ public: virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) {}; virtual void demosaic (const RAWParams &raw) {}; // virtual void // dehaz (RAWParams raw, ColorManagementParams cmp, DehazParams lcur, LUTf & cdcurve, bool dehacontlutili) {}; - virtual void dehaz (RAWParams raw, ColorManagementParams cmp, DehazParams deh, LUTf & cdcurve, const DehaztransmissionCurve & dehatransmissionCurve, bool dehacontlutili) {}; + virtual void dehaz (RAWParams raw, ColorManagementParams cmp, DehazParams deh, LUTf & cdcurve, const DehaztransmissionCurve & dehatransmissionCurve, bool dehacontlutili, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; virtual void flushRawData () {}; virtual void flushRGB () {}; virtual void HLRecovery_Global (ToneCurveParams hrp) {}; virtual void HLRecovery_inpaint (float** red, float** green, float** blue) {}; // virtual void MSR(LabImage* lab, int width, int height, int skip, DehazParams lcur) {}; - virtual void MSR(LabImage* lab, int width, int height, int skip, DehazParams deh, const DehaztransmissionCurve & dehatransmissionCurve) {}; + virtual void MSR(LabImage* lab, int width, int height, int skip, DehazParams deh, const DehaztransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; virtual bool IsrgbSourceModified() = 0; // tracks whether cached rgb output of demosaic has been modified // virtual void MSR(LabImage* lab, int width, int height, int skip, const LCurveParams &lcur); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 4c329c550..f2ab07155 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -86,7 +86,7 @@ ImProcCoordinator::ImProcCoordinator () bcurvehist(256), bcurvehistCropped(256), bbeforehist(256), fullw(1), fullh(1), pW(-1), pH(-1), - plistener(NULL), imageListener(NULL), aeListener(NULL), acListener(NULL), abwListener(NULL), actListener(NULL), adnListener(NULL), awavListener(NULL), hListener(NULL), + plistener(NULL), imageListener(NULL), aeListener(NULL), acListener(NULL), abwListener(NULL), actListener(NULL), adnListener(NULL), awavListener(NULL), dehaListener(NULL), hListener(NULL), resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false), utili(false), autili(false), wavcontlutili(false), butili(false), ccutili(false), cclutili(false), clcutili(false), opautili(false) @@ -240,9 +240,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CurveFactory::curveDehaContL (dehacontlutili, params.dehaz.cdcurve, cdcurve, 1); DehazParams DehaParams = params.dehaz; DehaParams.getCurves(dehatransmissionCurve); - imgsrc->dehaz( params.raw, params.icm, params.dehaz, cdcurve, dehatransmissionCurve, dehacontlutili);//enabled Dehaze + float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; + imgsrc->dehaz( params.raw, params.icm, params.dehaz, cdcurve, dehatransmissionCurve, dehacontlutili, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax);//enabled Dehaze + if(dehaListener) { + dehaListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); + } - } + } } // Updating toneCurve.hrenabled if necessary diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 0c2f8f459..9edefba80 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -154,7 +154,8 @@ protected: AutoColorTonListener* actListener; AutoChromaListener* adnListener; WaveletListener* awavListener; - + DehazListener* dehaListener; + HistogramListener* hListener; std::vector sizeListeners; @@ -299,6 +300,10 @@ public: { adnListener = adn; } + void setDehazListener (DehazListener* adh) + { + dehaListener = adh; + } void setWaveletListener (WaveletListener* awa) { awavListener = awa; diff --git a/rtengine/ipdehaz.cc b/rtengine/ipdehaz.cc index 6b922e503..357c672d2 100644 --- a/rtengine/ipdehaz.cc +++ b/rtengine/ipdehaz.cc @@ -16,10 +16,21 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . + * adaptation to Rawtherapee + * 2015 Jacques Desmis + * 2015 Ingo Weyrich + * D. J. Jobson, Z. Rahman, and G. A. Woodell. A multi-scale * Retinex for bridging the gap between color images and the * human observation of scenes. IEEE Transactions on Image Processing, * 1997, 6(7): 965-976 + + * Fan Guo Zixing Cai Bin Xie Jin Tang + * School of Information Science and Engineering, Central South University Changsha, China + + * Weixing Wang and Lian Xu + * College of Physics and Information Engineering, Fuzhou University, Fuzhou, China + * inspired from 2003 Fabien Pelisson */ @@ -187,12 +198,13 @@ void mean_stddv( float **dst, float &mean, float &stddv, int W_L, int H_L, const stddv = (float)sqrt(stddv); } -void RawImageSource::MSR(float** luminance, float** originalLuminance, int width, int height, DehazParams deh, const DehaztransmissionCurve & dehatransmissionCurve) +void RawImageSource::MSR(float** luminance, float** originalLuminance, int width, int height, DehazParams deh, const DehaztransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) { if (deh.enabled) {//enabled StopWatch Stop1("MSR"); float mean, stddv, maxtr, mintr; - float mini, delta, maxi; + // float mini, delta, maxi; + float delta; float eps = 2.f; float gain2 = (float) deh.gain / 100.f; //def =1 not use float offse = (float) deh.offs; //def = 0 not use @@ -426,17 +438,43 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, int width } float cdfactor = gain2 * 32768.f / delta; + maxCD =-9999999.f; + minCD =9999999.f; + #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel +#endif + { + float cdmax = -999999.f, cdmin = 999999.f; + +#ifdef _OPENMP + #pragma omp for #endif - for ( int i = 0; i < H_L; i ++ ) for (int j = 0; j < W_L; j++) { // float cd = cdfactor * ( luminance[i][j] * logBetaGain - mini ) + offse; float cd = cdfactor * ( luminance[i][j] - mini ) + offse; + if(cd > cdmax) cdmax=cd; + if(cd < cdmin) cdmin=cd; + + luminance[i][j] = clipdehaz( cd, 0.f, 32768.f ) * strength + (1.f - strength) * originalLuminance[i][j]; } +#ifdef _OPENMP + #pragma omp critical +#endif + { + maxCD = maxCD > cdmax ? maxCD : cdmax; + minCD = minCD < cdmin ? minCD : cdmin; + } + } + // printf("cdmin=%f cdmax=%f\n",minCD, maxCD); + Tmean = mean; + Tsigma = stddv; + Tmin = mintr; + Tmax = maxtr; + } } } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index c5a72e6dc..4f7d88fd7 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1800,7 +1800,7 @@ void RawImageSource::demosaic(const RAWParams &raw) } } -void RawImageSource::dehaz(RAWParams raw, ColorManagementParams cmp, DehazParams deh, LUTf & cdcurve, const DehaztransmissionCurve & dehatransmissionCurve, bool dehacontlutili) +void RawImageSource::dehaz(RAWParams raw, ColorManagementParams cmp, DehazParams deh, LUTf & cdcurve, const DehaztransmissionCurve & dehatransmissionCurve, bool dehacontlutili, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) { MyTime t4, t5; @@ -1863,7 +1863,7 @@ void RawImageSource::dehaz(RAWParams raw, ColorManagementParams cmp, DehazParams labdeha->b[i - border][j - border] = bb; } - MSR(labdeha->L, labTmp, WNew, HNew, deh, dehatransmissionCurve); + MSR(labdeha->L, labTmp, WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); delete [] labTmpBuffer; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 1fd858a17..d6bd3a6d3 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -152,7 +152,7 @@ public: void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse); void demosaic (const RAWParams &raw); // void dehaz (RAWParams raw, ColorManagementParams cmp, DehazParams lcur, LUTf & cdcurve, bool dehacontlutili); - void dehaz (RAWParams raw, ColorManagementParams cmp, DehazParams deh, LUTf & cdcurve, const DehaztransmissionCurve & dehatransmissionCurve, bool dehacontlutili); + void dehaz (RAWParams raw, ColorManagementParams cmp, DehazParams deh, LUTf & cdcurve, const DehaztransmissionCurve & dehatransmissionCurve, bool dehacontlutili, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); void flushRawData (); void flushRGB (); void HLRecovery_Global (ToneCurveParams hrp); @@ -228,7 +228,7 @@ public: void boxblur2(float** src, float** dst, int H, int W, int box ); void boxblur_resamp(float **src, float **dst, int H, int W, int box, int samp ); - void MSR(float** luminance, float **originalLuminance, int width, int height, DehazParams deh, const DehaztransmissionCurve & dehatransmissionCurve); + void MSR(float** luminance, float **originalLuminance, int width, int height, DehazParams deh, const DehaztransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); // void MSR(LabImage* lab, int width, int height, int skip, DehazParams deh, const DehaztransmissionCurve & dehatransmissionCurve); //void boxblur_resamp(float **red, float **green, float **blue, int H, int W, float thresh[3], float max[3], diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 6c727ac87..54d8d010b 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -287,6 +287,14 @@ public : }; +class DehazListener +{ +public : + virtual ~DehazListener() {} + virtual void minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) {} + +}; + class AutoColorTonListener { public : @@ -405,6 +413,7 @@ public: virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; virtual void setAutoChromaListener (AutoChromaListener* l) = 0; + virtual void setDehazListener (DehazListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; virtual ~StagedImageProcessor () {} diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index f86c1293b..d462b9ecc 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -124,8 +124,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p CurveFactory::curveDehaContL (dehacontlutili, params.dehaz.cdcurve, cdcurve, 1); DehazParams DehaParams = params.dehaz; DehaParams.getCurves(dehatransmissionCurve); - - imgsrc->dehaz( params.raw, params.icm, params.dehaz, cdcurve, dehatransmissionCurve, dehacontlutili ); + float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; + imgsrc->dehaz( params.raw, params.icm, params.dehaz, cdcurve, dehatransmissionCurve, dehacontlutili, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); } if (pl) { diff --git a/rtgui/dehaz.cc b/rtgui/dehaz.cc index 4c9d79d47..842e572a9 100644 --- a/rtgui/dehaz.cc +++ b/rtgui/dehaz.cc @@ -11,7 +11,15 @@ Dehaz::Dehaz () : FoldableToolPanel(this, "dehaz", M("TP_DEHAZ_LABEL"), false, t { CurveListener::setMulti(true); std::vector milestones; - + nextmin =0.; + nextmax =0.; + nextminiT = 0.; + nextmaxiT = 0.; + nextmeanT = 0.; + nextsigma = 0.; + nextminT = 0.; + nextmaxT = 0.; + dehazFrame = Gtk::manage (new Gtk::Frame (M("TP_DEHAZ_LAB")) ); dehazFrame->set_tooltip_text(M("TP_DEHAZ_LAB_TOOLTIP")); dehazFrame->set_border_width(0); @@ -86,7 +94,13 @@ Dehaz::Dehaz () : FoldableToolPanel(this, "dehaz", M("TP_DEHAZ_LABEL"), false, t dehazVBox->pack_start (*retinex); retinex->show (); + + mMLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + mMLabels->set_tooltip_markup (M("TP_DEHAZ_MLABEL_TOOLTIP")); + transLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + transLabels->set_tooltip_markup (M("TP_DEHAZ_TLABEL_TOOLTIP")); + scal = Gtk::manage (new Adjuster (M("TP_DEHAZ_SCAL"), 1, 8., 1., 3.)); gain = Gtk::manage (new Adjuster (M("TP_DEHAZ_GAIN"), 20, 200, 1, 100));//50 150 offs = Gtk::manage (new Adjuster (M("TP_DEHAZ_OFFS"), -10000, 10000, 1, 0)); @@ -102,6 +116,12 @@ Dehaz::Dehaz () : FoldableToolPanel(this, "dehaz", M("TP_DEHAZ_LABEL"), false, t medianmap->set_active (true); medianmapConn = medianmap->signal_toggled().connect( sigc::mem_fun(*this, &Dehaz::medianmapChanged) ); + RetiVBox->pack_start (*mMLabels); + mMLabels->show (); + + RetiVBox->pack_start (*transLabels); + transLabels->show (); + RetiVBox->pack_start (*curveEditorGD, Gtk::PACK_SHRINK, 4); curveEditorGD->show(); @@ -151,6 +171,77 @@ Dehaz::~Dehaz() delete transmissionCurveEditorG; } +int minmaxChangedUI (void* data) +{ + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->minmaxComputed_ (); + return 0; +} + +void Dehaz::minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax) +{ + nextmin = cdmin; + nextmax = cdma; + nextminiT = mini; + nextmaxiT = maxi; + nextmeanT = Tmean; + nextsigma = Tsigma; + nextminT = Tmin; + nextmaxT = Tmax; + g_idle_add (minmaxChangedUI, this); + +} + +bool Dehaz::minmaxComputed_ () +{ + + disableListener (); + enableListener (); + updateLabel (); + updateTrans (); + return false; + +} +void Dehaz::updateLabel () +{ + if (!batchMode) { + float nX, nY; + nX = nextmin; + nY = nextmax; + { + mMLabels->set_text( + Glib::ustring::compose(M("TP_DEHAZ_MLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), nX), + Glib::ustring::format(std::fixed, std::setprecision(0), nY)) + ); + } + } +} + +void Dehaz::updateTrans () +{ + if (!batchMode) { + float nm, nM, nZ, nA, nB, nS; + nm = nextminiT; + nM = nextmaxiT; + nZ = nextmeanT; + nA = nextminT; + nB = nextmaxT; + nS = nextsigma; + { + transLabels->set_text( + Glib::ustring::compose(M("TP_DEHAZ_TLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(1), nm), + Glib::ustring::format(std::fixed, std::setprecision(1), nM), + Glib::ustring::format(std::fixed, std::setprecision(1), nZ), + Glib::ustring::format(std::fixed, std::setprecision(1), nS), + Glib::ustring::format(std::fixed, std::setprecision(1), nA), + Glib::ustring::format(std::fixed, std::setprecision(1), nB)) + ); + } + } +} + void Dehaz::read (const ProcParams* pp, const ParamsEdited* pedited) @@ -235,6 +326,8 @@ void Dehaz::retinexUpdateUI () vart->show(); limd->show(); medianmap->show(); + mMLabels->show(); + transLabels->show(); transmissionCurveEditorG->show(); curveEditorGD->show(); dehazFrame->show(); @@ -244,6 +337,8 @@ void Dehaz::retinexUpdateUI () offs->hide(); vart->hide(); limd->hide(); + mMLabels->hide(); + transLabels->hide(); medianmap->hide(); transmissionCurveEditorG->hide(); curveEditorGD->hide(); diff --git a/rtgui/dehaz.h b/rtgui/dehaz.h index 86d6e134a..0f3b2f07e 100644 --- a/rtgui/dehaz.h +++ b/rtgui/dehaz.h @@ -13,8 +13,9 @@ #include "thresholdadjuster.h" #include "colorprovider.h" -class Dehaz : public ToolParamBlock, public FoldableToolPanel, public CurveListener, +class Dehaz : public ToolParamBlock, public FoldableToolPanel, public rtengine::DehazListener, public CurveListener, public AdjusterListener + { protected: @@ -33,7 +34,18 @@ protected: Gtk::CheckButton* retinex; Gtk::Frame* dehazFrame; Gtk::CheckButton* medianmap; - + double nextmin; + double nextmax; + double nextminiT; + double nextmaxiT; + double nextmeanT; + double nextminT; + double nextmaxT; + double nextsigma; + + Gtk::Label* mMLabels; + Gtk::Label* transLabels; + DiagonalCurveEditor* cdshape; CurveEditorGroup* transmissionCurveEditorG; sigc::connection dehazmetConn; @@ -55,6 +67,10 @@ public: void autoOpenCurve (); void retinexChanged (); void medianmapChanged (); + void minmaxChanged (double cdma, double cdmin, double mini, double maxi, double Tmean, double Tsigma, double Tmin, double Tmax); + bool minmaxComputed_ (); + void updateLabel (); + void updateTrans (); void enabledChanged (); void curveChanged (CurveEditor* ce); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 3436a9c4d..5d1615e03 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -478,6 +478,7 @@ void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool ipc->setAutoColorTonListener (colortoning); ipc->setAutoChromaListener (dirpyrdenoise); ipc->setWaveletListener (wavelet); + ipc->setDehazListener (dehaz); ipc->setSizeListener (crop); ipc->setSizeListener (resize);