Added PixelsMap class and improved optimization with long

(removed non portable BYTE type)
This commit is contained in:
ffsup2
2011-01-02 23:47:12 +01:00
parent 610bec315d
commit 4c18afd84d
3 changed files with 77 additions and 27 deletions

View File

@@ -32,6 +32,57 @@ struct badPix
badPix( int xc, int yc ):x(xc),y(yc){}
};
class PixelsMap{
int w; // line width in base_t units
int h; // height
typedef unsigned long base_t;
static const size_t base_t_size=sizeof(base_t);
base_t *pm;
public:
PixelsMap(int width, int height )
:h(height){
w = (width+base_t_size-1) /base_t_size;
pm = new base_t [h * w ];
memset(pm,0,h * w *base_t_size );
}
~PixelsMap(){
delete [] pm;
}
int width() const { return w; }
int height() const { return h; }
// if a pixel is set returns true
bool get(int x, int y)
{
return (pm[y*w+ x/(base_t_size*8) ] & (base_t)1<<(x%(base_t_size*8)) )!=0;
}
// set a pixel
void set(int x, int y)
{
pm[y*w+ x/(base_t_size*8) ] |= (base_t)1<<(x%(base_t_size*8)) ;
}
// set pixels from a list
int set( std::list<badPix> &bp)
{
int totSet=0;
for(std::list<badPix>::iterator iter = bp.begin(); iter != bp.end(); iter++,totSet++)
set( iter->x,iter->y);
return totSet;
}
void clear(){
memset(pm,0,h * w *base_t_size );
}
// return 0 if at least one pixel in the word(base_t) is set, otherwise return the number of pixels to skip to the next word base_t
int skipIfZero(int x, int y){
return pm[y*w+ x/(base_t_size*8) ]==0 ? base_t_size*8 -x%(base_t_size*8):0;
}
};
class RawImage: public DCraw
{
public:

View File

@@ -363,26 +363,28 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe
/* cfaCleanFromMap: correct raw pixels looking at the bitmap
* takes into consideration if there are multiple bad pixels in the neighborhood
*/
int RawImageSource::cfaCleanFromMap( BYTE* bitmapBads )
int RawImageSource::cfaCleanFromMap( PixelsMap &bitmapBads )
{
float eps=1.0;
int bmpW= (W/8+ (W%8?1:0));
int counter=0;
for( int row = 2; row < H-2; row++ ){
for(int col = 2; col <W-2; col++ ){
if( !bitmapBads[ row *bmpW + col/8] ){ col+=7;continue; } //optimization
if( !(bitmapBads[ row *bmpW + col/8] & (1<<col%8)) ) continue;
int sk = bitmapBads.skipIfZero(col,row); //optimization for a stripe all zero
if( sk ){
col +=sk-1; //-1 is because of col++ in cycle
continue;
}
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[ (row+dy) *bmpW + (col+dx)/8] & (1<<(col+dx)%8)) continue;
if( bitmapBads.get(col+dx,row+dy) ) continue;
sum += rawData[row+dy][col+dx];
tot++;
if (bitmapBads[ (row-dy) *bmpW + (col-dx)/8] & (1<<(col-dx)%8)) continue;
if (bitmapBads.get(col-dx,row-dy)) continue;
double dirwt = 1/( fabs( rawData[row+dy][col+dx]- rawData[row-dy][col-dx])+eps);
wtdsum += dirwt* rawData[row+dy][col+dx];
@@ -404,9 +406,8 @@ int RawImageSource::cfaCleanFromMap( BYTE* bitmapBads )
* For each pixel compare its value to the average of similar color surrounding
* (Taken from Emil Martinec idea)
*/
int RawImageSource::findHotDeadPixel( BYTE *bpMap, float thresh)
int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
{
int bmpW= (W/8+ (W%8?1:0));
float eps=1e-3;//tolerance to avoid dividing by zero
int counter=0;
for (int rr=2; rr < H-2; rr++)
@@ -419,7 +420,7 @@ int RawImageSource::findHotDeadPixel( BYTE *bpMap, float thresh)
if (pixratio > thresh) continue;
// mark the pixel as "bad"
bpMap[rr*bmpW+cc/8 ] |= 1<<(cc%8);
bpMap.set(cc,rr );
counter++;
}
return counter;
@@ -829,7 +830,7 @@ int RawImageSource::load (Glib::ustring fname, bool batch) {
plistener=NULL; // This must be reset, because only load() is called through progressConnector
t2.set();
if( settings->verbose )
printf("Load %s: %d µsec\n",fname.c_str(), t2.etime(t1));
printf("Load %s: %d usec\n",fname.c_str(), t2.etime(t1));
return 0; // OK!
}
@@ -850,27 +851,26 @@ void RawImageSource::preprocess (const RAWParams &raw)
printf( "Subtracting Darkframe:%s\n",rid->get_filename().c_str());
}
copyOriginalPixels(ri, rid);
size_t widthBitmap = (W/8+ (W%8?1:0));
size_t dimBitmap = widthBitmap*H;
BYTE *bitmapBads = new BYTE [ dimBitmap ];
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("") );
if( bp ){
for(std::list<badPix>::iterator iter = bp->begin(); iter != bp->end(); iter++,totBP++)
bitmapBads[ widthBitmap * (iter->y) + (iter->x)/8] |= 1<<(iter->x%8);
totBP+=bitmapBads.set( *bp );
if( settings->verbose ){
std::cout << "Correcting " << bp->size() << " pixels from .badpixels" << std::endl;
}
}
// If darkframe selected, correct hotpixels found on darkframe
bp = 0;
if( raw.df_autoselect ){
bp = dfm.getHotPixels( ri->get_maker(), ri->get_model(), ri->get_ISOspeed(), ri->get_shutter(), ri->get_timestamp());
}else if( raw.dark_frame.size()>0 )
bp = dfm.getHotPixels( raw.dark_frame );
if(bp){
for(std::list<badPix>::iterator iter = bp->begin(); iter != bp->end(); iter++,totBP++)
bitmapBads[ widthBitmap *iter->y + iter->x/8] |= 1<<(iter->x%8);
totBP+=bitmapBads.set( *bp );
if( settings->verbose && bp->size()>0){
std::cout << "Correcting " << bp->size() << " hotpixels from darkframe" << std::endl;
}
@@ -893,7 +893,6 @@ void RawImageSource::preprocess (const RAWParams &raw)
}
if( totBP )
cfaCleanFromMap( bitmapBads );
delete [] bitmapBads;
// 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->isBayer()) ) {
@@ -955,7 +954,7 @@ void RawImageSource::preprocess (const RAWParams &raw)
}
t2.set();
if( settings->verbose )
printf("Preprocessing: %d µsec\n", t2.etime(t1));
printf("Preprocessing: %d usec\n", t2.etime(t1));
return;
}
void RawImageSource::demosaic(const RAWParams &raw)
@@ -981,7 +980,7 @@ void RawImageSource::demosaic(const RAWParams &raw)
nodemosaic();
t2.set();
if( settings->verbose )
printf("Demosaicing: %s - %d µsec\n",raw.dmethod.c_str(), t2.etime(t1));
printf("Demosaicing: %s - %d usec\n",raw.dmethod.c_str(), t2.etime(t1));
}
if (plistener) {
plistener->setProgressStr ("Ready.");
@@ -2075,8 +2074,8 @@ int RawImageSource::getAEHistogram (unsigned int* histogram, int& histcompr) {
bn = rn;
}
}
printf ("AVG: %g %g %g\n", avg_r/rn, avg_g/gn, avg_b/bn);
if( settings->verbose )
printf ("AVG: %g %g %g\n", avg_r/rn, avg_g/gn, avg_b/bn);
// return ColorTemp (pow(avg_r/rn, 1.0/6.0)*img_r, pow(avg_g/gn, 1.0/6.0)*img_g, pow(avg_b/bn, 1.0/6.0)*img_b);

View File

@@ -150,8 +150,8 @@ class RawImageSource : public ImageSource {
int LinEqSolve( int nDim, float* pfMatr, float* pfVect, float* pfSolution);//Emil's CA auto correction
void CA_correct_RT (double cared, double cablue);
int cfaCleanFromMap( BYTE* bitmapBads );
int findHotDeadPixel( BYTE *bpMap, float thresh);
int cfaCleanFromMap( PixelsMap &bitmapBads );
int findHotDeadPixel( PixelsMap &bpMap, float thresh);
void ddct8x8s(int isgn, float **a);
void cfa_linedn (float linenoiselevel);//Emil's line denoise