further speedup for histogram matching

This commit is contained in:
heckflosse
2018-02-01 18:44:25 +01:00
parent 7848915e58
commit 00d6da7d89
2 changed files with 133 additions and 133 deletions

View File

@@ -395,7 +395,7 @@ RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname)
return rml; return rml;
} }
Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool multiThread) Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching)
{ {
RawImage *ri = new RawImage (fname); RawImage *ri = new RawImage (fname);
unsigned int tempImageNum = 0; unsigned int tempImageNum = 0;
@@ -427,10 +427,9 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
tpp->greenMultiplier = ri->get_pre_mul (1); tpp->greenMultiplier = ri->get_pre_mul (1);
tpp->blueMultiplier = ri->get_pre_mul (2); tpp->blueMultiplier = ri->get_pre_mul (2);
//ri->scale_colors();
float pre_mul[4], scale_mul[4], cblack[4]; float pre_mul[4], scale_mul[4], cblack[4];
ri->get_colorsCoeff (pre_mul, scale_mul, cblack, false); ri->get_colorsCoeff (pre_mul, scale_mul, cblack, false);
scale_colors (ri, scale_mul, cblack, multiThread); scale_colors (ri, scale_mul, cblack, forHistogramMatching); // enable multithreading when forHistogramMatching is true
ri->pre_interpolate(); ri->pre_interpolate();
@@ -672,154 +671,155 @@ Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocati
} else { } else {
tpp->scale = (double) height / (rotate_90 ? w : h); tpp->scale = (double) height / (rotate_90 ? w : h);
} }
if(!forHistogramMatching) { // we don't need this for histogram matching
// generate histogram for auto exposure, also calculate autoWB // generate histogram for auto exposure, also calculate autoWB
tpp->aeHistCompression = 3; tpp->aeHistCompression = 3;
tpp->aeHistogram(65536 >> tpp->aeHistCompression); tpp->aeHistogram(65536 >> tpp->aeHistCompression);
tpp->aeHistogram.clear(); tpp->aeHistogram.clear();
const unsigned int add = filter ? 1 : 4 / ri->get_colors(); const unsigned int add = filter ? 1 : 4 / ri->get_colors();
double pixSum[3] = {0.0}; double pixSum[3] = {0.0};
unsigned int n[3] = {0}; unsigned int n[3] = {0};
const double compression = pow(2.0, tpp->aeHistCompression); const double compression = pow(2.0, tpp->aeHistCompression);
const double camWb[3] = {tpp->camwbRed / compression, tpp->camwbGreen / compression, tpp->camwbBlue / compression}; const double camWb[3] = {tpp->camwbRed / compression, tpp->camwbGreen / compression, tpp->camwbBlue / compression};
const double clipval = 64000.0 / tpp->defGain; const double clipval = 64000.0 / tpp->defGain;
for (int i = 32; i < height - 32; i++) { for (int i = 32; i < height - 32; i++) {
int start, end; int start, end;
if (ri->get_FujiWidth() != 0) { if (ri->get_FujiWidth() != 0) {
int fw = ri->get_FujiWidth(); int fw = ri->get_FujiWidth();
start = ABS (fw - i) + 32; start = ABS (fw - i) + 32;
end = min (height + width - fw - i, fw + i) - 32; end = min (height + width - fw - i, fw + i) - 32;
} else { } else {
start = 32; start = 32;
end = width - 32; end = width - 32;
}
if (ri->get_colors() == 1) {
for (int j = start; j < end; j++) {
tpp->aeHistogram[image[i * width + j][0] >> tpp->aeHistCompression]++;
} }
} else if (ri->getSensorType() == ST_BAYER) {
int c0 = ri->FC(i, start); if (ri->get_colors() == 1) {
int c1 = ri->FC(i, start + 1); for (int j = start; j < end; j++) {
int j = start; tpp->aeHistogram[image[i * width + j][0] >> tpp->aeHistCompression]++;
int n0 = 0;
int n1 = 0;
double pixSum0 = 0.0;
double pixSum1 = 0.0;
for (; j < end - 1; j+=2) {
double v0 = image[i * width + j][c0];
tpp->aeHistogram[(int)(camWb[c0] * v0)]++;
if (v0 <= clipval) {
pixSum0 += v0;
n0++;
} }
double v1 = image[i * width + j + 1][c1]; } else if (ri->getSensorType() == ST_BAYER) {
tpp->aeHistogram[(int)(camWb[c1] * v1)]++; int c0 = ri->FC(i, start);
if (v1 <= clipval) { int c1 = ri->FC(i, start + 1);
pixSum1 += v1; int j = start;
n1++; int n0 = 0;
int n1 = 0;
double pixSum0 = 0.0;
double pixSum1 = 0.0;
for (; j < end - 1; j+=2) {
double v0 = image[i * width + j][c0];
tpp->aeHistogram[(int)(camWb[c0] * v0)]++;
if (v0 <= clipval) {
pixSum0 += v0;
n0++;
}
double v1 = image[i * width + j + 1][c1];
tpp->aeHistogram[(int)(camWb[c1] * v1)]++;
if (v1 <= clipval) {
pixSum1 += v1;
n1++;
}
} }
} if (j < end) {
if (j < end) { double v0 = image[i * width + j][c0];
double v0 = image[i * width + j][c0]; tpp->aeHistogram[(int)(camWb[c0] * v0)]++;
tpp->aeHistogram[(int)(camWb[c0] * v0)]++; if (v0 <= clipval) {
if (v0 <= clipval) { pixSum0 += v0;
pixSum0 += v0; n0++;
n0++; }
} }
} n[c0] += n0;
n[c0] += n0; n[c1] += n1;
n[c1] += n1; pixSum[c0] += pixSum0;
pixSum[c0] += pixSum0; pixSum[c1] += pixSum1;
pixSum[c1] += pixSum1; } else if (ri->getSensorType() == ST_FUJI_XTRANS) {
} else if (ri->getSensorType() == ST_FUJI_XTRANS) { int c[6];
int c[6];
for(int cc = 0; cc < 6; ++cc) {
c[cc] = ri->XTRANSFC(i, start + cc);
}
int j = start;
for (; j < end - 5; j += 6) {
for(int cc = 0; cc < 6; ++cc) { for(int cc = 0; cc < 6; ++cc) {
double d = image[i * width + j + cc][c[cc]]; c[cc] = ri->XTRANSFC(i, start + cc);
tpp->aeHistogram[(int)(camWb[c[cc]] * d)]++; }
if (d <= clipval) { int j = start;
pixSum[c[cc]] += d; for (; j < end - 5; j += 6) {
n[c[cc]]++; for(int cc = 0; cc < 6; ++cc) {
double d = image[i * width + j + cc][c[cc]];
tpp->aeHistogram[(int)(camWb[c[cc]] * d)]++;
if (d <= clipval) {
pixSum[c[cc]] += d;
n[c[cc]]++;
}
} }
} }
} for (; j < end; j++) {
for (; j < end; j++) { if (ri->ISXTRANSGREEN (i, j)) {
if (ri->ISXTRANSGREEN (i, j)) { double d = image[i * width + j][1];
double d = image[i * width + j][1]; tpp->aeHistogram[(int)(camWb[1] * d)]++;
tpp->aeHistogram[(int)(camWb[1] * d)]++; if (d <= clipval) {
if (d <= clipval) { pixSum[1] += d;
pixSum[1] += d; n[1]++;
n[1]++; }
} else if (ri->ISXTRANSRED (i, j)) {
double d = image[i * width + j][0];
tpp->aeHistogram[(int)(camWb[0] * d)]++;
if (d <= clipval) {
pixSum[0] += d;
n[0]++;
}
} else if (ri->ISXTRANSBLUE (i, j)) {
double d = image[i * width + j][2];
tpp->aeHistogram[(int)(camWb[2] * d)]++;
if (d <= clipval) {
pixSum[2] += d;
n[2]++;
}
} }
} else if (ri->ISXTRANSRED (i, j)) { }
double d = image[i * width + j][0]; } else { /* if(ri->getSensorType()==ST_FOVEON) */
tpp->aeHistogram[(int)(camWb[0] * d)]++; for (int j = start; j < end; j++) {
if (d <= clipval) { double r = image[i * width + j][0];
pixSum[0] += d; if (r <= clipval) {
pixSum[0] += r;
n[0]++; n[0]++;
} }
} else if (ri->ISXTRANSBLUE (i, j)) { double g = image[i * width + j][1];
double d = image[i * width + j][2]; if (g <= clipval) {
tpp->aeHistogram[(int)(camWb[2] * d)]++; pixSum[1] += g;
if (d <= clipval) { n[1]++;
pixSum[2] += d; }
tpp->aeHistogram[((int)g) >> tpp->aeHistCompression] += add;
double b = image[i * width + j][2];
if (b <= clipval) {
pixSum[2] += b;
n[2]++; n[2]++;
} }
tpp->aeHistogram[((int) (b * 0.5f)) >> tpp->aeHistCompression] += add;
} }
} }
} else { /* if(ri->getSensorType()==ST_FOVEON) */
for (int j = start; j < end; j++) {
double r = image[i * width + j][0];
if (r <= clipval) {
pixSum[0] += r;
n[0]++;
}
double g = image[i * width + j][1];
if (g <= clipval) {
pixSum[1] += g;
n[1]++;
}
tpp->aeHistogram[((int)g) >> tpp->aeHistCompression] += add;
double b = image[i * width + j][2];
if (b <= clipval) {
pixSum[2] += b;
n[2]++;
}
tpp->aeHistogram[((int) (b * 0.5f)) >> tpp->aeHistCompression] += add;
}
} }
if (ri->get_colors() == 1) {
pixSum[0] = pixSum[1] = pixSum[2] = 1.;
n[0] = n[1] = n[2] = 1;
}
pixSum[0] *= tpp->defGain;
pixSum[1] *= tpp->defGain;
pixSum[2] *= tpp->defGain;
double reds = pixSum[0] / std::max(n[0], 1u) * tpp->camwbRed;
double greens = pixSum[1] / std::max(n[1], 1u) * tpp->camwbGreen;
double blues = pixSum[2] / std::max(n[2], 1u) * tpp->camwbBlue;
tpp->redAWBMul = ri->get_rgb_cam (0, 0) * reds + ri->get_rgb_cam (0, 1) * greens + ri->get_rgb_cam (0, 2) * blues;
tpp->greenAWBMul = ri->get_rgb_cam (1, 0) * reds + ri->get_rgb_cam (1, 1) * greens + ri->get_rgb_cam (1, 2) * blues;
tpp->blueAWBMul = ri->get_rgb_cam (2, 0) * reds + ri->get_rgb_cam (2, 1) * greens + ri->get_rgb_cam (2, 2) * blues;
tpp->wbEqual = wbEq;
tpp->wbTempBias = 0.0;
ColorTemp cTemp;
cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen);
} }
if (ri->get_colors() == 1) {
pixSum[0] = pixSum[1] = pixSum[2] = 1.;
n[0] = n[1] = n[2] = 1;
}
pixSum[0] *= tpp->defGain;
pixSum[1] *= tpp->defGain;
pixSum[2] *= tpp->defGain;
double reds = pixSum[0] / std::max(n[0], 1u) * tpp->camwbRed;
double greens = pixSum[1] / std::max(n[1], 1u) * tpp->camwbGreen;
double blues = pixSum[2] / std::max(n[2], 1u) * tpp->camwbBlue;
tpp->redAWBMul = ri->get_rgb_cam (0, 0) * reds + ri->get_rgb_cam (0, 1) * greens + ri->get_rgb_cam (0, 2) * blues;
tpp->greenAWBMul = ri->get_rgb_cam (1, 0) * reds + ri->get_rgb_cam (1, 1) * greens + ri->get_rgb_cam (1, 2) * blues;
tpp->blueAWBMul = ri->get_rgb_cam (2, 0) * reds + ri->get_rgb_cam (2, 1) * greens + ri->get_rgb_cam (2, 2) * blues;
tpp->wbEqual = wbEq;
tpp->wbTempBias = 0.0;
ColorTemp cTemp;
cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen);
if (rotate && ri->get_rotateDegree() > 0) { if (rotate && ri->get_rotateDegree() > 0) {
tpp->thumbImg->rotate (ri->get_rotateDegree()); tpp->thumbImg->rotate (ri->get_rotateDegree());
} }
@@ -930,7 +930,7 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int
} }
// Full thumbnail processing, second stage if complete profile exists // Full thumbnail processing, second stage if complete profile exists
IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& myscale, bool forMonitor, bool multiThread) IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& myscale, bool forMonitor, bool forHistogramMatching)
{ {
unsigned int imgNum = 0; unsigned int imgNum = 0;
if (isRaw) { if (isRaw) {
@@ -1062,7 +1062,7 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT
int fh = baseImg->getHeight(); int fh = baseImg->getHeight();
//ColorTemp::CAT02 (baseImg, &params) ;//perhaps not good! //ColorTemp::CAT02 (baseImg, &params) ;//perhaps not good!
ImProcFunctions ipf (&params, multiThread); ImProcFunctions ipf (&params, forHistogramMatching); // enable multithreading when forHistogramMatching is true
ipf.setScale (sqrt (double (fw * fw + fh * fh)) / sqrt (double (thumbImg->getWidth() * thumbImg->getWidth() + thumbImg->getHeight() * thumbImg->getHeight()))*scale); ipf.setScale (sqrt (double (fw * fw + fh * fh)) / sqrt (double (thumbImg->getWidth() * thumbImg->getWidth() + thumbImg->getHeight() * thumbImg->getHeight()))*scale);
ipf.updateColorProfiles (ICCStore::getInstance()->getDefaultMonitorProfileName(), options.rtSettings.monitorIntent, false, false); ipf.updateColorProfiles (ICCStore::getInstance()->getDefaultMonitorProfileName(), options.rtSettings.monitorIntent, false, false);

View File

@@ -71,13 +71,13 @@ public:
void init (); void init ();
IImage8* processImage (const procparams::ProcParams& pparams, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& scale, bool forMonitor=true, bool multiThread = false); IImage8* processImage (const procparams::ProcParams& pparams, eSensorType sensorType, int rheight, TypeInterpolation interp, const FramesMetaData *metadata, double& scale, bool forMonitor=true, bool forHistogramMatching = false);
IImage8* quickProcessImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp); IImage8* quickProcessImage (const procparams::ProcParams& pparams, int rheight, TypeInterpolation interp);
int getImageWidth (const procparams::ProcParams& pparams, int rheight, float &ratio); int getImageWidth (const procparams::ProcParams& pparams, int rheight, float &ratio);
void getDimensions (int& w, int& h, double& scaleFac); void getDimensions (int& w, int& h, double& scaleFac);
static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false); static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode = false);
static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool multiThread = false); static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, double wbEq, bool rotate, bool forHistogramMatching = false);
static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode = false); static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode = false);
static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname); static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname);