From d6ae1339242d4423cfa1f1036402f376f6b47aa0 Mon Sep 17 00:00:00 2001 From: Emil Martinec Date: Thu, 24 Jun 2010 11:29:52 -0500 Subject: [PATCH] Green channel equilibration algorithm, for cameras such as Olympus, Panasonic, Canon 7D, etc that have different properties for the G1/G2 channels of the Bayer color filter array. In addition, minor changes to line denoise and CA_correct. --- rtdata/languages/English (UK) | 2 + rtdata/languages/English (US) | 2 + rtengine/CA_correct_RT.cc | 16 ++- rtengine/cfa_linedn_RT.cc | 84 ++++++++------ rtengine/green_equil_RT.cc | 211 ++++++++++++++++++++++++++++++++++ rtengine/rawimagesource.cc | 19 ++- rtengine/rawimagesource.h | 3 + rtengine/settings.h | 1 + rtgui/options.cc | 7 +- rtgui/preferences.cc | 15 +++ rtgui/preferences.h | 2 + 11 files changed, 311 insertions(+), 51 deletions(-) create mode 100644 rtengine/green_equil_RT.cc diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index bb3deb741..490a93762 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -369,6 +369,8 @@ PREFERENCES_CACORRECTION;Apply CA auto correction PREFERENCES_HOTDEADPIXFILT;Apply hot/dead pixel filter #Emil's line noise filter PREFERENCES_LINEDENOISE;Line noise filter +PREFERENCES_GREENEQUIL;Green equilibration + PREFERENCES_DEFAULTLANG;Default language PREFERENCES_DEFAULTTHEME;Default theme PREFERENCES_DEMOSAICINGALGO;Demosaicing Algorithm diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 2c9210fc5..c72716aab 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -371,6 +371,8 @@ PREFERENCES_CACORRECTION;Apply CA auto correction PREFERENCES_HOTDEADPIXFILT;Apply hot/dead pixel filter #Emil's line noise filter PREFERENCES_LINEDENOISE;Line noise filter +PREFERENCES_GREENEQUIL;Green equilibration + PREFERENCES_DEFAULTLANG;Default language PREFERENCES_DEFAULTTHEME;Default theme PREFERENCES_DEMOSAICINGALGO;Demosaicing Algorithm diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index fa1544684..f86f7dc80 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -320,10 +320,10 @@ void RawImageSource::CA_correct_RT() { for (cc=4+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-4; cc+=2, indx+=2) { - rbhpfv[indx] = fabs(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+v4][1]-rgb[indx+v4][c])) + \ + rbhpfv[indx] = SQR(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+v4][1]-rgb[indx+v4][c])) + \ fabs((rgb[indx-v4][1]-rgb[indx-v4][c])-(rgb[indx][1]-rgb[indx][c])) - \ fabs((rgb[indx-v4][1]-rgb[indx-v4][c])-(rgb[indx+v4][1]-rgb[indx+v4][c]))); - rbhpfh[indx] = fabs(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+4][1]-rgb[indx+4][c])) + \ + rbhpfh[indx] = SQR(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+4][1]-rgb[indx+4][c])) + \ fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx][1]-rgb[indx][c])) - \ fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx+4][1]-rgb[indx+4][c]))); @@ -358,7 +358,7 @@ void RawImageSource::CA_correct_RT() { gdiff=0.3125*(rgb[indx+TS][1]-rgb[indx-TS][1])+0.09375*(rgb[indx+TS+1][1]-rgb[indx-TS+1][1]+rgb[indx+TS-1][1]-rgb[indx-TS-1][1]); deltgrb=(rgb[indx][c]-rgb[indx][1]); - gradwt=fabs(0.25*rbhpfv[indx]+0.125*(rbhpfv[indx+2]+rbhpfv[indx-2]) )*(grblpfv[indx-v2]+grblpfv[indx+v2])/(eps+0.1*grblpfv[indx-v2]+rblpfv[indx-v2]+0.1*grblpfv[indx+v2]+rblpfv[indx+v2]); + gradwt=fabs(0.25*rbhpfv[indx]+0.125*(rbhpfv[indx+2]+rbhpfv[indx-2]) );//*(grblpfv[indx-v2]+grblpfv[indx+v2])/(eps+0.1*grblpfv[indx-v2]+rblpfv[indx-v2]+0.1*grblpfv[indx+v2]+rblpfv[indx+v2]); coeff[0][0][c] += gradwt*deltgrb*deltgrb; coeff[0][1][c] += gradwt*gdiff*deltgrb; @@ -370,7 +370,7 @@ void RawImageSource::CA_correct_RT() { gdiff=0.3125*(rgb[indx+1][1]-rgb[indx-1][1])+0.09375*(rgb[indx+1+TS][1]-rgb[indx-1+TS][1]+rgb[indx+1-TS][1]-rgb[indx-1-TS][1]); deltgrb=(rgb[indx][c]-rgb[indx][1]); - gradwt=fabs(0.25*rbhpfh[indx]+0.125*(rbhpfh[indx+v2]+rbhpfh[indx-v2]) )*(grblpfh[indx-2]+grblpfh[indx+2])/(eps+0.1*grblpfh[indx-2]+rblpfh[indx-2]+0.1*grblpfh[indx+2]+rblpfh[indx+2]); + gradwt=fabs(0.25*rbhpfh[indx]+0.125*(rbhpfh[indx+v2]+rbhpfh[indx-v2]) );//*(grblpfh[indx-2]+grblpfh[indx+2])/(eps+0.1*grblpfh[indx-2]+rblpfh[indx-2]+0.1*grblpfh[indx+2]+rblpfh[indx+2]); coeff[1][0][c] += gradwt*deltgrb*deltgrb; coeff[1][1][c] += gradwt*gdiff*deltgrb; @@ -502,7 +502,7 @@ void RawImageSource::CA_correct_RT() { //if (verbose) fprintf (stderr,_("tile vshift hshift (%d %d %4f %4f)...\n"),vblock, hblock, blockshifts[(vblock)*hblsz+hblock][c][0], blockshifts[(vblock)*hblsz+hblock][c][1]); - //now prepare coefficient matrix + //now prepare coefficient matrix; use only data points within two std devs of zero if (SQR(blockshifts[(vblock)*hblsz+hblock][c][0])>4.0*blockvar[0][c] || SQR(blockshifts[(vblock)*hblsz+hblock][c][1])>4.0*blockvar[1][c]) continue; numblox[c] += 1; for (dir=0; dir<2; dir++) { @@ -520,13 +520,11 @@ void RawImageSource::CA_correct_RT() { }//blocks numblox[1]=MIN(numblox[0],numblox[2]); - //if (numblox[1]<72) { - // polyord=4; numpar=16; + //if too few data points, restrict the order of the fit to linear if (numblox[1]<32) { polyord=2; numpar=4; if (numblox[1]< 10) return; } - //} //fit parameters to blockshifts for (c=0; c<3; c+=2) @@ -536,7 +534,7 @@ void RawImageSource::CA_correct_RT() { for (i=0; idata[row][col]; + for (rr=top; rr < top+numrows; rr++) + for (cc=left, indx=(rr-top)*TS; cc < left+numcols; cc++, indx++) { + cfain[indx] = ri->data[rr][cc]; } //pad the block to a multiple of 16 on both sides - if (cc1 < TS) { - indx=cc1 % 16; + if (numcols < TS) { + indx=numcols % 16; for (i=0; i<(16-indx); i++) - for (rr=0; rrdata[row][col] = CLIP((int)(cfadn[indx]+ 0.5)); } + } if(plistener) plistener->setProgress(fabs((float)top/height)); } // clean up - free(buffer); + //free(buffer); // done /*t2 = clock(); diff --git a/rtengine/green_equil_RT.cc b/rtengine/green_equil_RT.cc new file mode 100644 index 000000000..b64999db6 --- /dev/null +++ b/rtengine/green_equil_RT.cc @@ -0,0 +1,211 @@ +// CFA pixel cleaning via directional average +// by Emil Martinec +// 2/18/2010 +#define TS 256 // Tile size + +#define CLASS +/*#define ushort UshORt + typedef unsigned char uchar; + typedef unsigned short ushort;*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SQR(x) ((x)*(x)) + + +//void CLASS green_equilibrate()//for dcraw implementation +void CLASS RawImageSource::green_equilibrate(float thresh) +{ + // local variables + static const int border=8; + static const int border2=16; + static const int v1=TS, v2=2*TS, v3=3*TS, /*v4=4*TS,*/ p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3; + + int height=H, width=W; //for RT only + int top, left; + + int verbose=1; + + static const float eps=1.0; //tolerance to avoid dividing by zero + //static const float thresh=0.03; //threshold for performing green equilibration; max percentage difference of G1 vs G2 + // G1-G2 differences larger than this will be assumed to be Nyquist texture, and left untouched + static const float diffthresh=0.25; //threshold for texture, not to be equilibrated + + /*double dt; + clock_t t1, t2; + + //clock_t t1_main, t2_main = 0; + + // start + if (verbose) fprintf (stderr,_("Green equilibration ...\n")); + t1 = clock();*/ + + + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // Fill G interpolated values with border interpolation and input values + // Main algorithm: Tile loop +//#pragma omp parallel for shared(image,height,width) private(top,left) schedule(dynamic) + + for (top=0; top < height-border; top += TS-border2) + for (left=0; left < width-border; left += TS-border2) { + int bottom = MIN( top+TS,height); + int right = MIN(left+TS, width); + int numrows = bottom - top; + int numcols = right - left; + + int row, col; + int rr, cc, c, indx; + int vote1, vote2; + + float val1; + + float gin, gse, gsw, gne, gnw, wtse, wtsw, wtne, wtnw; + float gu, gd, gl, gr; + float mcorr, pcorr; + float ginterp; + float diffvarh, diffvarv, hvwt; + + char *buffer; // TS*TS*16 + float (*cfa); // TS*TS*4 + float (*checker); // TS*TS*4 + float (*gvar); // TS*TS*4 + float (*gdiffv); // TS*TS*4 + float (*gdiffh); // TS*TS*4 + + /* assign working space */ + buffer = (char *) malloc(5*sizeof(float)*TS*TS); + //merror(buffer,"green_equil()"); + memset(buffer,0,5*sizeof(float)*TS*TS); + + cfa = (float (*)) buffer; + checker = (float (*)) (buffer + sizeof(float)*TS*TS); + gvar = (float (*)) (buffer + 2*sizeof(float)*TS*TS); + gdiffv = (float (*)) (buffer + 3*sizeof(float)*TS*TS); + gdiffh = (float (*)) (buffer + 4*sizeof(float)*TS*TS); + + /*float cfa[TS*TS]; + float checker[TS*TS]; //this memory allocation crashes RT + float gvar[TS*TS]; + + memset( (void *)&cfa[0], 0 ,sizeof(cfa) );*/ + + // rgb from input CFA data + /* rgb values should be floating point number between 0 and 1 + after white balance multipliers are applied */ + for (rr=0; rr < numrows; rr++) + for (row=rr+top, cc=0; cc < numcols; cc++) { + col = cc+left; + //cfa[rr*TS+cc] = image[row*width+col][FC(row,col)];//for dcraw implementation + cfa[rr*TS+cc] = ri->data[row][col]; + + } + + //The green equilibration algorithm starts here + + for (rr=2; rr < numrows-2; rr++) + //for (cc=3-(FC(rr,2)&1), indx=rr*TS+cc; cc < numcols-2; cc+=2, indx+=2) { + for (indx=rr*TS+2; indx < rr*TS+numcols-2; indx++) { + + if (FC(rr,indx)&1) { + pcorr = (cfa[indx+p1]-cfa[indx])*(cfa[indx-p1]-cfa[indx]); + mcorr = (cfa[indx+m1]-cfa[indx])*(cfa[indx-m1]-cfa[indx]); + + if (pcorr>0 && mcorr>0) {checker[indx]=1;} else {checker[indx]=0;} + + //checker[indx]=1;//test what happens if we always interpolate + } else { + gu=cfa[indx-v1]+0.5*(cfa[indx]-cfa[indx-v2]); + gd=cfa[indx+v1]+0.5*(cfa[indx]-cfa[indx+v2]); + gl=cfa[indx-1]+0.5*(cfa[indx]-cfa[indx-2]); + gr=cfa[indx+1]+0.5*(cfa[indx]-cfa[indx+2]); + + gdiffh[indx] = SQR((gl-gr)/(eps+gl+gr)); + gdiffv[indx] = SQR((gu-gd)/(eps+gu+gd)); + + //gvar[indx] = 0.25*(gu*gu+gd*gd+gl*gl+gr*gr)-SQR(0.25*(gu+gd+gl+gr)); + } + } + + + + //now smooth the cfa data + for (rr=6; rr < numrows-6; rr++) + for (cc=7-(FC(rr,2)&1), indx=rr*TS+cc; cc < numcols-6; cc+=2, indx+=2) { + if (checker[indx]) { + + diffvarh = eps+(gdiffh[indx-v1]+gdiffh[indx-1]+gdiffh[indx+1]+gdiffh[indx+v1]); + diffvarv = eps+(gdiffv[indx-v1]+gdiffv[indx-1]+gdiffv[indx+1]+gdiffv[indx+v1]); + hvwt = fabs(diffvarv-diffvarh)/(diffvarv+diffvarh); + + + vote1=(checker[indx-v2]+checker[indx-2]+checker[indx+2]+checker[indx+v2]); + vote2=(checker[indx-m1]+checker[indx+p1]+checker[indx-p1]+checker[indx+m1]); + if (vote1>0 && vote2>0 && hvwt 0.125*(gvar[indx-1]+gvar[indx+1]+gvar[indx-v1]+gvar[indx+v1])) &&*/ ((ginterp-gin) < thresh*(ginterp+gin)) ) { + cfa[indx]=0.5*(ginterp+gin); + } + + } + } + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // copy smoothed results back to image matrix + for (rr=border; rr < numrows-border; rr++) + for (row=rr+top, cc=border+1-(FC(rr,2)&1), indx=rr*TS+cc; cc < numcols-border; cc+=2, indx+=2) { + if (cfa[indx]<1) continue; + col = cc + left; + //c = FC(row,col); + //image[row*width + col][c] = CLIP((int)(cfa[indx] + 0.5)); //for dcraw implementation + ri->data[row][col] = CLIP((int)(cfa[indx] + 0.5)); + } + + // clean up + free(buffer); + + } + + + // done + /*t2 = clock(); + dt = ((double)(t2-t1)) / CLOCKS_PER_SEC; + if (verbose) { + fprintf(stderr,_("elapsed time = %5.3fs\n"),dt); + }*/ + + +} +#undef TS diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 216ec0a1e..539c37a76 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -777,7 +777,7 @@ int RawImageSource::load (Glib::ustring fname) { idata = new ImageData (fname, &rml); // check if it is an olympus E camera, if yes, compute G channel pre-compensation factors - if (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,7)=="Panasonic")) && settings->demosaicMethod!="vng4" && ri->filters) { + if (settings->greenthresh || (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,7)=="Panasonic")) && settings->demosaicMethod!="vng4" && ri->filters) ) { // global correction int ng1=0, ng2=0; double avgg1=0, avgg2=0; @@ -799,8 +799,18 @@ int RawImageSource::load (Glib::ustring fname) { for (int j=border; jdata[i][j] = CLIP(ri->data[i][j] * (i%2 ? corrg2 : corrg1)); + } + + + // local correction in a 9x9 box + if (settings->greenthresh) { +//Emil's green equilbration + if (plistener) { + plistener->setProgressStr ("Green equilibrate..."); + plistener->setProgress (0.0); + } + green_equilibrate(0.01*(settings->greenthresh)); - // local correction in a 9x9 box /* unsigned short* corr_alloc = new unsigned short[W*H]; unsigned short** corr_data = new unsigned short* [H]; for (int i=0; iallocation, corr_alloc, W*H*sizeof(unsigned short)); delete corr_alloc; - delete corr_data; -*/ + delete corr_data; */ + } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -3222,6 +3232,7 @@ void RawImageSource::dcb_demosaic(int iterations, int dcb_enhance) #include "amaze_interpolate_RT.cc"//AMaZE demosaic #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 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index e6ede29bd..1c64474a9 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -142,6 +142,9 @@ class RawImageSource : public ImageSource { void ddct8x8s(int isgn, float **a); void cfa_linedn (float linenoiselevel);//Emil's line denoise + + void green_equilibrate (float greenthresh);//Emil's green equilibration + void eahd_demosaic (); void hphd_demosaic (); diff --git a/rtengine/settings.h b/rtengine/settings.h index 522eb8352..fe2fc8380 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -36,6 +36,7 @@ namespace rtengine { bool ca_autocorrect; // Emil's CA auto correction bool hotdeadpix_filt; // Emil's hot/dead pixel filter int linenoise; //Emil's line denoise + int greenthresh; //Emil's Green equilibration /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ diff --git a/rtgui/options.cc b/rtgui/options.cc index 34c0c9c45..72be1277f 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -124,7 +124,8 @@ void Options::setDefaults () { rtSettings.hotdeadpix_filt = true;//Emil's hot/dead pixel filter rtSettings.linenoise = 0;//Emil's line denoise - + rtSettings.greenthresh = 0;//Emil's Green equilibration + rtSettings.colorCorrectionSteps = 0; rtSettings.dcb_iterations = 2; rtSettings.dcb_enhance = true; @@ -269,6 +270,7 @@ if (keyFile.has_group ("Algorithms")) { if(keyFile.has_key("Algorithms", "CACorrect")) rtSettings.ca_autocorrect = keyFile.get_boolean("Algorithms", "CACorrect");//Emil's CA autocorrect if(keyFile.has_key("Algorithms", "HotDeadPixFilt")) rtSettings.hotdeadpix_filt = keyFile.get_boolean("Algorithms", "HotDeadPixFilt");//Emil's hot/dead pixel filter if(keyFile.has_key("Algorithms", "LineDenoise")) rtSettings.linenoise = keyFile.get_integer("Algorithms", "LineDenoise");//Emil's line denoise + if(keyFile.has_key("Algorithms", "GreenEquil")) rtSettings.greenthresh = keyFile.get_integer("Algorithms", "GreenEquil");//Emil's Green equilibration } if (keyFile.has_group ("Crop Settings")) { @@ -395,7 +397,8 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_boolean ("Algorithms", "CACorrect", rtSettings.ca_autocorrect);//Emil's CA correction keyFile.set_boolean ("Algorithms", "HotDeadPixFilt", rtSettings.hotdeadpix_filt);//Emil's hot/dead pixel filter keyFile.set_integer ("Algorithms", "LineDenoise", rtSettings.linenoise);//Emil's line denoise - + keyFile.set_integer ("Algorithms", "GreenEquil", rtSettings.greenthresh);//Emil's Green equilibration + keyFile.set_integer ("Crop Settings", "DPI", cropDPI); keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 2da24dfcf..e8fe60c7c 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -302,6 +302,18 @@ Gtk::Widget* Preferences::getProcParamsPanel () { hb14->pack_start (*LineDenoise); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //Emil's Green equilibration + GreenEquilLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_GREENEQUIL")+":")); + GreenEquil = Gtk::manage(new Gtk::SpinButton ()); + GreenEquil->set_digits(0); + GreenEquil->set_increments(1, 10); + GreenEquil->set_range(0, 100); + Gtk::HBox* hb15 = Gtk::manage(new Gtk::HBox()); + hb15->pack_start (*GreenEquilLabel, Gtk::PACK_SHRINK, 4); + hb15->pack_start (*GreenEquil); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + fdb->pack_start (*hb11, Gtk::PACK_SHRINK, 4); fdb->pack_start (*hb12, Gtk::PACK_SHRINK, 4); fdb->pack_start (*hb13, Gtk::PACK_SHRINK, 4); @@ -309,6 +321,7 @@ Gtk::Widget* Preferences::getProcParamsPanel () { fdb->pack_start (*caAutoCorrect, Gtk::PACK_SHRINK, 4);//Emil's CA correction fdb->pack_start (*HotDeadPixFilt, Gtk::PACK_SHRINK, 4);//Emil's hot/dead pixel filter fdb->pack_start (*hb14, Gtk::PACK_SHRINK, 4);//Emil's line denoise + fdb->pack_start (*hb15, Gtk::PACK_SHRINK, 4);//Emil's Green equlibration mvbpp->pack_start (*fdem, Gtk::PACK_SHRINK, 4); mvbpp->set_border_width (4); @@ -740,6 +753,7 @@ void Preferences::storePreferences () { moptions.rtSettings.ca_autocorrect=caAutoCorrect->get_active();//Emil's CA correction moptions.rtSettings.hotdeadpix_filt=HotDeadPixFilt->get_active();//Emil's hot/dead pixel filter moptions.rtSettings.linenoise=(int)LineDenoise->get_value();//Emil's line denoise + moptions.rtSettings.greenthresh=(int)GreenEquil->get_value();//Emil's Green equilibration if (sdcurrent->get_active ()) @@ -842,6 +856,7 @@ void Preferences::fillPreferences () { caAutoCorrect->set_active(moptions.rtSettings.ca_autocorrect);//Emil's CA Auto Correction HotDeadPixFilt->set_active(moptions.rtSettings.hotdeadpix_filt);//Emil's hot/dead pixel filter LineDenoise->set_value(moptions.rtSettings.linenoise);//Emil's line denoise + GreenEquil->set_value(moptions.rtSettings.greenthresh);//Emil's Green equilibration diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 0335ff914..646202017 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -79,6 +79,8 @@ class Preferences : public Gtk::Dialog { Gtk::CheckButton* HotDeadPixFilt;//Emil's hot/dead pixel filter Gtk::Label* LineDenoiseLabel;//Emil's line denoise Gtk::SpinButton* LineDenoise; + Gtk::Label* GreenEquilLabel;//Emil's Green equilibration + Gtk::SpinButton* GreenEquil; Gtk::FileChooserButton* iccDir; Gtk::FileChooserButton* monProfile;