Bilinear demosaic from dcraw + omp support. Faster then light! Great for previews.
This commit is contained in:
@@ -906,6 +906,8 @@ int RawImageSource::load (Glib::ustring fname) {
|
||||
vng4_demosaic ();
|
||||
else if (settings->demosaicMethod=="ahd")
|
||||
ahd_demosaic ();
|
||||
else if (settings->demosaicMethod=="bilinear")
|
||||
bilinear_demosaic();
|
||||
//else if (settings->demosaicMethod=="ppg")
|
||||
// ppg_demosaic ();
|
||||
else if (settings->demosaicMethod=="amaze")
|
||||
@@ -2339,13 +2341,14 @@ void RawImageSource::ppg_demosaic()
|
||||
free (image);
|
||||
}
|
||||
|
||||
void RawImageSource::border_interpolate(int border, ushort (*image)[4])
|
||||
void RawImageSource::border_interpolate(int border, ushort (*image)[4], int start, int end)
|
||||
{
|
||||
unsigned row, col, y, x, f, c, sum[8];
|
||||
int width=W, height=H;
|
||||
int colors = 3;
|
||||
|
||||
for (row=0; row < height; row++)
|
||||
if (end == 0 )end = H;
|
||||
for (row=start; row < end; row++)
|
||||
for (col=0; col < width; col++) {
|
||||
if (col==border && row >= border && row < height-border)
|
||||
col = width-border;
|
||||
@@ -2363,6 +2366,110 @@ void RawImageSource::border_interpolate(int border, ushort (*image)[4])
|
||||
}
|
||||
}
|
||||
|
||||
void RawImageSource::bilinear_interpolate_block(ushort (*image)[4], int start, int end)
|
||||
{
|
||||
ushort (*pix);
|
||||
int i, *ip, sum[4];
|
||||
int width=W;
|
||||
int colors = 3;
|
||||
|
||||
for (int row = start; row < end; row++)
|
||||
for (int col=1; col < width-1; col++) {
|
||||
pix = image[row*width+col];
|
||||
ip = blcode[row & 15][col & 15];
|
||||
memset (sum, 0, sizeof sum);
|
||||
for (i=8; i--; ip+=3)
|
||||
sum[ip[2]] += pix[ip[0]] << ip[1];
|
||||
for (i=colors; --i; ip+=2)
|
||||
pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
|
||||
}
|
||||
|
||||
for (int i=start; i<end; i++) {
|
||||
red[i] = new unsigned short[W];
|
||||
green[i] = new unsigned short[W];
|
||||
blue[i] = new unsigned short[W];
|
||||
for (int j=0; j<W; j++){
|
||||
red[i][j] = image[i*W+j][0];
|
||||
green[i][j] = image[i*W+j][1];
|
||||
blue[i][j] = image[i*W+j][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RawImageSource::bilinear_demosaic()
|
||||
{
|
||||
int width=W, height=H;
|
||||
int *ip, sum[4];
|
||||
int c, x, y, row, col, shift, color;
|
||||
int colors = 3;
|
||||
|
||||
ushort (*image)[4], *pix;
|
||||
image = (ushort (*)[4]) calloc (H*W, sizeof *image);
|
||||
|
||||
for (int ii=0; ii<H; ii++)
|
||||
for (int jj=0; jj<W; jj++)
|
||||
image[ii*W+jj][fc(ii,jj)] = ri->data[ii][jj];
|
||||
|
||||
//if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
|
||||
if (plistener) {
|
||||
plistener->setProgressStr ("Demosaicing...");
|
||||
plistener->setProgress (0.0);
|
||||
}
|
||||
|
||||
for (row=0; row < 16; row++)
|
||||
for (col=0; col < 16; col++) {
|
||||
ip = blcode[row][col];
|
||||
memset (sum, 0, sizeof sum);
|
||||
for (y=-1; y <= 1; y++)
|
||||
for (x=-1; x <= 1; x++) {
|
||||
shift = (y==0) + (x==0);
|
||||
if (shift == 2) continue;
|
||||
color = fc(row+y,col+x);
|
||||
*ip++ = (width*y + x)*4 + color;
|
||||
*ip++ = shift;
|
||||
*ip++ = color;
|
||||
sum[color] += 1 << shift;
|
||||
}
|
||||
FORCC
|
||||
if (c != fc(row,col)) {
|
||||
*ip++ = c;
|
||||
*ip++ = 256 / sum[c];
|
||||
}
|
||||
}
|
||||
|
||||
red = new unsigned short*[H];
|
||||
green = new unsigned short*[H];
|
||||
blue = new unsigned short*[H];
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
{
|
||||
int tid = omp_get_thread_num();
|
||||
int nthreads = omp_get_num_threads();
|
||||
int blk = W/nthreads;
|
||||
|
||||
int start = 0;
|
||||
if (tid == 0) start = 1;
|
||||
if (tid<nthreads-1)
|
||||
{
|
||||
border_interpolate(1, image, tid*blk, (tid+1)*blk);
|
||||
bilinear_interpolate_block(image, start+tid*blk, (tid+1)*blk);
|
||||
}
|
||||
else
|
||||
{
|
||||
border_interpolate(1, image, tid*blk, height);
|
||||
bilinear_interpolate_block(image, tid*blk, height-1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
border_interpolate(1, image);
|
||||
bilinear_interpolate_block(image, 1, height-1);
|
||||
#endif
|
||||
|
||||
if(plistener) plistener->setProgress (1.0);
|
||||
free (image);
|
||||
}
|
||||
|
||||
/*
|
||||
Adaptive Homogeneity-Directed interpolation is based on
|
||||
the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
|
||||
|
@@ -65,6 +65,7 @@ class RawImageSource : public ImageSource {
|
||||
char** needhr; // for color propagation
|
||||
int max[3];
|
||||
double defGain;
|
||||
int blcode[16][16][32];
|
||||
bool full;
|
||||
Glib::ustring oldmethod;
|
||||
cmsHPROFILE camProfile;
|
||||
@@ -154,7 +155,9 @@ class RawImageSource : public ImageSource {
|
||||
void amaze_demosaic_RT ();//Emil's code for AMaZE
|
||||
void dcb_demosaic(int iterations, int dcb_enhance);
|
||||
void ahd_demosaic();
|
||||
void border_interpolate(int border, ushort (*image)[4]);
|
||||
void bilinear_demosaic();
|
||||
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 dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border);
|
||||
void fill_raw( ushort (*cache )[4], int x0, int y0, ushort** rawData);
|
||||
void fill_border( ushort (*cache )[4], int border, int x0, int y0);
|
||||
|
@@ -25,7 +25,7 @@ namespace rtengine {
|
||||
class Settings {
|
||||
public:
|
||||
bool dualThreadEnabled; ///< If true, the image processing operations with utilize two processor cores (if possible)
|
||||
std::string demosaicMethod; ///< The algorithm used for demosaicing. Can be "eahd", "hphd" or "vng4".
|
||||
std::string demosaicMethod; ///< The algorithm used for demosaicing. Can be "eahd", "hphd", "ahd", "vng4", "amaze", "bilinear".
|
||||
int colorCorrectionSteps; ///< The number of color correction steps applied right after the demosaicing
|
||||
Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles
|
||||
int colorimetricIntent; ///< Colorimetric intent used at color space conversions
|
||||
|
@@ -267,6 +267,7 @@ Gtk::Widget* Preferences::getProcParamsPanel () {
|
||||
dmethod->append_text ("AMaZE");//Emil's code for AMaZE
|
||||
dmethod->append_text ("DCB");
|
||||
dmethod->append_text ("AHD");
|
||||
dmethod->append_text ("Bilinear");
|
||||
Gtk::Label* cclab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FALSECOLOR")+":"));
|
||||
ccSteps = Gtk::manage (new Gtk::SpinButton ());
|
||||
ccSteps->set_digits (0);
|
||||
@@ -748,6 +749,8 @@ void Preferences::storePreferences () {
|
||||
moptions.rtSettings.demosaicMethod = "dcb";
|
||||
else if (dmethod->get_active_row_number()==5)
|
||||
moptions.rtSettings.demosaicMethod = "ahd";
|
||||
else if (dmethod->get_active_row_number()==6)
|
||||
moptions.rtSettings.demosaicMethod = "bilinear";
|
||||
moptions.rtSettings.dcb_iterations=(int)dcbIterations->get_value();
|
||||
moptions.rtSettings.dcb_enhance=dcbEnhance->get_active();
|
||||
moptions.rtSettings.ca_autocorrect=caAutoCorrect->get_active();//Emil's CA correction
|
||||
@@ -848,6 +851,8 @@ void Preferences::fillPreferences () {
|
||||
dmethod->set_active (4);
|
||||
else if (moptions.rtSettings.demosaicMethod=="ahd")
|
||||
dmethod->set_active (5);
|
||||
else if (moptions.rtSettings.demosaicMethod=="bilinear")
|
||||
dmethod->set_active (6);
|
||||
dcbEnhance->set_active(moptions.rtSettings.dcb_enhance);
|
||||
dcbIterations->set_value(moptions.rtSettings.dcb_iterations);
|
||||
dcbEnhance->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb");
|
||||
|
Reference in New Issue
Block a user