Optimization for dark frames and hot/dead pixel detection/interpolation, Issue 2486

This commit is contained in:
Ingo 2014-09-10 14:55:58 +02:00
parent 7d16d8e422
commit 13a49eb7b3
20 changed files with 343 additions and 154 deletions

View File

@ -8,6 +8,7 @@ Developement contributors, in last name alphabetical order:
Martin Burri Martin Burri
Javier Celaya Javier Celaya
Jacques Desmis Jacques Desmis
Pavlov Dmitry
Oliver Duis Oliver Duis
Maciek Dworak Maciek Dworak
Michael Ezra Michael Ezra
@ -36,6 +37,7 @@ Other contributors (profiles, ideas, mockups, testing, forum activity, translati
Thorsten Bartolomäus Thorsten Bartolomäus
Patrik Brunner Patrik Brunner
Fernando Carello Fernando Carello
Pat David
Reine Edvardsson Reine Edvardsson
André Gauthier André Gauthier
Sébastien Guyader Sébastien Guyader

View File

@ -623,7 +623,8 @@ PARTIALPASTE_METAICMGROUP;Gruppe Metadaten / ICM
PARTIALPASTE_PCVIGNETTE;Vignettierungsfilter PARTIALPASTE_PCVIGNETTE;Vignettierungsfilter
PARTIALPASTE_PERSPECTIVE;Perspektive PARTIALPASTE_PERSPECTIVE;Perspektive
PARTIALPASTE_PREPROCESS_GREENEQUIL;Vorverarbeitung: Grün-Ausgleich 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_PREPROCESS_LINEDENOISE;Vorverarbeitung: Zeilenrauschfilter
PARTIALPASTE_RAWCACORR_AUTO;Chromatische Aberration: Automatische Korrektur PARTIALPASTE_RAWCACORR_AUTO;Chromatische Aberration: Automatische Korrektur
PARTIALPASTE_RAWCACORR_CABLUE;Chromatische Aberration: Blau 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_RAWEXPOS_PRESER;RAW-Weiß/Schwarz-Punkt: Lichter bewahren (EV)
PARTIALPASTE_RAWGROUP;Gruppe RAW PARTIALPASTE_RAWGROUP;Gruppe RAW
PARTIALPASTE_RAW_ALLENHANCE;Farbinterpolation: Artifakt-/Rauschminderung 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_DCBITERATIONS;Farbinterpolation: Anzahl der DCB-Iterationen
PARTIALPASTE_RAW_DMETHOD;Farbinterpolation: Methode PARTIALPASTE_RAW_DMETHOD;Farbinterpolation: Methode
PARTIALPASTE_RAW_FALSECOLOR;Farbinterpolation: Falschfarbenunterdrückung Stufen PARTIALPASTE_RAW_FALSECOLOR;Farbinterpolation: Falschfarbenunterdrückung Stufen
@ -1206,7 +1207,8 @@ TP_PERSPECTIVE_HORIZONTAL;Horizontal
TP_PERSPECTIVE_LABEL;Perspektive TP_PERSPECTIVE_LABEL;Perspektive
TP_PERSPECTIVE_VERTICAL;Vertikal TP_PERSPECTIVE_VERTICAL;Vertikal
TP_PREPROCESS_GREENEQUIL;Grün-Ausgleich 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_HOTDEADPIXTHRESH;Hot/Dead-Pixel-Erkennung\nSchwellenwert
TP_PREPROCESS_LABEL;Vorverarbeitung TP_PREPROCESS_LABEL;Vorverarbeitung
TP_PREPROCESS_LINEDENOISE;Zeilenrauschfilter 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_PRESER;Weißpunkt: Lichter\nbewahrende Korrektur (EV)
TP_RAWEXPOS_TWOGREEN;Grün-Werte automatisch angleichen TP_RAWEXPOS_TWOGREEN;Grün-Werte automatisch angleichen
TP_RAW_ALLENHANCE;Artifakt-/Rauschminderung nach\nFarbinterpolation durchführen 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_DCBITERATIONS;Anzahl der DCB-Iterationen
TP_RAW_DMETHOD;Methode TP_RAW_DMETHOD;Methode
TP_RAW_FALSECOLOR;Falschfarbenunterdrückung\nStufen TP_RAW_FALSECOLOR;Falschfarbenunterdrückung\nStufen

View File

@ -690,7 +690,8 @@ PARTIALPASTE_METAICMGROUP;Réglages des Métadonnées/ICM
PARTIALPASTE_PCVIGNETTE;Filtre Vignettage PARTIALPASTE_PCVIGNETTE;Filtre Vignettage
PARTIALPASTE_PERSPECTIVE;Perspective PARTIALPASTE_PERSPECTIVE;Perspective
PARTIALPASTE_PREPROCESS_GREENEQUIL;Équilibrage du vert 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_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne
PARTIALPASTE_RAWCACORR_AUTO;Corr. auto. de l'aberr. chromatique PARTIALPASTE_RAWCACORR_AUTO;Corr. auto. de l'aberr. chromatique
PARTIALPASTE_RAWCACORR_CABLUE;Aberr. chromatique bleu PARTIALPASTE_RAWCACORR_CABLUE;Aberr. chromatique bleu
@ -1360,8 +1361,10 @@ TP_PERSPECTIVE_VERTICAL;Verticale
TP_PFCURVE_CURVEEDITOR_CH;Teinte 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_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_GREENEQUIL;Équilibrage du vert
TP_PREPROCESS_HOTDEADPIXFILT;Filtrer les pixels chauds/morts TP_PREPROCESS_HOTPIXFILT;Filtrer les pixels chauds
TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Essaie de supprimer les pixels chauds/morts 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_LABEL;Traitement pre-dématriçage
TP_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne TP_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne
TP_PREPROCESS_NO_FOUND;Aucun trouvé TP_PREPROCESS_NO_FOUND;Aucun trouvé

View File

@ -319,7 +319,7 @@ HISTORY_MSG_95;Lab - Chromaticity
HISTORY_MSG_96;'a' Curve HISTORY_MSG_96;'a' Curve
HISTORY_MSG_97;'b' Curve HISTORY_MSG_97;'b' Curve
HISTORY_MSG_98;Demosaicing Method HISTORY_MSG_98;Demosaicing Method
HISTORY_MSG_99;Hot/Dead pixel filter HISTORY_MSG_99;Hot pixel filter
HISTORY_MSG_100;Saturation HISTORY_MSG_100;Saturation
HISTORY_MSG_101;HSV - Hue HISTORY_MSG_101;HSV - Hue
HISTORY_MSG_102;HSV - Saturation HISTORY_MSG_102;HSV - Saturation
@ -517,6 +517,7 @@ HISTORY_MSG_294;Film Simulation - Strength
HISTORY_MSG_295;Film Simulation - Film HISTORY_MSG_295;Film Simulation - Film
HISTORY_MSG_296;NR - Modulate luminance HISTORY_MSG_296;NR - Modulate luminance
HISTORY_MSG_297;NR - Quality HISTORY_MSG_297;NR - Quality
HISTORY_MSG_298;Dead pixel filter
HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b> HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
HISTORY_SNAPSHOTS;Snapshots HISTORY_SNAPSHOTS;Snapshots
@ -686,7 +687,8 @@ PARTIALPASTE_METAICMGROUP;Metadata/Color Management Settings
PARTIALPASTE_PCVIGNETTE;Vignette filter PARTIALPASTE_PCVIGNETTE;Vignette filter
PARTIALPASTE_PERSPECTIVE;Perspective PARTIALPASTE_PERSPECTIVE;Perspective
PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration 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_PREPROCESS_LINEDENOISE;Line noise filter
PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction
PARTIALPASTE_RAWCACORR_CABLUE;CA blue PARTIALPASTE_RAWCACORR_CABLUE;CA blue
@ -1376,8 +1378,10 @@ TP_PERSPECTIVE_VERTICAL;Vertical
TP_PFCURVE_CURVEEDITOR_CH;Hue TP_PFCURVE_CURVEEDITOR_CH;Hue
TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less.
TP_PREPROCESS_GREENEQUIL;Green Equilibration TP_PREPROCESS_GREENEQUIL;Green Equilibration
TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter TP_PREPROCESS_HOTPIXFILT;Hot pixel filter
TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Tries to suppress hot and dead pixels. 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_LABEL;Preprocessing
TP_PREPROCESS_LINEDENOISE;Line Noise Filter TP_PREPROCESS_LINEDENOISE;Line Noise Filter
TP_PREPROCESS_NO_FOUND;None found TP_PREPROCESS_NO_FOUND;None found

View File

@ -26,7 +26,7 @@
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
#include "imagedata.h" #include "imagedata.h"
namespace rtengine{ namespace rtengine{
extern const Settings* settings; extern const Settings* settings;
@ -95,7 +95,7 @@ RawImage* dfInfo::getRawImage()
return ri; return ri;
} }
std::list<badPix>& dfInfo::getHotPixels() std::vector<badPix>& dfInfo::getHotPixels()
{ {
if( !ri ){ if( !ri ){
updateRawImage(); updateRawImage();
@ -108,7 +108,7 @@ std::list<badPix>& dfInfo::getHotPixels()
* the first file is used also for reading all information other than pixels * the first file is used also for reading all information other than pixels
*/ */
void dfInfo::updateRawImage() void dfInfo::updateRawImage()
{ {
typedef unsigned int acc_t; typedef unsigned int acc_t;
if( !pathNames.empty() ){ if( !pathNames.empty() ){
std::list<Glib::ustring>::iterator iName = pathNames.begin(); std::list<Glib::ustring>::iterator iName = pathNames.begin();
@ -171,27 +171,37 @@ void dfInfo::updateRawImage()
} }
void dfInfo::updateBadPixelList( RawImage *df ) void dfInfo::updateBadPixelList( RawImage *df )
{ {
const int threshold=10; const float threshold=10.f/8.f;
if( ri->getSensorType()!=ST_NONE ){ 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 row=2; row<df->get_height()-2; row++)
for( int col=2; col < df->get_width()-2; col++){ 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][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; df->data[row+2][col-2] + df->data[row+2][col] + df->data[row+2][col+2]);
if( df->data[row][col]/threshold > m ) if( df->data[row][col] > m*threshold )
badPixels.push_back( badPix(col,row) ); 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{ }else{
for( int row=1; row<df->get_height()-1; row++) for( int row=1; row<df->get_height()-1; row++)
for( int col=1; col < df->get_width()-1; col++){ for( int col=1; col < df->get_width()-1; col++){
int m[3]; float m[3];
for( int c=0; c<3;c++){ 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]+ 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] [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) ); badPixels.push_back( badPix(col,row) );
} }
} }
@ -367,7 +377,7 @@ RawImage* DFManager::searchDarkFrame( const Glib::ustring filename )
return df->getRawImage(); return df->getRawImage();
return 0; 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++ ){ for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){
if( iter->second.pathname.compare( filename )==0 ) if( iter->second.pathname.compare( filename )==0 )
@ -375,7 +385,7 @@ std::list<badPix> *DFManager::getHotPixels ( const Glib::ustring filename )
} }
return 0; 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 ); dfInfo *df = find( mak, mod, iso, shut, t );
if( df ){ if( df ){
@ -408,35 +418,64 @@ int DFManager::scanBadPixelsFile( Glib::ustring filename )
dirpos1= dirpos2; dirpos1= dirpos2;
std::string makmodel(filename,dirpos1+1,lastdot-(dirpos1+1) ); std::string makmodel(filename,dirpos1+1,lastdot-(dirpos1+1) );
std::list<badPix> bp; std::vector<badPix> bp;
char line[256]; char line[256];
while( fgets(line,sizeof(line),file ) ){ if(fgets(line,sizeof(line),file )) {
int x,y; int x,y;
if( sscanf(line,"%d %d",&x,&y) == 2 ) int offset = 0;
bp.push_back( badPix(x,y) ); 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(); int numPixels = bp.size();
if( numPixels >0 ) if( numPixels >0 )
bpList[ makmodel ] = bp; bpList[ makmodel ] = bp;
fclose(file); fclose(file);
return numPixels; 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; bpList_t::iterator iter;
s << mak << " " <<mod; bool found = false;
if( !serial.empty()) if( !serial.empty() ) {
s << " " << serial; // search with sreial number first
bpList_t::iterator iter = bpList.find( s.str() ); std::ostringstream s;
if( iter != bpList.end() ){ s << mak << " " << mod << " " << serial;
if( settings->verbose ) iter = bpList.find( s.str() );
printf("Found:%s.badpixels in list\n",s.str().c_str()); if( iter != bpList.end() )
return &(iter->second); found = true;
} if( settings->verbose )
if( settings->verbose ) if(found)
printf("%s.badpixels not found\n",s.str().c_str()); printf("%s.badpixels found\n",s.str().c_str());
return 0; 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);
}
} }
// Global variable // Global variable

View File

@ -55,11 +55,11 @@ public:
std::string key(){ return key( maker,model,iso,shutter); } std::string key(){ return key( maker,model,iso,shutter); }
RawImage *getRawImage(); RawImage *getRawImage();
std::list<badPix> &getHotPixels(); std::vector<badPix> &getHotPixels();
protected: protected:
RawImage *ri; ///< Dark Frame raw data 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 updateBadPixelList( RawImage *df );
void updateRawImage(); void updateRawImage();
@ -73,13 +73,13 @@ public:
void getStat( int &totFiles, int &totTemplate); 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 std::string &mak, const std::string &mod, int iso, double shut, time_t t );
RawImage *searchDarkFrame( const Glib::ustring filename ); 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::vector<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::vector<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> *getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial);
protected: protected:
typedef std::multimap<std::string,dfInfo> dfList_t; 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; dfList_t dfList;
bpList_t bpList; bpList_t bpList;
bool initialized; bool initialized;

View File

@ -155,7 +155,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
rp.bayersensor.ccSteps = 0; rp.bayersensor.ccSteps = 0;
rp.xtranssensor.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); progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases);

View File

@ -120,7 +120,7 @@ enum ProcEvent {
EvLaCurve=95, EvLaCurve=95,
EvLbCurve=96, EvLbCurve=96,
EvDemosaicMethod=97, EvDemosaicMethod=97,
EvPreProcessHotDeadPixel=98, EvPreProcessHotPixel=98,
EvSaturation=99, EvSaturation=99,
EvHSVEqualizerH=100, EvHSVEqualizerH=100,
EvHSVEqualizerS=101, EvHSVEqualizerS=101,
@ -322,6 +322,7 @@ enum ProcEvent {
EvFilmSimulationFilename=294, EvFilmSimulationFilename=294,
EvDPDNLCurve=295, EvDPDNLCurve=295,
EvDPDNsmet=296, EvDPDNsmet=296,
EvPreProcessDeadPixel=297,
NUMOFEVENTS NUMOFEVENTS
}; };

View File

@ -835,7 +835,8 @@ void ProcParams::setDefaults () {
raw.cared = 0; raw.cared = 0;
raw.cablue = 0; raw.cablue = 0;
raw.ca_autocorrect = false; raw.ca_autocorrect = false;
raw.hotdeadpix_filt = false; raw.hotPixelFilter = false;
raw.deadPixelFilter = false;
raw.hotdeadpix_thresh = 40; raw.hotdeadpix_thresh = 40;
exif.clear (); exif.clear ();
iptc.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.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.caRed) keyFile.set_double ("RAW", "CARed", raw.cared );
if (!pedited || pedited->raw.caBlue) keyFile.set_double ("RAW", "CABlue", raw.cablue ); 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.hotDeadPixelThresh) keyFile.set_integer ("RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh );
if (!pedited || pedited->raw.bayersensor.method) keyFile.set_string ("RAW Bayer", "Method", raw.bayersensor.method ); 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", "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", "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", "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", "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", "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; } 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.ca_autocorrect == other.raw.ca_autocorrect
&& raw.cared == other.raw.cared && raw.cared == other.raw.cared
&& raw.cablue == other.raw.cablue && 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 && raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh
&& icm.input == other.icm.input && icm.input == other.icm.input
&& icm.toneCurve == other.icm.toneCurve && icm.toneCurve == other.icm.toneCurve

View File

@ -947,7 +947,8 @@ class RAWParams {
double expos; double expos;
double preser; double preser;
bool hotdeadpix_filt; bool hotPixelFilter;
bool deadPixelFilter;
int hotdeadpix_thresh; int hotdeadpix_thresh;
}; };

View File

@ -20,7 +20,6 @@
#define __RAWIMAGE_H #define __RAWIMAGE_H
#include <ctime> #include <ctime>
#include <glibmm.h>
#include "dcraw.h" #include "dcraw.h"
#include "imageio.h" #include "imageio.h"
@ -28,9 +27,9 @@ namespace rtengine {
struct badPix struct badPix
{ {
int x; uint16_t x;
int y; uint16_t y;
badPix( int xc, int yc ):x(xc),y(yc){} badPix( uint16_t xc, uint16_t yc ):x(xc),y(yc){}
}; };
class PixelsMap{ class PixelsMap{
@ -66,12 +65,12 @@ public:
} }
// set pixels from a list // set pixels from a list
int set( std::list<badPix> &bp) int set( std::vector<badPix> &bp)
{ {
int totSet=0; for(std::vector<badPix>::iterator iter = bp.begin(); iter != bp.end(); ++iter)
for(std::list<badPix>::iterator iter = bp.begin(); iter != bp.end(); iter++,totSet++)
set( iter->x,iter->y); set( iter->x,iter->y);
return totSet;
return bp.size();
} }
void clear(){ void clear(){
@ -156,6 +155,8 @@ public:
int get_thumbBPS(){ return thumb_load_raw ? 16 : 8; } int get_thumbBPS(){ return thumb_load_raw ? 16 : 8; }
bool get_thumbSwap() const; bool get_thumbSwap() const;
unsigned get_thumbLength(){ return thumb_length;} unsigned get_thumbLength(){ return thumb_length;}
bool zeroIsBad() {return zero_is_bad == 1 ? true : false;}
public: public:
// dcraw functions // dcraw functions
void scale_colors(){ if(isXtrans()) clearXtransCblack( ); DCraw::scale_colors(); } void scale_colors(){ if(isXtrans()) clearXtransCblack( ); DCraw::scale_colors(); }

View File

@ -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 * 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; int counter=0;
#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
for( int row = 2; row < H-2; row++ ){ for( int row = 2; row < H-2; row++ ){
for(int col = 2; col <W-2; col++ ){ for(int col = 2; col <W-2; col++ ){
int sk = bitmapBads.skipIfZero(col,row); //optimization for a stripe all zero 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 col +=sk-1; //-1 is because of col++ in cycle
continue; continue;
} }
if( ! bitmapBads.get(col,row ) ) if(!bitmapBads.get(col,row))
continue; continue;
double wtdsum=0,norm=0,sum=0,tot=0; float wtdsum=0.f,norm=0.f;
for( int dy=-2;dy<=2;dy+=2){
for( int dx=-2;dx<=2;dx+=2){ // diagonal interpolation
if (dy==0 && dx==0) continue; if(FC(row,col)==1) {
if( bitmapBads.get(col+dx,row+dy) ) continue; // green channel. We can use closer pixels than for red or blue channel. Distance to center pixel is sqrt(2) => weighting is 0.70710678
sum += rawData[row+dy][col+dx]; // For green channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
tot++; // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
if (bitmapBads.get(col-dx,row-dy)) continue; // 0 0 0 0 0
// 0 1 0 1 0
double dirwt = 1/( fabs( rawData[row+dy][col+dx]- rawData[row-dy][col-dx])+eps); // 0 0 0 0 0
wtdsum += dirwt* rawData[row+dy][col+dx]; // 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; norm += dirwt;
} }
} }
if (norm > 0.0){ // channel independent. Distance to center pixel is 2 => weighting is 0.5
rawData[row][col]= wtdsum / norm;//gradient weighted average // 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++; counter++;
} else { } else { //backup plan -- simple average. Same method for all channels. We could improve this, but it's really unlikely that this case happens
if (tot > 0.1) rawData[row][col] = sum/tot;//backup plan -- simple average 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) * (Taken from Emil Martinec idea)
* (Optimized by Ingo Weyrich 2013) * (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 // counter for dead or hot pixels
int counter=0; int counter=0;
@ -528,7 +589,7 @@ int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext], med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext],
rawData[i][jprev],rawData[i][j],rawData[i][jnext], rawData[i][jprev],rawData[i][j],rawData[i][jnext],
rawData[inext][jprev],rawData[inext][j],rawData[inext][jnext],temp); 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) #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++) { for (int cc=0; cc < W; cc++,rrmWpcc++) {
//evaluate pixel for heat/death //evaluate pixel for heat/death
float pixdev = cfablur[rrmWpcc]; float pixdev = cfablur[rrmWpcc];
if((!findDeadPixels) && pixdev <= 0)
continue;
if((!findHotPixels) && pixdev >= 0)
continue;
pixdev = fabsf(pixdev);
float hfnbrave = -pixdev; float hfnbrave = -pixdev;
int left=max(0,cc-2); int left=max(0,cc-2);
int right=min(W-1,cc+2); int right=min(W-1,cc+2);
for (int mm=top; mm<=bottom; mm++) { for (int mm=top; mm<=bottom; mm++) {
int mmmWpnn = mm*W+left; int mmmWpnn = mm*W+left;
for (int nn=left; nn<=right; nn++,mmmWpnn++) { 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" // mark the pixel as "bad"
bpMap.set(cc,rr); bpMap.set(cc,rr);
counter++; counter++;
@ -1015,7 +1081,23 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
if( rid && settings->verbose){ if( rid && settings->verbose){
printf( "Subtracting Darkframe:%s\n",rid->get_filename().c_str()); 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 //FLATFIELD start
Glib::ustring newFF = raw.ff_file; 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()); rif = ffm.searchFlatField( idata->getMake(), idata->getModel(),idata->getLens(),idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS());
} }
bool hasFlatField = (rif!=NULL); bool hasFlatField = (rif!=NULL);
if( hasFlatField && settings->verbose) { if( hasFlatField && settings->verbose) {
printf( "Flat Field Correction:%s\n",rif->get_filename().c_str()); printf( "Flat Field Correction:%s\n",rif->get_filename().c_str());
} }
copyOriginalPixels(raw, ri, rid, rif); copyOriginalPixels(raw, ri, rid, rif);
//FLATFIELD end //FLATFIELD end
PixelsMap bitmapBads(W,H);
int totBP=0; // Hold count of bad pixels to correct
// Always correct camera badpixels // Always correct camera badpixels from .badpixels file
std::list<badPix> *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), std::string("") ); std::vector<badPix> *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), idata->getSerialNumber() );
if( bp ){ if( bp ){
totBP+=bitmapBads.set( *bp ); totBP+=bitmapBads.set( *bp );
if( settings->verbose ){ 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) scaleColors( 0,0, W, H, raw);//+ + raw parameters for black level(raw.blackxx)
// Correct vignetting of lens profile // 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); defGain = 0.0;//log(initialGain) / log(2.0);
if ( raw.hotdeadpix_filt>0 ) { if ( raw.hotPixelFilter>0 || raw.deadPixelFilter>0) {
if (plistener) { if (plistener) {
plistener->setProgressStr ("Hot/Dead Pixel Filter..."); plistener->setProgressStr ("Hot/Dead Pixel Filter...");
plistener->setProgress (0.0); plistener->setProgress (0.0);
} }
float varthresh = (20.0*((float)raw.hotdeadpix_thresh/100.0) + 1.0 ); int nFound = findHotDeadPixels( bitmapBads, raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter );
int nFound =findHotDeadPixel( bitmapBads, varthresh );
totBP += nFound; totBP += nFound;
if( settings->verbose && nFound>0){ if( settings->verbose && nFound>0){
printf( "Correcting %d hot/dead pixels found inside image\n",nFound ); 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 // 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])) ) { 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])) ) {
@ -1136,6 +1214,10 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
green_equilibrate(0.01*(raw.bayersensor.greenthresh)); green_equilibrate(0.01*(raw.bayersensor.greenthresh));
} }
if( totBP )
interpolateBadPixels( bitmapBads );
if ( ri->getSensorType()==ST_BAYER && raw.bayersensor.linenoise >0 ) { if ( ri->getSensorType()==ST_BAYER && raw.bayersensor.linenoise >0 ) {
if (plistener) { if (plistener) {

View File

@ -217,8 +217,8 @@ class RawImageSource : public ImageSource {
void ddct8x8s(int isgn, float a[8][8]); void ddct8x8s(int isgn, float a[8][8]);
void processRawWhitepoint (float expos, float preser); // exposure before interpolation void processRawWhitepoint (float expos, float preser); // exposure before interpolation
int cfaCleanFromMap( PixelsMap &bitmapBads ); int interpolateBadPixels( PixelsMap &bitmapBads );
int findHotDeadPixel( PixelsMap &bpMap, float thresh); int findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels );
void cfa_linedn (float linenoiselevel);//Emil's line denoise 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 ); void cfa_tile_denoise (fftwf_complex * fcfablox, int vblk, int hblk, int numblox_H, int numblox_W, float noisevar, float * rolloff );

View File

@ -118,7 +118,7 @@ LUMINANCECURVE, // EvLSaturation,
LUMINANCECURVE, // EvLaCurve, LUMINANCECURVE, // EvLaCurve,
LUMINANCECURVE, // EvLbCurve, LUMINANCECURVE, // EvLbCurve,
DEMOSAIC, // EvDemosaicMethod DEMOSAIC, // EvDemosaicMethod
DARKFRAME, // EvPreProcessHotDeadPixel DARKFRAME, // EvPreProcessHotPixel
RGBCURVE, // EvSaturation, RGBCURVE, // EvSaturation,
RGBCURVE, // EvHSVEqualizerH, RGBCURVE, // EvHSVEqualizerH,
RGBCURVE, // EvHSVEqualizerS, RGBCURVE, // EvHSVEqualizerS,
@ -318,8 +318,8 @@ RGBCURVE, //EvFilmSimulationEnabled
RGBCURVE, //EvFilmSimulationStrength RGBCURVE, //EvFilmSimulationStrength
RGBCURVE, //EvFilmSimulationFilename RGBCURVE, //EvFilmSimulationFilename
ALLNORAW, // EvDPDNLCurve ALLNORAW, // EvDPDNLCurve
ALLNORAW // EvDPDNsmet ALLNORAW, // EvDPDNsmet
DARKFRAME // EvPreProcessDeadPixel
}; };

View File

@ -317,7 +317,8 @@ void ParamsEdited::set (bool v) {
raw.caCorrection = v; raw.caCorrection = v;
raw.caBlue = v; raw.caBlue = v;
raw.caRed = v; raw.caRed = v;
raw.hotDeadPixelFilter = v; raw.hotPixelFilter = v;
raw.deadPixelFilter = v;
raw.hotDeadPixelThresh = v; raw.hotDeadPixelThresh = v;
raw.darkFrame = v; raw.darkFrame = v;
raw.dfAuto = 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.caCorrection = raw.caCorrection && p.raw.ca_autocorrect == other.raw.ca_autocorrect;
raw.caRed = raw.caRed && p.raw.cared == other.raw.cared; raw.caRed = raw.caRed && p.raw.cared == other.raw.cared;
raw.caBlue = raw.caBlue && p.raw.cablue == other.raw.cablue; 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.hotDeadPixelThresh = raw.hotDeadPixelThresh && p.raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh;
raw.darkFrame = raw.darkFrame && p.raw.dark_frame == other.raw.dark_frame; 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.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.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.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.hotDeadPixelThresh) toEdit.raw.hotdeadpix_thresh = mods.raw.hotdeadpix_thresh;
if (raw.darkFrame) toEdit.raw.dark_frame = mods.raw.dark_frame; if (raw.darkFrame) toEdit.raw.dark_frame = mods.raw.dark_frame;
if (raw.dfAuto) toEdit.raw.df_autoselect = mods.raw.df_autoselect; if (raw.dfAuto) toEdit.raw.df_autoselect = mods.raw.df_autoselect;
@ -1042,7 +1045,7 @@ bool RAWParamsEdited::XTransSensor::isUnchanged() const {
} }
bool RAWParamsEdited::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; && dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && exPreser && ff_AutoClipControl && ff_clipControl;
} }

View File

@ -536,7 +536,8 @@ class RAWParamsEdited {
bool caCorrection; bool caCorrection;
bool caRed; bool caRed;
bool caBlue; bool caBlue;
bool hotDeadPixelFilter; bool hotPixelFilter;
bool deadPixelFilter;
bool hotDeadPixelThresh; bool hotDeadPixelThresh;
bool darkFrame; bool darkFrame;
bool dfAuto; bool dfAuto;

View File

@ -97,7 +97,8 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) {
raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO"))); raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO")));
raw_cared = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CARED"))); raw_cared = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CARED")));
raw_cablue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CABLUE"))); 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_linenoise = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_LINEDENOISE")));
raw_greenthresh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_GREENEQUIL"))); raw_greenthresh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_GREENEQUIL")));
raw_method = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DMETHOD"))); 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 (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0);
vboxes[6]->pack_start (*raw_linenoise, Gtk::PACK_SHRINK, 2); 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_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 (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0);
vboxes[6]->pack_start (*raw_expos, Gtk::PACK_SHRINK, 2); vboxes[6]->pack_start (*raw_expos, Gtk::PACK_SHRINK, 2);
vboxes[6]->pack_start (*raw_preser, 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_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_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_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_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)); 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)); 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_ca_autocorrectConn.block (true);
raw_caredConn.block (true); raw_caredConn.block (true);
raw_cablueConn.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_linenoiseConn.block (true);
raw_greenthreshConn.block (true); raw_greenthreshConn.block (true);
df_fileConn.block (true); df_fileConn.block (true);
@ -403,7 +407,8 @@ void PartialPasteDlg::rawToggled () {
raw_ca_autocorrect->set_active (raw->get_active ()); raw_ca_autocorrect->set_active (raw->get_active ());
raw_cared->set_active (raw->get_active ()); raw_cared->set_active (raw->get_active ());
raw_cablue->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_linenoise->set_active (raw->get_active ());
raw_greenthresh->set_active (raw->get_active ()); raw_greenthresh->set_active (raw->get_active ());
df_file->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_ca_autocorrectConn.block (false);
raw_caredConn.block (false); raw_caredConn.block (false);
raw_cablueConn.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_linenoiseConn.block (false);
raw_greenthreshConn.block (false); raw_greenthreshConn.block (false);
df_fileConn.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_ca_autocorrect->get_active ()) filterPE.raw.caCorrection = falsePE.raw.caCorrection;
if (!raw_cared->get_active ()) filterPE.raw.caRed = falsePE.raw.caRed; if (!raw_cared->get_active ()) filterPE.raw.caRed = falsePE.raw.caRed;
if (!raw_cablue->get_active ()) filterPE.raw.caBlue = falsePE.raw.caBlue; 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; } filterPE.raw.hotDeadPixelThresh = falsePE.raw.hotDeadPixelThresh; }
if (!df_file->get_active ()) filterPE.raw.darkFrame = falsePE.raw.darkFrame; if (!df_file->get_active ()) filterPE.raw.darkFrame = falsePE.raw.darkFrame;
if (!df_AutoSelect->get_active ()) filterPE.raw.dfAuto = falsePE.raw.dfAuto; if (!df_AutoSelect->get_active ()) filterPE.raw.dfAuto = falsePE.raw.dfAuto;

View File

@ -94,7 +94,8 @@ class PartialPasteDlg : public Gtk::Dialog {
Gtk::CheckButton* raw_ca_autocorrect; Gtk::CheckButton* raw_ca_autocorrect;
Gtk::CheckButton* raw_cared; Gtk::CheckButton* raw_cared;
Gtk::CheckButton* raw_cablue; 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_linenoise;
Gtk::CheckButton* raw_greenthresh; Gtk::CheckButton* raw_greenthresh;
Gtk::CheckButton* raw_method; Gtk::CheckButton* raw_method;
@ -121,7 +122,7 @@ class PartialPasteDlg : public Gtk::Dialog {
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn;
sigc::connection exifchConn, iptcConn, icmConn, gamcsconn; sigc::connection exifchConn, iptcConn, icmConn, gamcsconn;
sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; 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: public:
PartialPasteDlg (Glib::ustring title); PartialPasteDlg (Glib::ustring title);

View File

@ -26,54 +26,86 @@ using namespace rtengine::procparams;
PreProcess::PreProcess () : FoldableToolPanel(this) PreProcess::PreProcess () : FoldableToolPanel(this)
{ {
hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTDEADPIXFILT"))));
hotDeadPixel->set_tooltip_markup (M("TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP")); Gtk::HBox* hotdeadPixel = Gtk::manage( new Gtk::HBox () );
hotdeadPixel->set_spacing(4);
pack_start( *hotDeadPixel, Gtk::PACK_SHRINK, 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) void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
{ {
disableListener (); disableListener ();
hdpixelconn.block (true); hpixelconn.block (true);
dpixelconn.block (true);
if(pedited ){ 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); hpixelconn.block (false);
dpixelconn.block (false);
hdpixelconn.block (false);
enableListener (); enableListener ();
} }
void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) 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) { 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 (batchMode) {
if (hotDeadPixel->get_inconsistent()) { if (hotPixel->get_inconsistent()) {
hotDeadPixel->set_inconsistent (false); hotPixel->set_inconsistent (false);
hdpixelconn.block (true); hpixelconn.block (true);
hotDeadPixel->set_active (false); hotPixel->set_active (false);
hdpixelconn.block (false); hpixelconn.block (false);
} }
else if (lastHot) else if (lastHot)
hotDeadPixel->set_inconsistent (true); hotPixel->set_inconsistent (true);
lastHot = hotDeadPixel->get_active (); lastHot = hotPixel->get_active ();
} }
if (listener) 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"));
} }

View File

@ -27,10 +27,11 @@
class PreProcess : public ToolParamBlock, /*public AdjusterListener,*/ public FoldableToolPanel { class PreProcess : public ToolParamBlock, /*public AdjusterListener,*/ public FoldableToolPanel {
protected: protected:
Gtk::CheckButton* hotPixel;
Gtk::CheckButton* hotDeadPixel; Gtk::CheckButton* deadPixel;
bool lastHot; bool lastHot,lastDead;
sigc::connection hdpixelconn; sigc::connection hpixelconn;
sigc::connection dpixelconn;
public: public:
@ -41,7 +42,8 @@ class PreProcess : public ToolParamBlock, /*public AdjusterListener,*/ public Fo
//void setBatchMode (bool batchMode); //void setBatchMode (bool batchMode);
//void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); //void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void hotDeadPixelChanged(); void hotPixelChanged();
void deadPixelChanged();
//void adjusterChanged (Adjuster* a, double newval); //void adjusterChanged (Adjuster* a, double newval);
//void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd); //void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd);