Improved badpixels removal method. Fixed range of line noise slider. Put in possibility for AMaZE and fast_demo to process crops (not hooked up to GUI yet though).

This commit is contained in:
Emil Martinec
2010-09-25 15:25:36 -05:00
parent dc2350cee8
commit 23a8834755
6 changed files with 1059 additions and 36 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -27,9 +27,9 @@
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void RawImageSource::fast_demo() { void RawImageSource::fast_demo(int winx, int winy, int winw, int winh) {
int winx=0, winy=0; //int winx=0, winy=0;
int winw=W, winh=H; //int winw=W, winh=H;
if (plistener) { if (plistener) {
plistener->setProgressStr ("Fast demosaicing..."); plistener->setProgressStr ("Fast demosaicing...");

View File

@@ -540,7 +540,7 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) {
ppar.icm.input = "(none)"; ppar.icm.input = "(none)";
Image16* im = new Image16 (fW, fH); Image16* im = new Image16 (fW, fH);
imgsrc->preprocess( ppar.raw ); imgsrc->preprocess( ppar.raw );
imgsrc->demosaic( ppar.raw ); imgsrc->demosaic(ppar.raw );
imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.hlrecovery, ppar.icm, ppar.raw); imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.hlrecovery, ppar.icm, ppar.raw);
im->saveJPEG (fname, 85); im->saveJPEG (fname, 85);
mProcessing.unlock (); mProcessing.unlock ();

View File

@@ -331,8 +331,7 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe
*/ */
int RawImageSource::cfaCleanFromMap( BYTE* bitmapBads ) int RawImageSource::cfaCleanFromMap( BYTE* bitmapBads )
{ {
const int border=4; float eps=1.0;
double eps=1e-10;
int bmpW= (W/8+ (W%8?1:0)); int bmpW= (W/8+ (W%8?1:0));
int counter=0; int counter=0;
for( int row = 0; row < H; row++ ){ for( int row = 0; row < H; row++ ){
@@ -342,21 +341,26 @@ int RawImageSource::cfaCleanFromMap( BYTE* bitmapBads )
if( !(bitmapBads[ row *bmpW + col/8] & (1<<col%8)) ) continue; if( !(bitmapBads[ row *bmpW + col/8] & (1<<col%8)) ) continue;
double wtdsum=0,norm=0; double wtdsum=0,norm=0,sum=0,tot=0;
for( int dy=-2;dy<=2;dy+=2){ for( int dy=-2;dy<=2;dy+=2){
for( int dx=-2;dx<=2;dx+=2){ for( int dx=-2;dx<=2;dx+=2){
if (dy==0 && dx==0) continue; if (dy==0 && dx==0) continue;
if (row+dy<0 || row+dy>=H || col+dx<0 || row+dx>=W ) continue; if (row+dy<0 || row+dy>=H || col+dx<0 || col+dx>=W ) continue;
if (bitmapBads[ (row+dy) *bmpW + (col+dx)/8] & (1<<(col+dx)%8)) continue; if (bitmapBads[ (row+dy) *bmpW + (col+dx)/8] & (1<<(col+dx)%8)) continue;
sum += rawData[row+dy][col+dx];
tot++;
if (bitmapBads[ (row-dy) *bmpW + (col-dx)/8] & (1<<(col+dx)%8)) continue;
double dirwt = 1/( ( rawData[row+dy][col+dx]- rawData[row][col])*( rawData[row+dy][col+dx]- rawData[row][col])+eps); double dirwt = 1/( fabs( rawData[row+dy][col+dx]- rawData[row-dy][col-dx])+eps);
wtdsum += dirwt* rawData[row+dy][col+dx]; wtdsum += dirwt* rawData[row+dy][col+dx];
norm += dirwt; norm += dirwt;
} }
} }
if (norm > 0.){ if (norm > 0.0){
rawData[row][col]= wtdsum / norm;//low pass filter rawData[row][col]= wtdsum / norm;//gradient weighted average
counter++; counter++;
} else {
if (tot > 0) rawData[row][col] = sum/tot;//backup plan -- simple average
} }
} }
} }
@@ -370,7 +374,7 @@ int RawImageSource::cfaCleanFromMap( BYTE* bitmapBads )
int RawImageSource::findHotDeadPixel( BYTE *bpMap, float thresh) int RawImageSource::findHotDeadPixel( BYTE *bpMap, float thresh)
{ {
int bmpW= (W/8+ (W%8?1:0)); int bmpW= (W/8+ (W%8?1:0));
float eps=1e-10;//tolerance to avoid dividing by zero float eps=1e-3;//tolerance to avoid dividing by zero
int counter=0; int counter=0;
for (int rr=2; rr < H-2; rr++) for (int rr=2; rr < H-2; rr++)
for (int cc=2; cc < W-2; cc++) { for (int cc=2; cc < W-2; cc++) {
@@ -822,6 +826,20 @@ void RawImageSource::preprocess (const RAWParams &raw)
defGain = log(ri->defgain) / log(2.0); //\TODO ri->defgain should be "costant" defGain = log(ri->defgain) / log(2.0); //\TODO ri->defgain should be "costant"
if ( raw.hotdeadpix_filt ) {
if (plistener) {
plistener->setProgressStr ("Hot/Dead Pixel Filter...");
plistener->setProgress (0.0);
}
int nFound =findHotDeadPixel( bitmapBads,0.1 );
if( settings->verbose && nFound>0){
printf( "Correcting %d hot/dead pixels found inside image\n",nFound );
}
}
cfaCleanFromMap( bitmapBads );
delete [] 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 ( raw.greenthresh || (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,7)=="Panasonic")) && raw.dmethod != RAWParams::methodstring[ RAWParams::vng4] && ri->filters) ) { if ( raw.greenthresh || (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,7)=="Panasonic")) && raw.dmethod != RAWParams::methodstring[ RAWParams::vng4] && ri->filters) ) {
// global correction // global correction
@@ -855,18 +873,6 @@ void RawImageSource::preprocess (const RAWParams &raw)
green_equilibrate(0.01*(raw.greenthresh)); green_equilibrate(0.01*(raw.greenthresh));
} }
if ( raw.hotdeadpix_filt ) {
if (plistener) {
plistener->setProgressStr ("Hot/Dead Pixel Filter...");
plistener->setProgress (0.0);
}
int nFound =findHotDeadPixel( bitmapBads,0.1 );
if( settings->verbose && nFound>0){
printf( "Correcting %d hot/dead pixels found inside image\n",nFound );
}
}
cfaCleanFromMap( bitmapBads );
delete [] bitmapBads;
if ( raw.linenoise >0 ) { if ( raw.linenoise >0 ) {
if (plistener) { if (plistener) {
@@ -899,19 +905,19 @@ void RawImageSource::demosaic(const RAWParams &raw)
else if (raw.dmethod == RAWParams::methodstring[RAWParams::vng4] ) else if (raw.dmethod == RAWParams::methodstring[RAWParams::vng4] )
vng4_demosaic (); vng4_demosaic ();
else if (raw.dmethod == RAWParams::methodstring[RAWParams::ahd] ) else if (raw.dmethod == RAWParams::methodstring[RAWParams::ahd] )
ahd_demosaic (); ahd_demosaic (0,0,W,H);
else if (raw.dmethod == RAWParams::methodstring[RAWParams::amaze] ) else if (raw.dmethod == RAWParams::methodstring[RAWParams::amaze] )
amaze_demosaic_RT (); amaze_demosaic_RT (0,0,W,H);
else if (raw.dmethod == RAWParams::methodstring[RAWParams::dcb] ) else if (raw.dmethod == RAWParams::methodstring[RAWParams::dcb] )
dcb_demosaic(raw.dcb_iterations, raw.dcb_enhance? 1:0); dcb_demosaic(raw.dcb_iterations, raw.dcb_enhance? 1:0);
else if (raw.dmethod == RAWParams::methodstring[RAWParams::eahd]) else if (raw.dmethod == RAWParams::methodstring[RAWParams::eahd])
eahd_demosaic (); eahd_demosaic ();
else if (raw.dmethod == RAWParams::methodstring[RAWParams::fast] ) else if (raw.dmethod == RAWParams::methodstring[RAWParams::fast] )
fast_demo (); fast_demo (0,0,W,H);
else else
nodemosaic(); nodemosaic();
t2.set(); t2.set();
printf("Demosaicing: %s - %d <EFBFBD>sec\n",raw.dmethod.c_str(), t2.etime(t1)); printf("Demosaicing: %s - %d µsec\n",raw.dmethod.c_str(), t2.etime(t1));
} }
if (plistener) { if (plistener) {
plistener->setProgressStr ("Ready."); plistener->setProgressStr ("Ready.");
@@ -2662,7 +2668,7 @@ blue = new unsigned short*[H];
#define FORC3 FORC(3) #define FORC3 FORC(3)
#define SQR(x) ((x)*(x)) #define SQR(x) ((x)*(x))
void RawImageSource::ahd_demosaic() void RawImageSource::ahd_demosaic(int winx, int winy, int winw, int winh)
{ {
int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
ushort (*pix)[4], (*rix)[3]; ushort (*pix)[4], (*rix)[3];
@@ -3225,7 +3231,7 @@ void RawImageSource::dcb_refinement(ushort (*image)[4], int x0, int y0)
} }
} }
// missing colors are interpolated using high quality algorithm by Luis Sanz Rodríguez // missing colors are interpolated using high quality algorithm by Luis Sanz Rodr√≠guez
void RawImageSource::dcb_color_full(ushort (*image)[4], int x0, int y0, float (*chroma)[2]) void RawImageSource::dcb_color_full(ushort (*image)[4], int x0, int y0, float (*chroma)[2])
{ {
const int u=CACHESIZE, v=2*CACHESIZE, w=3*CACHESIZE; const int u=CACHESIZE, v=2*CACHESIZE, w=3*CACHESIZE;
@@ -3400,7 +3406,7 @@ void RawImageSource::dcb_demosaic(int iterations, int dcb_enhance)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//Emil's code for AMaZE //Emil's code for AMaZE
#include "fast_demo.cc"//fast demosaic #include "fast_demo.cc"//fast demosaic
#include "amaze_interpolate_RT.cc"//AMaZE demosaic #include "amaze_demosaic_RT.cc"//AMaZE demosaic
#include "CA_correct_RT.cc"//Emil's CA auto correction #include "CA_correct_RT.cc"//Emil's CA auto correction
#include "cfa_linedn_RT.cc"//Emil's CA auto correction #include "cfa_linedn_RT.cc"//Emil's CA auto correction
#include "green_equil_RT.cc"//Emil's green channel equilibration #include "green_equil_RT.cc"//Emil's green channel equilibration

View File

@@ -162,10 +162,10 @@ class RawImageSource : public ImageSource {
void hphd_demosaic(); void hphd_demosaic();
void vng4_demosaic(); void vng4_demosaic();
void ppg_demosaic(); void ppg_demosaic();
void amaze_demosaic_RT();//Emil's code for AMaZE void amaze_demosaic_RT(int winx, int winy, int winw, int winh);//Emil's code for AMaZE
void fast_demo();//Emil's code for fast demosaicing void fast_demo(int winx, int winy, int winw, int winh);//Emil's code for fast demosaicing
void dcb_demosaic(int iterations, int dcb_enhance); void dcb_demosaic(int iterations, int dcb_enhance);
void ahd_demosaic(); void ahd_demosaic(int winx, int winy, int winw, int winh);
void bilinear_demosaic(); void bilinear_demosaic();
void bilinear_interpolate_block(ushort (*image)[4], int start, int end); void bilinear_interpolate_block(ushort (*image)[4], int start, int end);
void border_interpolate(int border, ushort (*image)[4], int start = 0, int end = 0); void border_interpolate(int border, ushort (*image)[4], int start = 0, int end = 0);

View File

@@ -36,7 +36,7 @@ PreProcess::PreProcess ()
caAutocorrect = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_CACORRECTION")))); caAutocorrect = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_CACORRECTION"))));
hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_HOTDEADPIXFILT")))); hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_HOTDEADPIXFILT"))));
lineDenoise = Gtk::manage(new Adjuster (M("PREFERENCES_LINEDENOISE"),0,30,1,0)); lineDenoise = Gtk::manage(new Adjuster (M("PREFERENCES_LINEDENOISE"),0,1000,1,0));
lineDenoise->setAdjusterListener (this); lineDenoise->setAdjusterListener (this);
lineDenoise->show(); lineDenoise->show();