Optimization for dark frames and hot/dead pixel detection/interpolation, Issue 2486
This commit is contained in:
parent
7d16d8e422
commit
13a49eb7b3
@ -8,6 +8,7 @@ Developement contributors, in last name alphabetical order:
|
||||
Martin Burri
|
||||
Javier Celaya
|
||||
Jacques Desmis
|
||||
Pavlov Dmitry
|
||||
Oliver Duis
|
||||
Maciek Dworak
|
||||
Michael Ezra
|
||||
@ -36,6 +37,7 @@ Other contributors (profiles, ideas, mockups, testing, forum activity, translati
|
||||
Thorsten Bartolomäus
|
||||
Patrik Brunner
|
||||
Fernando Carello
|
||||
Pat David
|
||||
Reine Edvardsson
|
||||
André Gauthier
|
||||
Sébastien Guyader
|
||||
|
@ -623,7 +623,8 @@ PARTIALPASTE_METAICMGROUP;Gruppe Metadaten / ICM
|
||||
PARTIALPASTE_PCVIGNETTE;Vignettierungsfilter
|
||||
PARTIALPASTE_PERSPECTIVE;Perspektive
|
||||
PARTIALPASTE_PREPROCESS_GREENEQUIL;Vorverarbeitung: Grün-Ausgleich
|
||||
PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Vorverarbeitung: Hot/Dead-Pixel-Filter anwenden
|
||||
PARTIALPASTE_PREPROCESS_HOTPIXFILT;Vorverarbeitung: Hot-Pixel-Filter
|
||||
PARTIALPASTE_PREPROCESS_DEADPIXFILT;Vorverarbeitung: Dead-Pixel-Filter
|
||||
PARTIALPASTE_PREPROCESS_LINEDENOISE;Vorverarbeitung: Zeilenrauschfilter
|
||||
PARTIALPASTE_RAWCACORR_AUTO;Chromatische Aberration: Automatische Korrektur
|
||||
PARTIALPASTE_RAWCACORR_CABLUE;Chromatische Aberration: Blau
|
||||
@ -633,7 +634,7 @@ PARTIALPASTE_RAWEXPOS_LINEAR;RAW-Weiß/Schwarz-Punkt: Linearer Korrekturfaktor
|
||||
PARTIALPASTE_RAWEXPOS_PRESER;RAW-Weiß/Schwarz-Punkt: Lichter bewahren (EV)
|
||||
PARTIALPASTE_RAWGROUP;Gruppe RAW
|
||||
PARTIALPASTE_RAW_ALLENHANCE;Farbinterpolation: Artifakt-/Rauschminderung
|
||||
PARTIALPASTE_RAW_DCBENHANCE;Farbinterpolation: DCB-Verfeinerungsschritt durchführen
|
||||
PARTIALPASTE_RAW_DCBENHANCE;Farbinterpolation: DCB-Verfeinerungsschritt
|
||||
PARTIALPASTE_RAW_DCBITERATIONS;Farbinterpolation: Anzahl der DCB-Iterationen
|
||||
PARTIALPASTE_RAW_DMETHOD;Farbinterpolation: Methode
|
||||
PARTIALPASTE_RAW_FALSECOLOR;Farbinterpolation: Falschfarbenunterdrückung Stufen
|
||||
@ -1206,7 +1207,8 @@ TP_PERSPECTIVE_HORIZONTAL;Horizontal
|
||||
TP_PERSPECTIVE_LABEL;Perspektive
|
||||
TP_PERSPECTIVE_VERTICAL;Vertikal
|
||||
TP_PREPROCESS_GREENEQUIL;Grün-Ausgleich
|
||||
TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead-Pixel-Filter anwenden
|
||||
TP_PREPROCESS_HOTPIXFILT;Hot-Pixel-Filter
|
||||
TP_PREPROCESS_DEADPIXFILT;Dead-Pixel-Filter
|
||||
TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/Dead-Pixel-Erkennung\nSchwellenwert
|
||||
TP_PREPROCESS_LABEL;Vorverarbeitung
|
||||
TP_PREPROCESS_LINEDENOISE;Zeilenrauschfilter
|
||||
@ -1223,7 +1225,7 @@ TP_RAWEXPOS_LINEAR;Weißpunkt: Linearer\nKorrekturfaktor
|
||||
TP_RAWEXPOS_PRESER;Weißpunkt: Lichter\nbewahrende Korrektur (EV)
|
||||
TP_RAWEXPOS_TWOGREEN;Grün-Werte automatisch angleichen
|
||||
TP_RAW_ALLENHANCE;Artifakt-/Rauschminderung nach\nFarbinterpolation durchführen
|
||||
TP_RAW_DCBENHANCE;DCB-Verfeinerungsschritt durchführen
|
||||
TP_RAW_DCBENHANCE;DCB-Verfeinerungsschritt
|
||||
TP_RAW_DCBITERATIONS;Anzahl der DCB-Iterationen
|
||||
TP_RAW_DMETHOD;Methode
|
||||
TP_RAW_FALSECOLOR;Falschfarbenunterdrückung\nStufen
|
||||
|
@ -690,7 +690,8 @@ PARTIALPASTE_METAICMGROUP;Réglages des Métadonnées/ICM
|
||||
PARTIALPASTE_PCVIGNETTE;Filtre Vignettage
|
||||
PARTIALPASTE_PERSPECTIVE;Perspective
|
||||
PARTIALPASTE_PREPROCESS_GREENEQUIL;Équilibrage du vert
|
||||
PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filtrage des pixels chauds/morts
|
||||
PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtrage des pixels chauds
|
||||
PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filtrage des pixels morts
|
||||
PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne
|
||||
PARTIALPASTE_RAWCACORR_AUTO;Corr. auto. de l'aberr. chromatique
|
||||
PARTIALPASTE_RAWCACORR_CABLUE;Aberr. chromatique bleu
|
||||
@ -1360,8 +1361,10 @@ TP_PERSPECTIVE_VERTICAL;Verticale
|
||||
TP_PFCURVE_CURVEEDITOR_CH;Teinte
|
||||
TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Contrôle la force du défrangeage en fonction de la couleur. En haut = action maxi, en bas = pas d'action sur la couleur.
|
||||
TP_PREPROCESS_GREENEQUIL;Équilibrage du vert
|
||||
TP_PREPROCESS_HOTDEADPIXFILT;Filtrer les pixels chauds/morts
|
||||
TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Essaie de supprimer les pixels chauds/morts
|
||||
TP_PREPROCESS_HOTPIXFILT;Filtrer les pixels chauds
|
||||
TP_PREPROCESS_DEADPIXFILT;Filtrer les pixels morts
|
||||
TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Essaie de supprimer les pixels chauds
|
||||
TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Essaie de supprimer les pixels morts
|
||||
TP_PREPROCESS_LABEL;Traitement pre-dématriçage
|
||||
TP_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne
|
||||
TP_PREPROCESS_NO_FOUND;Aucun trouvé
|
||||
|
@ -319,7 +319,7 @@ HISTORY_MSG_95;Lab - Chromaticity
|
||||
HISTORY_MSG_96;'a' Curve
|
||||
HISTORY_MSG_97;'b' Curve
|
||||
HISTORY_MSG_98;Demosaicing Method
|
||||
HISTORY_MSG_99;Hot/Dead pixel filter
|
||||
HISTORY_MSG_99;Hot pixel filter
|
||||
HISTORY_MSG_100;Saturation
|
||||
HISTORY_MSG_101;HSV - Hue
|
||||
HISTORY_MSG_102;HSV - Saturation
|
||||
@ -517,6 +517,7 @@ HISTORY_MSG_294;Film Simulation - Strength
|
||||
HISTORY_MSG_295;Film Simulation - Film
|
||||
HISTORY_MSG_296;NR - Modulate luminance
|
||||
HISTORY_MSG_297;NR - Quality
|
||||
HISTORY_MSG_298;Dead pixel filter
|
||||
HISTORY_NEWSNAPSHOT;Add
|
||||
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
|
||||
HISTORY_SNAPSHOTS;Snapshots
|
||||
@ -686,7 +687,8 @@ PARTIALPASTE_METAICMGROUP;Metadata/Color Management Settings
|
||||
PARTIALPASTE_PCVIGNETTE;Vignette filter
|
||||
PARTIALPASTE_PERSPECTIVE;Perspective
|
||||
PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration
|
||||
PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter
|
||||
PARTIALPASTE_PREPROCESS_HOTPIXFILT;Apply hot pixel filter
|
||||
PARTIALPASTE_PREPROCESS_DEADPIXFILT;Apply dead pixel filter
|
||||
PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter
|
||||
PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction
|
||||
PARTIALPASTE_RAWCACORR_CABLUE;CA blue
|
||||
@ -1376,8 +1378,10 @@ TP_PERSPECTIVE_VERTICAL;Vertical
|
||||
TP_PFCURVE_CURVEEDITOR_CH;Hue
|
||||
TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less.
|
||||
TP_PREPROCESS_GREENEQUIL;Green Equilibration
|
||||
TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter
|
||||
TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Tries to suppress hot and dead pixels.
|
||||
TP_PREPROCESS_HOTPIXFILT;Hot pixel filter
|
||||
TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels.
|
||||
TP_PREPROCESS_DEADPIXFILT;Dead pixel filter
|
||||
TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels.
|
||||
TP_PREPROCESS_LABEL;Preprocessing
|
||||
TP_PREPROCESS_LINEDENOISE;Line Noise Filter
|
||||
TP_PREPROCESS_NO_FOUND;None found
|
||||
|
@ -95,7 +95,7 @@ RawImage* dfInfo::getRawImage()
|
||||
return ri;
|
||||
}
|
||||
|
||||
std::list<badPix>& dfInfo::getHotPixels()
|
||||
std::vector<badPix>& dfInfo::getHotPixels()
|
||||
{
|
||||
if( !ri ){
|
||||
updateRawImage();
|
||||
@ -172,26 +172,36 @@ void dfInfo::updateRawImage()
|
||||
|
||||
void dfInfo::updateBadPixelList( RawImage *df )
|
||||
{
|
||||
const int threshold=10;
|
||||
const float threshold=10.f/8.f;
|
||||
if( ri->getSensorType()!=ST_NONE ){
|
||||
std::vector<badPix> badPixelsTemp;
|
||||
|
||||
#pragma omp parallel
|
||||
{
|
||||
std::vector<badPix> badPixelsThread;
|
||||
#pragma omp for nowait
|
||||
for( int row=2; row<df->get_height()-2; row++)
|
||||
for( int col=2; col < df->get_width()-2; col++){
|
||||
int m = (df->data[row-2][col-2] + df->data[row-2][col] + df->data[row-2][col+2]+
|
||||
float m = (df->data[row-2][col-2] + df->data[row-2][col] + df->data[row-2][col+2]+
|
||||
df->data[row][col-2] + df->data[row][col+2]+
|
||||
df->data[row+2][col-2] + df->data[row+2][col] + df->data[row+2][col+2])/8;
|
||||
if( df->data[row][col]/threshold > m )
|
||||
badPixels.push_back( badPix(col,row) );
|
||||
df->data[row+2][col-2] + df->data[row+2][col] + df->data[row+2][col+2]);
|
||||
if( df->data[row][col] > m*threshold )
|
||||
badPixelsThread.push_back( badPix(col,row) );
|
||||
}
|
||||
#pragma omp critical
|
||||
badPixelsTemp.insert(badPixelsTemp.end(),badPixelsThread.begin(),badPixelsThread.end());
|
||||
}
|
||||
badPixels.insert(badPixels.end(),badPixelsTemp.begin(),badPixelsTemp.end());
|
||||
}else{
|
||||
for( int row=1; row<df->get_height()-1; row++)
|
||||
for( int col=1; col < df->get_width()-1; col++){
|
||||
int m[3];
|
||||
float m[3];
|
||||
for( int c=0; c<3;c++){
|
||||
m[c] = (df->data[row-1][3*(col-1)+c] + df->data[row-1][3*col+c] + df->data[row-1][3*(col+1)+c]+
|
||||
df->data[row] [3*(col-1)+c] + df->data[row] [3*col+c]+
|
||||
df->data[row+1][3*(col-1)+c] + df->data[row+1][3*col+c] + df->data[row+1][3*(col+1)+c])/8;
|
||||
df->data[row+1][3*(col-1)+c] + df->data[row+1][3*col+c] + df->data[row+1][3*(col+1)+c]);
|
||||
}
|
||||
if( df->data[row][3*col]/threshold > m[0] || df->data[row][3*col+1]/threshold > m[1] || df->data[row][3*col+2]/threshold > m[2])
|
||||
if( df->data[row][3*col] > m[0]*threshold || df->data[row][3*col+1] > m[1]*threshold || df->data[row][3*col+2] > m[2]*threshold)
|
||||
badPixels.push_back( badPix(col,row) );
|
||||
}
|
||||
}
|
||||
@ -367,7 +377,7 @@ RawImage* DFManager::searchDarkFrame( const Glib::ustring filename )
|
||||
return df->getRawImage();
|
||||
return 0;
|
||||
}
|
||||
std::list<badPix> *DFManager::getHotPixels ( const Glib::ustring filename )
|
||||
std::vector<badPix> *DFManager::getHotPixels ( const Glib::ustring filename )
|
||||
{
|
||||
for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){
|
||||
if( iter->second.pathname.compare( filename )==0 )
|
||||
@ -375,7 +385,7 @@ std::list<badPix> *DFManager::getHotPixels ( const Glib::ustring filename )
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
std::list<badPix> *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t )
|
||||
std::vector<badPix> *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t )
|
||||
{
|
||||
dfInfo *df = find( mak, mod, iso, shut, t );
|
||||
if( df ){
|
||||
@ -408,13 +418,21 @@ int DFManager::scanBadPixelsFile( Glib::ustring filename )
|
||||
dirpos1= dirpos2;
|
||||
|
||||
std::string makmodel(filename,dirpos1+1,lastdot-(dirpos1+1) );
|
||||
std::list<badPix> bp;
|
||||
std::vector<badPix> bp;
|
||||
char line[256];
|
||||
while( fgets(line,sizeof(line),file ) ){
|
||||
if(fgets(line,sizeof(line),file )) {
|
||||
int x,y;
|
||||
if( sscanf(line,"%d %d",&x,&y) == 2 )
|
||||
bp.push_back( badPix(x,y) );
|
||||
}
|
||||
int offset = 0;
|
||||
int numparms = sscanf(line,"%d %d",&x,&y);
|
||||
if( numparms == 1 ) // only one number in first line means, that this is the offset.
|
||||
offset = x;
|
||||
else if(numparms == 2)
|
||||
bp.push_back( badPix(x+offset,y+offset) );
|
||||
while( fgets(line,sizeof(line),file ) ){
|
||||
if( sscanf(line,"%d %d",&x,&y) == 2 )
|
||||
bp.push_back( badPix(x+offset,y+offset) );
|
||||
}
|
||||
}
|
||||
int numPixels = bp.size();
|
||||
if( numPixels >0 )
|
||||
bpList[ makmodel ] = bp;
|
||||
@ -422,21 +440,42 @@ int DFManager::scanBadPixelsFile( Glib::ustring filename )
|
||||
return numPixels;
|
||||
}
|
||||
|
||||
std::list<badPix> *DFManager::getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial)
|
||||
std::vector<badPix> *DFManager::getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << mak << " " <<mod;
|
||||
if( !serial.empty())
|
||||
s << " " << serial;
|
||||
bpList_t::iterator iter = bpList.find( s.str() );
|
||||
if( iter != bpList.end() ){
|
||||
bpList_t::iterator iter;
|
||||
bool found = false;
|
||||
if( !serial.empty() ) {
|
||||
// search with sreial number first
|
||||
std::ostringstream s;
|
||||
s << mak << " " << mod << " " << serial;
|
||||
iter = bpList.find( s.str() );
|
||||
if( iter != bpList.end() )
|
||||
found = true;
|
||||
if( settings->verbose )
|
||||
printf("Found:%s.badpixels in list\n",s.str().c_str());
|
||||
if(found)
|
||||
printf("%s.badpixels found\n",s.str().c_str());
|
||||
else
|
||||
printf("%s.badpixels not found\n",s.str().c_str());
|
||||
|
||||
}
|
||||
if(!found) {
|
||||
// search without serial number
|
||||
std::ostringstream s;
|
||||
s << mak << " " <<mod;
|
||||
iter = bpList.find( s.str() );
|
||||
if( iter != bpList.end() )
|
||||
found = true;
|
||||
if( settings->verbose )
|
||||
if(found)
|
||||
printf("%s.badpixels found\n",s.str().c_str());
|
||||
else
|
||||
printf("%s.badpixels not found\n",s.str().c_str());
|
||||
}
|
||||
if(!found) {
|
||||
return 0;
|
||||
} else {
|
||||
return &(iter->second);
|
||||
}
|
||||
if( settings->verbose )
|
||||
printf("%s.badpixels not found\n",s.str().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Global variable
|
||||
|
@ -55,11 +55,11 @@ public:
|
||||
std::string key(){ return key( maker,model,iso,shutter); }
|
||||
|
||||
RawImage *getRawImage();
|
||||
std::list<badPix> &getHotPixels();
|
||||
std::vector<badPix> &getHotPixels();
|
||||
|
||||
protected:
|
||||
RawImage *ri; ///< Dark Frame raw data
|
||||
std::list<badPix> badPixels; ///< Extracted hot pixels
|
||||
std::vector<badPix> badPixels; ///< Extracted hot pixels
|
||||
|
||||
void updateBadPixelList( RawImage *df );
|
||||
void updateRawImage();
|
||||
@ -73,13 +73,13 @@ public:
|
||||
void getStat( int &totFiles, int &totTemplate);
|
||||
RawImage *searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
|
||||
RawImage *searchDarkFrame( const Glib::ustring filename );
|
||||
std::list<badPix> *getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
|
||||
std::list<badPix> *getHotPixels ( const Glib::ustring filename );
|
||||
std::list<badPix> *getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial);
|
||||
std::vector<badPix> *getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
|
||||
std::vector<badPix> *getHotPixels ( const Glib::ustring filename );
|
||||
std::vector<badPix> *getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial);
|
||||
|
||||
protected:
|
||||
typedef std::multimap<std::string,dfInfo> dfList_t;
|
||||
typedef std::map<std::string, std::list<badPix> > bpList_t;
|
||||
typedef std::map<std::string, std::vector<badPix> > bpList_t;
|
||||
dfList_t dfList;
|
||||
bpList_t bpList;
|
||||
bool initialized;
|
||||
|
@ -155,7 +155,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
|
||||
|
||||
rp.bayersensor.ccSteps = 0;
|
||||
rp.xtranssensor.ccSteps = 0;
|
||||
rp.hotdeadpix_filt = false;
|
||||
rp.deadPixelFilter = rp.hotPixelFilter = false;
|
||||
}
|
||||
|
||||
progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases);
|
||||
|
@ -120,7 +120,7 @@ enum ProcEvent {
|
||||
EvLaCurve=95,
|
||||
EvLbCurve=96,
|
||||
EvDemosaicMethod=97,
|
||||
EvPreProcessHotDeadPixel=98,
|
||||
EvPreProcessHotPixel=98,
|
||||
EvSaturation=99,
|
||||
EvHSVEqualizerH=100,
|
||||
EvHSVEqualizerS=101,
|
||||
@ -322,6 +322,7 @@ enum ProcEvent {
|
||||
EvFilmSimulationFilename=294,
|
||||
EvDPDNLCurve=295,
|
||||
EvDPDNsmet=296,
|
||||
EvPreProcessDeadPixel=297,
|
||||
|
||||
NUMOFEVENTS
|
||||
};
|
||||
|
@ -835,7 +835,8 @@ void ProcParams::setDefaults () {
|
||||
raw.cared = 0;
|
||||
raw.cablue = 0;
|
||||
raw.ca_autocorrect = false;
|
||||
raw.hotdeadpix_filt = false;
|
||||
raw.hotPixelFilter = false;
|
||||
raw.deadPixelFilter = false;
|
||||
raw.hotdeadpix_thresh = 40;
|
||||
exif.clear ();
|
||||
iptc.clear ();
|
||||
@ -1494,7 +1495,8 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
|
||||
if (!pedited || pedited->raw.caCorrection) keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect );
|
||||
if (!pedited || pedited->raw.caRed) keyFile.set_double ("RAW", "CARed", raw.cared );
|
||||
if (!pedited || pedited->raw.caBlue) keyFile.set_double ("RAW", "CABlue", raw.cablue );
|
||||
if (!pedited || pedited->raw.hotDeadPixelFilter) keyFile.set_boolean ("RAW", "HotDeadPixels", raw.hotdeadpix_filt );
|
||||
if (!pedited || pedited->raw.hotPixelFilter) keyFile.set_boolean ("RAW", "HotPixelFilter", raw.hotPixelFilter );
|
||||
if (!pedited || pedited->raw.deadPixelFilter) keyFile.set_boolean ("RAW", "DeadPixelFilter", raw.deadPixelFilter );
|
||||
if (!pedited || pedited->raw.hotDeadPixelThresh) keyFile.set_integer ("RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh );
|
||||
|
||||
if (!pedited || pedited->raw.bayersensor.method) keyFile.set_string ("RAW Bayer", "Method", raw.bayersensor.method );
|
||||
@ -2201,7 +2203,11 @@ if (keyFile.has_group ("RAW")) {
|
||||
if (keyFile.has_key ("RAW", "CA")) { raw.ca_autocorrect = keyFile.get_boolean ("RAW", "CA" ); if (pedited) pedited->raw.caCorrection = true; }
|
||||
if (keyFile.has_key ("RAW", "CARed")) { raw.cared = keyFile.get_double ("RAW", "CARed" ); if (pedited) pedited->raw.caRed = true; }
|
||||
if (keyFile.has_key ("RAW", "CABlue")) { raw.cablue = keyFile.get_double ("RAW", "CABlue" ); if (pedited) pedited->raw.caBlue = true; }
|
||||
if (keyFile.has_key ("RAW", "HotDeadPixels")) { raw.hotdeadpix_filt = keyFile.get_boolean ("RAW", "HotDeadPixels" ); if (pedited) pedited->raw.hotDeadPixelFilter = true; }
|
||||
// for compatibility to elder pp3 versions
|
||||
if (keyFile.has_key ("RAW", "HotDeadPixels")) { raw.deadPixelFilter = raw.hotPixelFilter = keyFile.get_boolean ("RAW", "HotDeadPixels" ); if (pedited) pedited->raw.hotPixelFilter = pedited->raw.deadPixelFilter = true; }
|
||||
if (keyFile.has_key ("RAW", "HotPixelFilter")) { raw.hotPixelFilter = keyFile.get_boolean ("RAW", "HotPixelFilter" ); if (pedited) pedited->raw.hotPixelFilter = true; }
|
||||
if (keyFile.has_key ("RAW", "DeadPixelFilter")) { raw.deadPixelFilter = keyFile.get_boolean ("RAW", "DeadPixelFilter" ); if (pedited) pedited->raw.deadPixelFilter = true; }
|
||||
|
||||
if (keyFile.has_key ("RAW", "HotDeadPixelThresh")) { raw.hotdeadpix_thresh = keyFile.get_integer ("RAW", "HotDeadPixelThresh" ); if (pedited) pedited->raw.hotDeadPixelThresh = true; }
|
||||
if (keyFile.has_key ("RAW", "PreExposure")) { raw.expos =keyFile.get_double("RAW", "PreExposure"); if (pedited) pedited->raw.exPos = true; }
|
||||
if (keyFile.has_key ("RAW", "PrePreserv")) { raw.preser =keyFile.get_double("RAW", "PrePreserv"); if (pedited) pedited->raw.exPreser = true; }
|
||||
@ -2570,7 +2576,8 @@ bool ProcParams::operator== (const ProcParams& other) {
|
||||
&& raw.ca_autocorrect == other.raw.ca_autocorrect
|
||||
&& raw.cared == other.raw.cared
|
||||
&& raw.cablue == other.raw.cablue
|
||||
&& raw.hotdeadpix_filt == other.raw.hotdeadpix_filt
|
||||
&& raw.hotPixelFilter == other.raw.hotPixelFilter
|
||||
&& raw.deadPixelFilter == other.raw.deadPixelFilter
|
||||
&& raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh
|
||||
&& icm.input == other.icm.input
|
||||
&& icm.toneCurve == other.icm.toneCurve
|
||||
|
@ -947,7 +947,8 @@ class RAWParams {
|
||||
double expos;
|
||||
double preser;
|
||||
|
||||
bool hotdeadpix_filt;
|
||||
bool hotPixelFilter;
|
||||
bool deadPixelFilter;
|
||||
int hotdeadpix_thresh;
|
||||
};
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#define __RAWIMAGE_H
|
||||
|
||||
#include <ctime>
|
||||
#include <glibmm.h>
|
||||
#include "dcraw.h"
|
||||
#include "imageio.h"
|
||||
|
||||
@ -28,9 +27,9 @@ namespace rtengine {
|
||||
|
||||
struct badPix
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
badPix( int xc, int yc ):x(xc),y(yc){}
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
badPix( uint16_t xc, uint16_t yc ):x(xc),y(yc){}
|
||||
};
|
||||
|
||||
class PixelsMap{
|
||||
@ -66,12 +65,12 @@ public:
|
||||
}
|
||||
|
||||
// set pixels from a list
|
||||
int set( std::list<badPix> &bp)
|
||||
int set( std::vector<badPix> &bp)
|
||||
{
|
||||
int totSet=0;
|
||||
for(std::list<badPix>::iterator iter = bp.begin(); iter != bp.end(); iter++,totSet++)
|
||||
for(std::vector<badPix>::iterator iter = bp.begin(); iter != bp.end(); ++iter)
|
||||
set( iter->x,iter->y);
|
||||
return totSet;
|
||||
|
||||
return bp.size();
|
||||
}
|
||||
|
||||
void clear(){
|
||||
@ -156,6 +155,8 @@ public:
|
||||
int get_thumbBPS(){ return thumb_load_raw ? 16 : 8; }
|
||||
bool get_thumbSwap() const;
|
||||
unsigned get_thumbLength(){ return thumb_length;}
|
||||
bool zeroIsBad() {return zero_is_bad == 1 ? true : false;}
|
||||
|
||||
public:
|
||||
// dcraw functions
|
||||
void scale_colors(){ if(isXtrans()) clearXtransCblack( ); DCraw::scale_colors(); }
|
||||
|
@ -456,13 +456,14 @@ void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
/* cfaCleanFromMap: correct raw pixels looking at the bitmap
|
||||
/* interpolateBadPixels: correct raw pixels looking at the bitmap
|
||||
* takes into consideration if there are multiple bad pixels in the neighborhood
|
||||
*/
|
||||
int RawImageSource::cfaCleanFromMap( PixelsMap &bitmapBads )
|
||||
int RawImageSource::interpolateBadPixels( PixelsMap &bitmapBads )
|
||||
{
|
||||
float eps=1.0;
|
||||
static const float eps=1.f;
|
||||
int counter=0;
|
||||
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
|
||||
for( int row = 2; row < H-2; row++ ){
|
||||
for(int col = 2; col <W-2; col++ ){
|
||||
int sk = bitmapBads.skipIfZero(col,row); //optimization for a stripe all zero
|
||||
@ -470,32 +471,90 @@ int RawImageSource::cfaCleanFromMap( PixelsMap &bitmapBads )
|
||||
col +=sk-1; //-1 is because of col++ in cycle
|
||||
continue;
|
||||
}
|
||||
if( ! bitmapBads.get(col,row ) )
|
||||
if(!bitmapBads.get(col,row))
|
||||
continue;
|
||||
|
||||
double wtdsum=0,norm=0,sum=0,tot=0;
|
||||
for( int dy=-2;dy<=2;dy+=2){
|
||||
for( int dx=-2;dx<=2;dx+=2){
|
||||
if (dy==0 && dx==0) continue;
|
||||
if( bitmapBads.get(col+dx,row+dy) ) continue;
|
||||
sum += rawData[row+dy][col+dx];
|
||||
tot++;
|
||||
if (bitmapBads.get(col-dx,row-dy)) continue;
|
||||
float wtdsum=0.f,norm=0.f;
|
||||
|
||||
double dirwt = 1/( fabs( rawData[row+dy][col+dx]- rawData[row-dy][col-dx])+eps);
|
||||
wtdsum += dirwt* rawData[row+dy][col+dx];
|
||||
// diagonal interpolation
|
||||
if(FC(row,col)==1) {
|
||||
// green channel. We can use closer pixels than for red or blue channel. Distance to center pixel is sqrt(2) => weighting is 0.70710678
|
||||
// For green channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
|
||||
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
|
||||
// 0 0 0 0 0
|
||||
// 0 1 0 1 0
|
||||
// 0 0 0 0 0
|
||||
// 0 1 0 1 0
|
||||
// 0 0 0 0 0
|
||||
for( int dx=-1;dx<=1;dx+=2){
|
||||
if( bitmapBads.get(col+dx,row-1) || bitmapBads.get(col-dx,row+1))
|
||||
continue;
|
||||
float dirwt = 0.70710678f/( fabsf( rawData[row-1][col+dx]- rawData[row+1][col-dx])+eps);
|
||||
wtdsum += dirwt * (rawData[row-1][col+dx] + rawData[row+1][col-dx]);
|
||||
norm += dirwt;
|
||||
}
|
||||
} else {
|
||||
// red and blue channel. Distance to center pixel is sqrt(8) => weighting is 0.35355339
|
||||
// For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
|
||||
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
|
||||
// 1 0 0 0 1
|
||||
// 0 0 0 0 0
|
||||
// 0 0 0 0 0
|
||||
// 0 0 0 0 0
|
||||
// 1 0 0 0 1
|
||||
for( int dx=-2;dx<=2;dx+=4){
|
||||
if( bitmapBads.get(col+dx,row-2) || bitmapBads.get(col-dx,row+2))
|
||||
continue;
|
||||
float dirwt = 0.35355339f/( fabsf( rawData[row-2][col+dx]- rawData[row+2][col-dx])+eps);
|
||||
wtdsum += dirwt * (rawData[row-2][col+dx] + rawData[row+2][col-dx]);
|
||||
norm += dirwt;
|
||||
}
|
||||
}
|
||||
if (norm > 0.0){
|
||||
rawData[row][col]= wtdsum / norm;//gradient weighted average
|
||||
// channel independent. Distance to center pixel is 2 => weighting is 0.5
|
||||
// Additionally for all channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
|
||||
// 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
|
||||
// 0 0 1 0 0
|
||||
// 0 0 0 0 0
|
||||
// 1 0 0 0 1
|
||||
// 0 0 0 0 0
|
||||
// 0 0 1 0 0
|
||||
|
||||
// horizontal interpolation
|
||||
if(!(bitmapBads.get(col-2,row) || bitmapBads.get(col+2,row))) {
|
||||
float dirwt = 0.5f/( fabsf( rawData[row][col-2]- rawData[row][col+2])+eps);
|
||||
wtdsum += dirwt * (rawData[row][col-2] + rawData[row][col+2]);
|
||||
norm += dirwt;
|
||||
}
|
||||
|
||||
// vertical interpolation
|
||||
if(!(bitmapBads.get(col,row-2) || bitmapBads.get(col,row+2))) {
|
||||
float dirwt = 0.5f/( fabsf( rawData[row-2][col]- rawData[row+2][col])+eps);
|
||||
wtdsum += dirwt * (rawData[row-2][col] + rawData[row+2][col]);
|
||||
norm += dirwt;
|
||||
}
|
||||
|
||||
if (LIKELY(norm > 0.f)){ // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999%
|
||||
rawData[row][col]= wtdsum / (2.f * norm);//gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
|
||||
counter++;
|
||||
} else {
|
||||
if (tot > 0.1) rawData[row][col] = sum/tot;//backup plan -- simple average
|
||||
} else { //backup plan -- simple average. Same method for all channels. We could improve this, but it's really unlikely that this case happens
|
||||
int tot = 0;
|
||||
float sum = 0;
|
||||
for( int dy=-2;dy<=2;dy+=2){
|
||||
for( int dx=-2;dx<=2;dx+=2){
|
||||
if(bitmapBads.get(col+dx,row+dy))
|
||||
continue;
|
||||
sum += rawData[row+dy][col+dx];
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
if (tot > 0) {
|
||||
rawData[row][col] = sum/tot;
|
||||
counter ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
return counter; // Number of interpolated pixels.
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
@ -505,8 +564,10 @@ int RawImageSource::cfaCleanFromMap( PixelsMap &bitmapBads )
|
||||
* (Taken from Emil Martinec idea)
|
||||
* (Optimized by Ingo Weyrich 2013)
|
||||
*/
|
||||
int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
|
||||
int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels )
|
||||
{
|
||||
float varthresh = (20.0*(thresh/100.0) + 1.0 );
|
||||
|
||||
// counter for dead or hot pixels
|
||||
int counter=0;
|
||||
|
||||
@ -528,7 +589,7 @@ int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
|
||||
med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext],
|
||||
rawData[i][jprev],rawData[i][j],rawData[i][jnext],
|
||||
rawData[inext][jprev],rawData[inext][j],rawData[inext][jnext],temp);
|
||||
cfablur[i*W+j] = fabs(rawData[i][j]-temp);
|
||||
cfablur[i*W+j] = rawData[i][j]-temp;
|
||||
}
|
||||
}
|
||||
#pragma omp for reduction(+:counter) schedule (dynamic,16)
|
||||
@ -540,16 +601,21 @@ int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
|
||||
for (int cc=0; cc < W; cc++,rrmWpcc++) {
|
||||
//evaluate pixel for heat/death
|
||||
float pixdev = cfablur[rrmWpcc];
|
||||
if((!findDeadPixels) && pixdev <= 0)
|
||||
continue;
|
||||
if((!findHotPixels) && pixdev >= 0)
|
||||
continue;
|
||||
pixdev = fabsf(pixdev);
|
||||
float hfnbrave = -pixdev;
|
||||
int left=max(0,cc-2);
|
||||
int right=min(W-1,cc+2);
|
||||
for (int mm=top; mm<=bottom; mm++) {
|
||||
int mmmWpnn = mm*W+left;
|
||||
for (int nn=left; nn<=right; nn++,mmmWpnn++) {
|
||||
hfnbrave += cfablur[mmmWpnn];
|
||||
hfnbrave += fabsf(cfablur[mmmWpnn]);
|
||||
}
|
||||
}
|
||||
if (pixdev * ((bottom-top+1)*(right-left+1)-1) > thresh*hfnbrave) {
|
||||
if (pixdev * ((bottom-top+1)*(right-left+1)-1) > varthresh*hfnbrave) {
|
||||
// mark the pixel as "bad"
|
||||
bpMap.set(cc,rr);
|
||||
counter++;
|
||||
@ -1015,7 +1081,23 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
if( rid && settings->verbose){
|
||||
printf( "Subtracting Darkframe:%s\n",rid->get_filename().c_str());
|
||||
}
|
||||
//copyOriginalPixels(ri, rid);
|
||||
|
||||
PixelsMap bitmapBads(W,H);
|
||||
int totBP=0; // Hold count of bad pixels to correct
|
||||
|
||||
if(ri->zeroIsBad()) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica)
|
||||
#pragma omp parallel for reduction(+:totBP)
|
||||
for(int i=0;i<H;i++)
|
||||
for(int j=0;j<W;j++) {
|
||||
if(ri->data[i][j] == 0.f) {
|
||||
bitmapBads.set(j,i);
|
||||
totBP++;
|
||||
}
|
||||
}
|
||||
if( settings->verbose) {
|
||||
printf( "%d pixels with value zero marked as bad pixels\n",totBP);
|
||||
}
|
||||
}
|
||||
|
||||
//FLATFIELD start
|
||||
Glib::ustring newFF = raw.ff_file;
|
||||
@ -1027,20 +1109,18 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
rif = ffm.searchFlatField( idata->getMake(), idata->getModel(),idata->getLens(),idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS());
|
||||
}
|
||||
|
||||
|
||||
bool hasFlatField = (rif!=NULL);
|
||||
if( hasFlatField && settings->verbose) {
|
||||
printf( "Flat Field Correction:%s\n",rif->get_filename().c_str());
|
||||
}
|
||||
|
||||
copyOriginalPixels(raw, ri, rid, rif);
|
||||
//FLATFIELD end
|
||||
|
||||
|
||||
|
||||
PixelsMap bitmapBads(W,H);
|
||||
int totBP=0; // Hold count of bad pixels to correct
|
||||
|
||||
// Always correct camera badpixels
|
||||
std::list<badPix> *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), std::string("") );
|
||||
// Always correct camera badpixels from .badpixels file
|
||||
std::vector<badPix> *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), idata->getSerialNumber() );
|
||||
if( bp ){
|
||||
totBP+=bitmapBads.set( *bp );
|
||||
if( settings->verbose ){
|
||||
@ -1061,6 +1141,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
scaleColors( 0,0, W, H, raw);//+ + raw parameters for black level(raw.blackxx)
|
||||
|
||||
// Correct vignetting of lens profile
|
||||
@ -1081,20 +1162,17 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
|
||||
defGain = 0.0;//log(initialGain) / log(2.0);
|
||||
|
||||
if ( raw.hotdeadpix_filt>0 ) {
|
||||
if ( raw.hotPixelFilter>0 || raw.deadPixelFilter>0) {
|
||||
if (plistener) {
|
||||
plistener->setProgressStr ("Hot/Dead Pixel Filter...");
|
||||
plistener->setProgress (0.0);
|
||||
}
|
||||
float varthresh = (20.0*((float)raw.hotdeadpix_thresh/100.0) + 1.0 );
|
||||
int nFound =findHotDeadPixel( bitmapBads, varthresh );
|
||||
int nFound = findHotDeadPixels( bitmapBads, raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter );
|
||||
totBP += nFound;
|
||||
if( settings->verbose && nFound>0){
|
||||
printf( "Correcting %d hot/dead pixels found inside image\n",nFound );
|
||||
}
|
||||
}
|
||||
if( totBP )
|
||||
cfaCleanFromMap( bitmapBads );
|
||||
|
||||
// check if it is an olympus E camera, if yes, compute G channel pre-compensation factors
|
||||
if ( ri->getSensorType()==ST_BAYER && (raw.bayersensor.greenthresh || (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,9)=="Panasonic")) && raw.bayersensor.method != RAWParams::BayerSensor::methodstring[ RAWParams::BayerSensor::vng4])) ) {
|
||||
@ -1137,6 +1215,10 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
}
|
||||
|
||||
|
||||
if( totBP )
|
||||
interpolateBadPixels( bitmapBads );
|
||||
|
||||
|
||||
if ( ri->getSensorType()==ST_BAYER && raw.bayersensor.linenoise >0 ) {
|
||||
if (plistener) {
|
||||
plistener->setProgressStr ("Line Denoise...");
|
||||
|
@ -217,8 +217,8 @@ class RawImageSource : public ImageSource {
|
||||
void ddct8x8s(int isgn, float a[8][8]);
|
||||
void processRawWhitepoint (float expos, float preser); // exposure before interpolation
|
||||
|
||||
int cfaCleanFromMap( PixelsMap &bitmapBads );
|
||||
int findHotDeadPixel( PixelsMap &bpMap, float thresh);
|
||||
int interpolateBadPixels( PixelsMap &bitmapBads );
|
||||
int findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels );
|
||||
|
||||
void cfa_linedn (float linenoiselevel);//Emil's line denoise
|
||||
void cfa_tile_denoise (fftwf_complex * fcfablox, int vblk, int hblk, int numblox_H, int numblox_W, float noisevar, float * rolloff );
|
||||
|
@ -118,7 +118,7 @@ LUMINANCECURVE, // EvLSaturation,
|
||||
LUMINANCECURVE, // EvLaCurve,
|
||||
LUMINANCECURVE, // EvLbCurve,
|
||||
DEMOSAIC, // EvDemosaicMethod
|
||||
DARKFRAME, // EvPreProcessHotDeadPixel
|
||||
DARKFRAME, // EvPreProcessHotPixel
|
||||
RGBCURVE, // EvSaturation,
|
||||
RGBCURVE, // EvHSVEqualizerH,
|
||||
RGBCURVE, // EvHSVEqualizerS,
|
||||
@ -318,8 +318,8 @@ RGBCURVE, //EvFilmSimulationEnabled
|
||||
RGBCURVE, //EvFilmSimulationStrength
|
||||
RGBCURVE, //EvFilmSimulationFilename
|
||||
ALLNORAW, // EvDPDNLCurve
|
||||
ALLNORAW // EvDPDNsmet
|
||||
|
||||
ALLNORAW, // EvDPDNsmet
|
||||
DARKFRAME // EvPreProcessDeadPixel
|
||||
|
||||
|
||||
};
|
||||
|
@ -317,7 +317,8 @@ void ParamsEdited::set (bool v) {
|
||||
raw.caCorrection = v;
|
||||
raw.caBlue = v;
|
||||
raw.caRed = v;
|
||||
raw.hotDeadPixelFilter = v;
|
||||
raw.hotPixelFilter = v;
|
||||
raw.deadPixelFilter = v;
|
||||
raw.hotDeadPixelThresh = v;
|
||||
raw.darkFrame = v;
|
||||
raw.dfAuto = v;
|
||||
@ -649,7 +650,8 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
|
||||
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.hotDeadPixelFilter = raw.hotDeadPixelFilter && p.raw.hotdeadpix_filt == other.raw.hotdeadpix_filt;
|
||||
raw.hotPixelFilter = raw.hotPixelFilter && p.raw.hotPixelFilter == other.raw.hotPixelFilter;
|
||||
raw.deadPixelFilter = raw.deadPixelFilter && p.raw.deadPixelFilter == other.raw.deadPixelFilter;
|
||||
raw.hotDeadPixelThresh = raw.hotDeadPixelThresh && p.raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh;
|
||||
raw.darkFrame = raw.darkFrame && p.raw.dark_frame == other.raw.dark_frame;
|
||||
raw.dfAuto = raw.dfAuto && p.raw.df_autoselect == other.raw.df_autoselect;
|
||||
@ -989,7 +991,8 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
|
||||
if (raw.exPos) toEdit.raw.expos = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_LINEAR] ? toEdit.raw.expos + mods.raw.expos : mods.raw.expos;
|
||||
if (raw.exPreser) toEdit.raw.preser = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_PRESER] ? toEdit.raw.preser + mods.raw.preser : mods.raw.preser;
|
||||
|
||||
if (raw.hotDeadPixelFilter) toEdit.raw.hotdeadpix_filt = mods.raw.hotdeadpix_filt;
|
||||
if (raw.hotPixelFilter) toEdit.raw.hotPixelFilter = mods.raw.hotPixelFilter;
|
||||
if (raw.deadPixelFilter) toEdit.raw.deadPixelFilter = mods.raw.deadPixelFilter;
|
||||
if (raw.hotDeadPixelThresh) toEdit.raw.hotdeadpix_thresh = mods.raw.hotdeadpix_thresh;
|
||||
if (raw.darkFrame) toEdit.raw.dark_frame = mods.raw.dark_frame;
|
||||
if (raw.dfAuto) toEdit.raw.df_autoselect = mods.raw.df_autoselect;
|
||||
@ -1042,7 +1045,7 @@ bool RAWParamsEdited::XTransSensor::isUnchanged() const {
|
||||
}
|
||||
|
||||
bool RAWParamsEdited::isUnchanged() const {
|
||||
return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && caCorrection && caRed && caBlue && hotDeadPixelFilter && hotDeadPixelThresh && darkFrame
|
||||
return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && caCorrection && caRed && caBlue && hotPixelFilter && deadPixelFilter && hotDeadPixelThresh && darkFrame
|
||||
&& dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && exPreser && ff_AutoClipControl && ff_clipControl;
|
||||
}
|
||||
|
||||
|
@ -536,7 +536,8 @@ class RAWParamsEdited {
|
||||
bool caCorrection;
|
||||
bool caRed;
|
||||
bool caBlue;
|
||||
bool hotDeadPixelFilter;
|
||||
bool hotPixelFilter;
|
||||
bool deadPixelFilter;
|
||||
bool hotDeadPixelThresh;
|
||||
bool darkFrame;
|
||||
bool dfAuto;
|
||||
|
@ -97,7 +97,8 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) {
|
||||
raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO")));
|
||||
raw_cared = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CARED")));
|
||||
raw_cablue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CABLUE")));
|
||||
raw_hotdeadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT")));
|
||||
raw_hotpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTPIXFILT")));
|
||||
raw_deadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_DEADPIXFILT")));
|
||||
raw_linenoise = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_LINEDENOISE")));
|
||||
raw_greenthresh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_GREENEQUIL")));
|
||||
raw_method = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DMETHOD")));
|
||||
@ -190,7 +191,8 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) {
|
||||
vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0);
|
||||
vboxes[6]->pack_start (*raw_linenoise, Gtk::PACK_SHRINK, 2);
|
||||
vboxes[6]->pack_start (*raw_greenthresh, Gtk::PACK_SHRINK, 2);
|
||||
vboxes[6]->pack_start (*raw_hotdeadpix_filt, Gtk::PACK_SHRINK, 2);
|
||||
vboxes[6]->pack_start (*raw_hotpix_filt, Gtk::PACK_SHRINK, 2);
|
||||
vboxes[6]->pack_start (*raw_deadpix_filt, Gtk::PACK_SHRINK, 2);
|
||||
vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0);
|
||||
vboxes[6]->pack_start (*raw_expos, Gtk::PACK_SHRINK, 2);
|
||||
vboxes[6]->pack_start (*raw_preser, Gtk::PACK_SHRINK, 2);
|
||||
@ -307,7 +309,8 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) {
|
||||
raw_ca_autocorrectConn = raw_ca_autocorrect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
raw_caredConn = raw_cared->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
raw_cablueConn = raw_cablue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
raw_hotdeadpix_filtConn = raw_hotdeadpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
raw_hotpix_filtConn = raw_hotpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
raw_deadpix_filtConn = raw_deadpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
raw_linenoiseConn = raw_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
raw_greenthreshConn = raw_greenthresh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
df_fileConn = df_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
|
||||
@ -378,7 +381,8 @@ void PartialPasteDlg::rawToggled () {
|
||||
raw_ca_autocorrectConn.block (true);
|
||||
raw_caredConn.block (true);
|
||||
raw_cablueConn.block (true);
|
||||
raw_hotdeadpix_filtConn.block (true);
|
||||
raw_hotpix_filtConn.block (true);
|
||||
raw_deadpix_filtConn.block (true);
|
||||
raw_linenoiseConn.block (true);
|
||||
raw_greenthreshConn.block (true);
|
||||
df_fileConn.block (true);
|
||||
@ -403,7 +407,8 @@ void PartialPasteDlg::rawToggled () {
|
||||
raw_ca_autocorrect->set_active (raw->get_active ());
|
||||
raw_cared->set_active (raw->get_active ());
|
||||
raw_cablue->set_active (raw->get_active ());
|
||||
raw_hotdeadpix_filt->set_active (raw->get_active ());
|
||||
raw_hotpix_filt->set_active (raw->get_active ());
|
||||
raw_deadpix_filt->set_active (raw->get_active ());
|
||||
raw_linenoise->set_active (raw->get_active ());
|
||||
raw_greenthresh->set_active (raw->get_active ());
|
||||
df_file->set_active (raw->get_active ());
|
||||
@ -426,7 +431,8 @@ void PartialPasteDlg::rawToggled () {
|
||||
raw_ca_autocorrectConn.block (false);
|
||||
raw_caredConn.block (false);
|
||||
raw_cablueConn.block (false);
|
||||
raw_hotdeadpix_filtConn.block (false);
|
||||
raw_hotpix_filtConn.block (false);
|
||||
raw_deadpix_filtConn.block (false);
|
||||
raw_linenoiseConn.block (false);
|
||||
raw_greenthreshConn.block (false);
|
||||
df_fileConn.block (false);
|
||||
@ -688,7 +694,9 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param
|
||||
if (!raw_ca_autocorrect->get_active ()) filterPE.raw.caCorrection = falsePE.raw.caCorrection;
|
||||
if (!raw_cared->get_active ()) filterPE.raw.caRed = falsePE.raw.caRed;
|
||||
if (!raw_cablue->get_active ()) filterPE.raw.caBlue = falsePE.raw.caBlue;
|
||||
if (!raw_hotdeadpix_filt->get_active ()) { filterPE.raw.hotDeadPixelFilter = falsePE.raw.hotDeadPixelFilter;
|
||||
if (!raw_hotpix_filt->get_active ()) { filterPE.raw.hotPixelFilter = falsePE.raw.hotPixelFilter;
|
||||
filterPE.raw.hotDeadPixelThresh = falsePE.raw.hotDeadPixelThresh; }
|
||||
if (!raw_deadpix_filt->get_active ()) { filterPE.raw.deadPixelFilter = falsePE.raw.deadPixelFilter;
|
||||
filterPE.raw.hotDeadPixelThresh = falsePE.raw.hotDeadPixelThresh; }
|
||||
if (!df_file->get_active ()) filterPE.raw.darkFrame = falsePE.raw.darkFrame;
|
||||
if (!df_AutoSelect->get_active ()) filterPE.raw.dfAuto = falsePE.raw.dfAuto;
|
||||
|
@ -94,7 +94,8 @@ class PartialPasteDlg : public Gtk::Dialog {
|
||||
Gtk::CheckButton* raw_ca_autocorrect;
|
||||
Gtk::CheckButton* raw_cared;
|
||||
Gtk::CheckButton* raw_cablue;
|
||||
Gtk::CheckButton* raw_hotdeadpix_filt;
|
||||
Gtk::CheckButton* raw_hotpix_filt;
|
||||
Gtk::CheckButton* raw_deadpix_filt;
|
||||
Gtk::CheckButton* raw_linenoise;
|
||||
Gtk::CheckButton* raw_greenthresh;
|
||||
Gtk::CheckButton* raw_method;
|
||||
@ -121,7 +122,7 @@ class PartialPasteDlg : public Gtk::Dialog {
|
||||
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn;
|
||||
sigc::connection exifchConn, iptcConn, icmConn, gamcsconn;
|
||||
sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn;
|
||||
sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotdeadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; //,raw_all_enhanceConn
|
||||
sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; //,raw_all_enhanceConn
|
||||
|
||||
public:
|
||||
PartialPasteDlg (Glib::ustring title);
|
||||
|
@ -26,54 +26,86 @@ using namespace rtengine::procparams;
|
||||
|
||||
PreProcess::PreProcess () : FoldableToolPanel(this)
|
||||
{
|
||||
hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTDEADPIXFILT"))));
|
||||
hotDeadPixel->set_tooltip_markup (M("TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP"));
|
||||
|
||||
pack_start( *hotDeadPixel, Gtk::PACK_SHRINK, 4);
|
||||
Gtk::HBox* hotdeadPixel = Gtk::manage( new Gtk::HBox () );
|
||||
hotdeadPixel->set_spacing(4);
|
||||
hotPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTPIXFILT"))));
|
||||
deadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_DEADPIXFILT"))));
|
||||
|
||||
hdpixelconn = hotDeadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotDeadPixelChanged), true);
|
||||
hotPixel->set_tooltip_markup (M("TP_PREPROCESS_HOTPIXFILT_TOOLTIP"));
|
||||
deadPixel->set_tooltip_markup (M("TP_PREPROCESS_DEADPIXFILT_TOOLTIP"));
|
||||
|
||||
hotdeadPixel->pack_start( *hotPixel, Gtk::PACK_SHRINK);
|
||||
hotdeadPixel->pack_start( *deadPixel, Gtk::PACK_SHRINK, 0);
|
||||
pack_start(*hotdeadPixel, Gtk::PACK_SHRINK, 0);
|
||||
// hotdeadPixel->show();
|
||||
hpixelconn = hotPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotPixelChanged), true);
|
||||
dpixelconn = deadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::deadPixelChanged), true);
|
||||
}
|
||||
|
||||
void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
|
||||
{
|
||||
disableListener ();
|
||||
hdpixelconn.block (true);
|
||||
|
||||
hpixelconn.block (true);
|
||||
dpixelconn.block (true);
|
||||
if(pedited ){
|
||||
hotDeadPixel->set_inconsistent (!pedited->raw.hotDeadPixelFilter);
|
||||
hotPixel->set_inconsistent (!pedited->raw.hotPixelFilter);
|
||||
deadPixel->set_inconsistent (!pedited->raw.deadPixelFilter);
|
||||
}
|
||||
|
||||
lastHot = pp->raw.hotdeadpix_filt;
|
||||
lastHot = pp->raw.hotPixelFilter;
|
||||
lastDead = pp->raw.deadPixelFilter;
|
||||
hotPixel->set_active (pp->raw.hotPixelFilter);
|
||||
deadPixel->set_active (pp->raw.deadPixelFilter);
|
||||
|
||||
hotDeadPixel->set_active (pp->raw.hotdeadpix_filt);
|
||||
|
||||
hdpixelconn.block (false);
|
||||
hpixelconn.block (false);
|
||||
dpixelconn.block (false);
|
||||
enableListener ();
|
||||
}
|
||||
|
||||
void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited)
|
||||
{
|
||||
pp->raw.hotdeadpix_filt = hotDeadPixel->get_active();
|
||||
pp->raw.hotPixelFilter = hotPixel->get_active();
|
||||
pp->raw.deadPixelFilter = deadPixel->get_active();
|
||||
|
||||
if (pedited) {
|
||||
pedited->raw.hotDeadPixelFilter = !hotDeadPixel->get_inconsistent();
|
||||
pedited->raw.hotPixelFilter = !hotPixel->get_inconsistent();
|
||||
pedited->raw.deadPixelFilter = !deadPixel->get_inconsistent();
|
||||
}
|
||||
}
|
||||
|
||||
void PreProcess::hotDeadPixelChanged ()
|
||||
void PreProcess::hotPixelChanged ()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (hotDeadPixel->get_inconsistent()) {
|
||||
hotDeadPixel->set_inconsistent (false);
|
||||
hdpixelconn.block (true);
|
||||
hotDeadPixel->set_active (false);
|
||||
hdpixelconn.block (false);
|
||||
if (hotPixel->get_inconsistent()) {
|
||||
hotPixel->set_inconsistent (false);
|
||||
hpixelconn.block (true);
|
||||
hotPixel->set_active (false);
|
||||
hpixelconn.block (false);
|
||||
}
|
||||
else if (lastHot)
|
||||
hotDeadPixel->set_inconsistent (true);
|
||||
hotPixel->set_inconsistent (true);
|
||||
|
||||
lastHot = hotDeadPixel->get_active ();
|
||||
lastHot = hotPixel->get_active ();
|
||||
}
|
||||
if (listener)
|
||||
listener->panelChanged (EvPreProcessHotDeadPixel, hotDeadPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED"));
|
||||
listener->panelChanged (EvPreProcessHotPixel, hotPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED"));
|
||||
}
|
||||
|
||||
void PreProcess::deadPixelChanged ()
|
||||
{
|
||||
if (batchMode) {
|
||||
if (deadPixel->get_inconsistent()) {
|
||||
deadPixel->set_inconsistent (false);
|
||||
dpixelconn.block (true);
|
||||
deadPixel->set_active (false);
|
||||
dpixelconn.block (false);
|
||||
}
|
||||
else if (lastDead)
|
||||
deadPixel->set_inconsistent (true);
|
||||
|
||||
lastDead = deadPixel->get_active ();
|
||||
}
|
||||
if (listener)
|
||||
listener->panelChanged (EvPreProcessDeadPixel, deadPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED"));
|
||||
}
|
||||
|
@ -27,10 +27,11 @@
|
||||
class PreProcess : public ToolParamBlock, /*public AdjusterListener,*/ public FoldableToolPanel {
|
||||
|
||||
protected:
|
||||
|
||||
Gtk::CheckButton* hotDeadPixel;
|
||||
bool lastHot;
|
||||
sigc::connection hdpixelconn;
|
||||
Gtk::CheckButton* hotPixel;
|
||||
Gtk::CheckButton* deadPixel;
|
||||
bool lastHot,lastDead;
|
||||
sigc::connection hpixelconn;
|
||||
sigc::connection dpixelconn;
|
||||
|
||||
public:
|
||||
|
||||
@ -41,7 +42,8 @@ class PreProcess : public ToolParamBlock, /*public AdjusterListener,*/ public Fo
|
||||
//void setBatchMode (bool batchMode);
|
||||
//void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
|
||||
|
||||
void hotDeadPixelChanged();
|
||||
void hotPixelChanged();
|
||||
void deadPixelChanged();
|
||||
|
||||
//void adjusterChanged (Adjuster* a, double newval);
|
||||
//void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user