From 69594682fa9ea13c647ff50b703b91dad41d83a5 Mon Sep 17 00:00:00 2001 From: jdc Date: Tue, 4 Jan 2011 07:35:04 +0100 Subject: [PATCH] exposure correction before interpolation see issue#441 --- rtdata/languages/default | 2 + rtengine/expo_before_b.cc | 111 +++++++++++++++++++++++++++++++++++++ rtengine/procparams.cc | 21 ++++++- rtengine/procparams.h | 3 + rtengine/rawimagesource.cc | 14 ++++- rtengine/rawimagesource.h | 2 + rtgui/paramsedited.cc | 5 ++ rtgui/paramsedited.h | 3 + rtgui/preprocess.cc | 34 ++++++++++++ rtgui/preprocess.h | 2 + 10 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 rtengine/expo_before_b.cc diff --git a/rtdata/languages/default b/rtdata/languages/default index 1680c21a2..5e434d81a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -451,6 +451,8 @@ PREFERENCES_DIRSOFTWARE;Installation directory PREFERENCES_DMETHOD;Method PREFERENCES_EDITORCMDLINE;Other command line PREFERENCES_EDITORLAYOUT;Editor Layout +PREFERENCES_EXPOS;Exposure before interpolation\n :correction (lin) +PREFERENCES_PRESER;Exposure before interpolation\n :preserve highlights (EV) PREFERENCES_EXTERNALEDITOR;External editor PREFERENCES_FALSECOLOR;False color suppression steps PREFERENCES_FBROWSEROPTS;File Browser Options diff --git a/rtengine/expo_before_b.cc b/rtengine/expo_before_b.cc new file mode 100644 index 000000000..a19329ece --- /dev/null +++ b/rtengine/expo_before_b.cc @@ -0,0 +1,111 @@ + +//////////////////////////////////////////////////////////////// +// +// //exposure correction before interpolation +// +// code dated: December 27, 2010 +// +// Expo_before.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +// Jacques Desmis +// use fast-demo(provisional) from Emil Martinec +// inspired from work Guillermo Luijk and Manuel LLorens(Perfectraw) +// I use OMP + // This function uses parameters: + // exposure (lineal): 2^(-8..0..8): currently 0.5 +3 + // preserve (log) : 0..8 : currently 0.1 1 + +//modi : 31/12/2010 +#define LIM(x,min,max) MAX(min,MIN(x,max)) +#define CLIPF(x) LIM(x,0.0,65535.0) + +void RawImageSource::exp_bef(float expos, float preser) { + double dt,dT2; + clock_t t1, t2,t3,t4,t5; + float Yp, exposure2, K, EV; +// float LUT[65536]; +float *LUT = new float[65536]; + int i; + int row,col; + int width=W, height=H; + + // I use with Dcraw FDD interpolate from Luis Sanz , very fast and good, one can change for another : here with Rawtherpee == fastdemo() from Emil Martinec + //t1 = clock(); + //float *img = new float[H*W];//to save configuration : with RT is it necessary ?? + unsigned short** imgd; + imgd = allocArray< unsigned short >(W,H);//with memcpy : faster than for (...) + for (int i=0; i(imgd, H);//free memory imgd + + //exposure correction inspired from G.Luijk + if(preser==0.0){ // protect highlights +#pragma omp parallel for shared(expos) + for(int row=0;row1){ + K=65535/expos*exp(-preser*log((double) 2)); + for(int j=0;j<=65535;j++) LUT[(int)j]=CLIPF(((65535-K*expos)/(65535-K)*(j-65535)+65535)/j); + +#pragma omp parallel for shared(expos) + for(int row=0;rowsetProgress (0.0); } - CA_correct_RT(raw.cared, raw.cablue); + CA_correct_RT(raw.cared, raw.cablue); } + + if ( raw.expos !=1 ) { // exposure + if (plistener) { + plistener->setProgressStr ("Exposure Correction..."); + plistener->setProgress (0.0); + } + exp_bef(raw.expos, raw.preser); + + } + t2.set(); if( settings->verbose ) printf("Preprocessing: %d µsec\n", t2.etime(t1)); @@ -3204,6 +3214,8 @@ void RawImageSource::dcb_demosaic(int iterations, int dcb_enhance) #include "CA_correct_RT.cc"//Emil's CA auto correction #include "cfa_linedn_RT.cc"//Emil's CA auto correction #include "green_equil_RT.cc"//Emil's green channel equilibration +#include "expo_before_b.cc"//Jacques's exposure before interpolation + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index faffd3b5c..20995f486 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -150,6 +150,8 @@ class RawImageSource : public ImageSource { int LinEqSolve( int nDim, float* pfMatr, float* pfVect, float* pfSolution);//Emil's CA auto correction void CA_correct_RT (double cared, double cablue); + void exp_bef (float expos, float preser);//exposi + int cfaCleanFromMap( BYTE* bitmapBads ); int findHotDeadPixel( BYTE *bpMap, float thresh); void ddct8x8s(int isgn, float **a); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 822512523..a5b92cffd 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -288,6 +288,9 @@ void ParamsEdited::initFrom (const std::vector raw.caCorrection = raw.caCorrection && p.raw.ca_autocorrect == other.raw.ca_autocorrect; raw.caRed = raw.caRed && p.raw.cared == other.raw.cared; raw.caBlue = raw.caBlue && p.raw.cablue == other.raw.cablue; + // raw.exCorrection = raw.exCorrection && p.raw.expos_correc == other.raw.expos_correc; + raw.exPos = raw.exPos && p.raw.expos == other.raw.expos; + raw.exPreser = raw.exPreser && p.raw.preser == other.raw.preser; //exposi raw.darkFrame = raw.darkFrame && p.raw.dark_frame == other.raw.dark_frame; raw.dfAuto = raw.dfAuto && p.raw.df_autoselect == other.raw.df_autoselect; raw.greenEq = raw.greenEq && p.raw.greenthresh == other.raw.greenthresh; @@ -434,6 +437,8 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (raw.caCorrection) toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect; if (raw.caRed) toEdit.raw.cared = mods.raw.cared; if (raw.caBlue) toEdit.raw.cablue = mods.raw.cablue; + if (raw.exPos) toEdit.raw.expos =mods.raw.expos; + if (raw.exPreser) toEdit.raw.preser =mods.raw.preser; if (raw.greenEq) toEdit.raw.greenthresh = mods.raw.greenthresh; if (raw.hotDeadPixel) toEdit.raw.hotdeadpix_filt= mods.raw.hotdeadpix_filt; if (raw.linenoise) toEdit.raw.linenoise = mods.raw.linenoise; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 2c77ab3fe..b0de09599 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -287,6 +287,9 @@ class RAWParamsEdited { bool linenoise; bool darkFrame; bool dfAuto; + bool exCorrection; + bool exPos; + bool exPreser; }; class ExifPairEdited { diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc index c07edb951..bac00850e 100644 --- a/rtgui/preprocess.cc +++ b/rtgui/preprocess.cc @@ -43,6 +43,14 @@ PreProcess::PreProcess () caBlue = Gtk::manage(new Adjuster (M("PREFERENCES_CABLUE"),-4.0,4.0,0.1,0)); caBlue->setAdjusterListener (this); caBlue->show(); +//exposi + exPos = Gtk::manage(new Adjuster (M("PREFERENCES_EXPOS"),0.2,4.0,0.1,1)); + exPos->setAdjusterListener (this); + exPos->show(); + exPreser = Gtk::manage(new Adjuster (M("PREFERENCES_PRESER"),0,2.5,0.1,0)); + exPreser->setAdjusterListener (this); + exPreser->show(); + hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_HOTDEADPIXFILT")))); @@ -62,6 +70,9 @@ PreProcess::PreProcess () pack_start( *caAutocorrect, Gtk::PACK_SHRINK, 4); pack_start( *caRed, Gtk::PACK_SHRINK, 4); pack_start( *caBlue, Gtk::PACK_SHRINK, 4); + pack_start( *exPos, Gtk::PACK_SHRINK, 4);//exposi + pack_start( *exPreser, Gtk::PACK_SHRINK, 4); + pack_start( *Gtk::manage (new Gtk::HSeparator())); pack_start( *lineDenoise, Gtk::PACK_SHRINK, 4); pack_start( *Gtk::manage (new Gtk::HSeparator())); @@ -87,6 +98,9 @@ void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEd caAutocorrect->set_inconsistent(!pedited->raw.caCorrection); caRed->setEditedState( pedited->raw.caRed ? Edited : UnEdited ); caBlue->setEditedState( pedited->raw.caBlue ? Edited : UnEdited ); + exPos->setEditedState( pedited->raw.exPos ? Edited : UnEdited ); + exPreser->setEditedState( pedited->raw.exPreser ? Edited : UnEdited ); + //exposi hotDeadPixel->set_inconsistent (!pedited->raw.hotDeadPixel); lineDenoise->setEditedState( pedited->raw.linenoise ? Edited : UnEdited ); greenEqThreshold->setEditedState( pedited->raw.greenEq ? Edited : UnEdited ); @@ -105,6 +119,8 @@ void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEd caAutocorrect->set_active(pp->raw.ca_autocorrect); caRed->setValue (pp->raw.cared); caBlue->setValue (pp->raw.cablue); + exPos->setValue (pp->raw.expos); + exPreser->setValue (pp->raw.preser);//exposi hotDeadPixel->set_active (pp->raw.hotdeadpix_filt); lineDenoise->setValue (pp->raw.linenoise); greenEqThreshold->setValue (pp->raw.greenthresh); @@ -126,6 +142,9 @@ void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedi pp->raw.ca_autocorrect = caAutocorrect->get_active(); pp->raw.cared = (double)caRed->getValue(); pp->raw.cablue = (double)caBlue->getValue(); + pp->raw.expos = (double)exPos->getValue(); + pp->raw.preser = (double)exPreser->getValue();//exposi + pp->raw.hotdeadpix_filt = hotDeadPixel->get_active(); pp->raw.linenoise = (int)lineDenoise->getValue(); pp->raw.greenthresh = (int)greenEqThreshold->getValue(); @@ -138,6 +157,10 @@ void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedi pedited->raw.caCorrection = !caAutocorrect->get_inconsistent(); pedited->raw.caRed = caRed->getEditedState (); pedited->raw.caBlue = caBlue->getEditedState (); + //pedited->raw.exCorrection = !caAutocorrect->get_inconsistent(); + pedited->raw.exPos = exPos->getEditedState (); + pedited->raw.exPreser = exPreser->getEditedState ();//exposi + pedited->raw.hotDeadPixel = !hotDeadPixel->get_inconsistent(); } } @@ -153,6 +176,8 @@ void PreProcess::setBatchMode(bool batchMode) ToolPanel::setBatchMode (batchMode); caRed->showEditedCB (); caBlue->showEditedCB (); + exPos->showEditedCB (); + exPreser->showEditedCB ();//exposi lineDenoise->showEditedCB (); greenEqThreshold->showEditedCB (); } @@ -162,16 +187,25 @@ void PreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, lineDenoise->setDefault( defParams->raw.linenoise); caRed->setDefault( defParams->raw.cared); caBlue->setDefault( defParams->raw.cablue); + exPos->setDefault( defParams->raw.expos); + exPreser->setDefault( defParams->raw.preser); + greenEqThreshold->setDefault (defParams->raw.greenthresh); if (pedited) { lineDenoise->setDefaultEditedState( pedited->raw.linenoise ? Edited : UnEdited); caRed->setDefaultEditedState( pedited->raw.caRed ? Edited : UnEdited); caBlue->setDefaultEditedState( pedited->raw.caBlue ? Edited : UnEdited); + exPos->setDefaultEditedState( pedited->raw.exPos ? Edited : UnEdited); + exPreser->setDefaultEditedState( pedited->raw.exPreser ? Edited : UnEdited); + greenEqThreshold->setDefaultEditedState(pedited->raw.greenEq ? Edited : UnEdited); }else{ lineDenoise->setDefaultEditedState( Irrelevant ); caRed->setDefaultEditedState( Irrelevant ); caBlue->setDefaultEditedState( Irrelevant ); + exPos->setDefaultEditedState( Irrelevant ); + exPreser->setDefaultEditedState( Irrelevant ); + greenEqThreshold->setDefaultEditedState(Irrelevant ); } } diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h index ec699e91f..af8a76244 100644 --- a/rtgui/preprocess.h +++ b/rtgui/preprocess.h @@ -37,6 +37,8 @@ class PreProcess : public Gtk::VBox, public AdjusterListener, public ToolPanel{ Adjuster* caRed; Adjuster* caBlue; + Adjuster* exPos; + Adjuster* exPreser; Adjuster* lineDenoise; Adjuster* greenEqThreshold; Gtk::CheckButton* caAutocorrect;