Speedup and reduced memory usage for xtrans dual demosaic
This commit is contained in:
parent
929a5ce727
commit
498a39a88f
@ -111,41 +111,34 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
|
||||
buildBlendMask(L, blend, winw, winh, contrastf, autoContrast);
|
||||
contrast = contrastf * 100.f;
|
||||
|
||||
array2D<float>& redTmp = L; // L is not needed anymore => reuse it
|
||||
array2D<float> greenTmp;
|
||||
array2D<float> blueTmp;
|
||||
|
||||
if (isBayer) {
|
||||
if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEBILINEAR) ||
|
||||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ||
|
||||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBBILINEAR)) {
|
||||
bayer_bilinear_demosaic(blend, rawData, red, green, blue);
|
||||
return;
|
||||
} else {
|
||||
greenTmp(winw, winh);
|
||||
blueTmp(winw, winh);
|
||||
array2D<float>& redTmp = L; // L is not needed anymore => reuse it
|
||||
array2D<float> greenTmp(winw, winh);
|
||||
array2D<float> blueTmp(winw, winh);
|
||||
vng4_demosaic(rawData, redTmp, greenTmp, blueTmp);
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic,16)
|
||||
#endif
|
||||
for(int i = 0; i < winh; ++i) {
|
||||
// the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache
|
||||
for(int j = 0; j < winw; ++j) {
|
||||
red[i][j] = intp(blend[i][j], red[i][j], redTmp[i][j]);
|
||||
}
|
||||
for(int j = 0; j < winw; ++j) {
|
||||
green[i][j] = intp(blend[i][j], green[i][j], greenTmp[i][j]);
|
||||
}
|
||||
for(int j = 0; j < winw; ++j) {
|
||||
blue[i][j] = intp(blend[i][j], blue[i][j], blueTmp[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
greenTmp(winw, winh);
|
||||
blueTmp(winw, winh);
|
||||
fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp);
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic,16)
|
||||
#endif
|
||||
for(int i = 0; i < winh; ++i) {
|
||||
// the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache
|
||||
for(int j = 0; j < winw; ++j) {
|
||||
red[i][j] = intp(blend[i][j], red[i][j], redTmp[i][j]);
|
||||
}
|
||||
for(int j = 0; j < winw; ++j) {
|
||||
green[i][j] = intp(blend[i][j], green[i][j], greenTmp[i][j]);
|
||||
}
|
||||
for(int j = 0; j < winw; ++j) {
|
||||
blue[i][j] = intp(blend[i][j], blue[i][j], blueTmp[i][j]);
|
||||
}
|
||||
fast_xtrans_interpolate_blend(blend, rawData, red, green, blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +299,7 @@ protected:
|
||||
void xtransborder_interpolate (int border, array2D<float> &red, array2D<float> &green, array2D<float> &blue);
|
||||
void xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize = 1, bool measure = false);
|
||||
void fast_xtrans_interpolate (const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);
|
||||
void fast_xtrans_interpolate_blend (const float* const * blend, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);
|
||||
void pixelshift(int winx, int winy, int winw, int winh, const procparams::RAWParams &rawParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection);
|
||||
void bayer_bilinear_demosaic(const float *const * blend, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);
|
||||
void hflip (Imagefloat* im);
|
||||
|
@ -1027,6 +1027,67 @@ void RawImageSource::fast_xtrans_interpolate (const array2D<float> &rawData, arr
|
||||
plistener->setProgress (1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void RawImageSource::fast_xtrans_interpolate_blend (const float* const * blend, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue)
|
||||
{
|
||||
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_XTRANSFAST")));
|
||||
plistener->setProgress(0.0);
|
||||
}
|
||||
|
||||
int xtrans[6][6];
|
||||
ri->getXtransMatrix(xtrans);
|
||||
|
||||
const float weight[3][3] = {
|
||||
{0.25f, 0.5f, 0.25f},
|
||||
{0.5f, 0.f, 0.5f},
|
||||
{0.25f, 0.5f, 0.25f}
|
||||
};
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for schedule(dynamic, 16)
|
||||
#endif
|
||||
for (int row = 8; row < H - 8; ++row) {
|
||||
for (int col = 8; col < W - 8; ++col) {
|
||||
float sum[3] = {};
|
||||
|
||||
for (int v = -1; v <= 1; v++) {
|
||||
for (int h = -1; h <= 1; h++) {
|
||||
sum[fcol(row + v, col + h)] += rawData[row + v][(col + h)] * weight[v + 1][h + 1];
|
||||
}
|
||||
}
|
||||
|
||||
switch(fcol(row, col)) {
|
||||
case 0: // red pixel
|
||||
red[row][col] = intp(blend[row][col], red[row][col], rawData[row][col]);
|
||||
green[row][col] = intp(blend[row][col], green[row][col], sum[1] * 0.5f);
|
||||
blue[row][col] = intp(blend[row][col], blue[row][col], sum[2]);
|
||||
break;
|
||||
|
||||
case 1: // green pixel
|
||||
green[row][col] = intp(blend[row][col], green[row][col], rawData[row][col]);
|
||||
if (fcol(row, col - 1) == fcol(row, col + 1)) { // Solitary green pixel always has exactly two direct red and blue neighbors in 3x3 grid
|
||||
red[row][col] = intp(blend[row][col], red[row][col], sum[0]);
|
||||
blue[row][col] = intp(blend[row][col], blue[row][col], sum[2]);
|
||||
} else { // Non solitary green pixel always has one direct and one diagonal red and blue neighbor in 3x3 grid
|
||||
red[row][col] = intp(blend[row][col], red[row][col], sum[0] * 1.3333333f);
|
||||
blue[row][col] = intp(blend[row][col], blue[row][col], sum[2] * 1.3333333f);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // blue pixel
|
||||
red[row][col] = intp(blend[row][col], red[row][col], sum[0]);
|
||||
green[row][col] = intp(blend[row][col], green[row][col], sum[1] * 0.5f);
|
||||
blue[row][col] = intp(blend[row][col], blue[row][col], rawData[row][col]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plistener) {
|
||||
plistener->setProgress (1.0);
|
||||
}
|
||||
}
|
||||
#undef fcol
|
||||
#undef isgreen
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user