experimental hacks on simpleprocess.cc

This commit is contained in:
Alberto Griggio
2017-03-07 17:38:32 +01:00
parent 06137b02be
commit 200e6dd882

View File

@@ -35,9 +35,72 @@ namespace rtengine
{
extern const Settings* settings;
IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush)
{
namespace {
class ImageProcessor {
public:
ImageProcessor(ProcessingJob* pjob, int& errorCode,
ProgressListener* pl, bool tunnelMetaData, bool flush):
pjob(pjob),
errorCode(errorCode),
pl(pl),
tunnelMetaData(tunnelMetaData),
flush(flush),
// internal state
ii(nullptr),
imgsrc(nullptr),
fw(-1),
fh(-1),
pp(0, 0, 0, 0, 0)
{
}
Image16 *operator()(bool fast)
{
if (!fast) {
return normal_pipeline();
} else {
return fast_pipeline();
}
}
private:
Image16 *normal_pipeline()
{
if (!stage_1()) {
return nullptr;
}
stage_calc_denoise();
stage_2();
stage_3();
stage_4();
stage_5();
stage_6();
return stage_7();
}
Image16 *fast_pipeline()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
if (!job->pparams.resize.enabled) {
return normal_pipeline();
}
if (!stage_1()) {
return nullptr;
}
stage_2();
stage_4();
stage_early_resize();
stage_calc_denoise();
stage_3();
stage_5();
stage_6();
return stage_7();
}
bool stage_1()
{
errorCode = 0;
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
@@ -47,24 +110,23 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
pl->setProgress (0.0);
}
InitialImage* ii = job->initialImage;
ii = job->initialImage;
if (!ii) {
ii = InitialImage::load (job->fname, job->isRaw, &errorCode);
if (errorCode) {
delete job;
return nullptr;
return false; //return nullptr;
}
}
procparams::ProcParams& params = job->pparams;
// acquire image from imagesource
ImageSource* imgsrc = ii->getImageSource ();
imgsrc = ii->getImageSource ();
int tr = getCoarseBitMask(params.coarse);
int fw, fh;
tr = getCoarseBitMask(params.coarse);
imgsrc->getFullSize (fw, fh, tr);
// check the crop params
@@ -101,7 +163,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
ImProcFunctions ipf (&params, true);
PreviewProps pp (0, 0, fw, fh, 1);
pp = PreviewProps(0, 0, fw, fh, 1);
imgsrc->preprocess( params.raw, params.lensProf, params.coarse, params.dirpyrDenoise.enabled);
if (params.toneCurve.autoexp) {// this enabled HLRecovery
@@ -153,7 +215,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
}
// set the color temperature
ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method);
if (params.wb.method == "Camera") {
currWB = imgsrc->getWB ();
@@ -163,14 +225,24 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias);
}
NoiseCurve noiseLCurve;
NoiseCurve noiseCCurve;
Imagefloat *calclum = nullptr ;
// // AG begin
// baseImg = new Imagefloat (fw, fh);
// imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw);
// // AG end
return true;
}
void stage_calc_denoise()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
calclum = nullptr ;
params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve);
float autoNR = (float) settings->nrauto;//
float autoNRmax = (float) settings->nrautomax;//
int tilesize;
int overlap;
autoNR = (float) settings->nrauto;//
autoNRmax = (float) settings->nrautomax;//
if(settings->leveldnti == 0) {
tilesize = 1024;
@@ -192,16 +264,16 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
nbtl = 9;
}
float *ch_M = new float [nbtl];//allocate memory
float *max_r = new float [nbtl];
float *max_b = new float [nbtl];
float *min_b = new float [9];
float *min_r = new float [9];
float *lumL = new float [nbtl];
float *chromC = new float [nbtl];
float *ry = new float [nbtl];
float *sk = new float [nbtl];
float *pcsk = new float [nbtl];
ch_M = new float [nbtl];//allocate memory
max_r = new float [nbtl];
max_b = new float [nbtl];
min_b = new float [9];
min_r = new float [9];
lumL = new float [nbtl];
chromC = new float [nbtl];
ry = new float [nbtl];
sk = new float [nbtl];
pcsk = new float [nbtl];
// printf("expert=%d\n",settings->leveldnautsimpl);
if(settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PON") {
@@ -245,13 +317,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf gamcurve(65536, 0);
float gam, gamthresh, gamslope;
ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope);
#pragma omp parallel
#pragma omp parallel
{
Imagefloat *origCropPart;//init auto noise
origCropPart = new Imagefloat (crW, crH);//allocate memory
Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves
int skipP = 1;
#pragma omp for schedule(dynamic) collapse(2) nowait
#pragma omp for schedule(dynamic) collapse(2) nowait
for(int wcr = 0; wcr < numtiles_W; wcr++) {
for(int hcr = 0; hcr < numtiles_H; hcr++) {
@@ -259,6 +331,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
int beg_tileH = hcr * tileHskip + tileHskip / 2.f - crH / 2.f;
PreviewProps ppP (beg_tileW , beg_tileH, crW, crH, skipP);
imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw );
//baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve);
// we only need image reduced to 1/4 here
for(int ii = 0; ii < crH; ii += 2) {
@@ -466,18 +539,20 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
coordH[0] = begH;
coordH[1] = fh / 2 - crH / 2;
coordH[2] = fh - crH - begH;
#pragma omp parallel
#pragma omp parallel
{
Imagefloat *origCropPart;//init auto noise
origCropPart = new Imagefloat (crW, crH);//allocate memory
Imagefloat *provicalc = new Imagefloat ((crW + 1) / 2, (crH + 1) / 2); //for denoise curves
#pragma omp for schedule(dynamic) collapse(2) nowait
#pragma omp for schedule(dynamic) collapse(2) nowait
for(int wcr = 0; wcr <= 2; wcr++) {
for(int hcr = 0; hcr <= 2; hcr++) {
PreviewProps ppP (coordW[wcr] , coordH[hcr], crW, crH, 1);
imgsrc->getImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw);
//baseImg->getStdImage(currWB, tr, origCropPart, ppP, true, params.toneCurve);
// we only need image reduced to 1/4 here
for(int ii = 0; ii < crH; ii += 2) {
@@ -634,11 +709,16 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
//end evaluate noise
}
// return true;
}
void stage_2()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
Imagefloat* baseImg = new Imagefloat (fw, fh);
baseImg = new Imagefloat (fw, fh);
imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw);
if (pl) {
@@ -647,12 +727,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// LUTf Noisecurve (65536,0);
//!!!// auto exposure!!!
double expcomp = params.toneCurve.expcomp;
int bright = params.toneCurve.brightness;
int contr = params.toneCurve.contrast;
int black = params.toneCurve.black;
int hlcompr = params.toneCurve.hlcompr;
int hlcomprthresh = params.toneCurve.hlcomprthresh;
expcomp = params.toneCurve.expcomp;
bright = params.toneCurve.brightness;
contr = params.toneCurve.contrast;
black = params.toneCurve.black;
hlcompr = params.toneCurve.hlcompr;
hlcomprthresh = params.toneCurve.hlcomprthresh;
if (params.toneCurve.autoexp) {
LUTu aehist;
@@ -668,6 +749,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
imgsrc->flushRawData();
imgsrc->flushRGB();
}
}
void stage_3()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
// perform luma/chroma denoise
// CieImage *cieView;
@@ -692,7 +780,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if (denoiseParams.enabled && (noiseLCurve || noiseCCurve )) {
// we only need image reduced to 1/4 here
calclum = new Imagefloat ((fw + 1) / 2, (fh + 1) / 2); //for luminance denoise curve
#pragma omp parallel for
#pragma omp parallel for
for(int ii = 0; ii < fh; ii += 2) {
for(int jj = 0; jj < fw; jj += 2) {
@@ -727,10 +815,25 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
delete [] sk;
delete [] pcsk;
// imgsrc->convertColorSpace(baseImg, params.icm, currWB);
// // perform first analysis
// hist16 (65536);
// ipf.firstAnalysis (baseImg, params, hist16);
}
void stage_4()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
imgsrc->convertColorSpace(baseImg, params.icm, currWB);
// perform first analysis
LUTu hist16 (65536);
hist16 (65536);
ipf.firstAnalysis (baseImg, params, hist16);
@@ -742,7 +845,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
delete baseImg;
baseImg = trImg;
}
}
void stage_5()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) {
const int W = baseImg->getWidth();
@@ -770,28 +879,15 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// RGB processing
LUTf curve1 (65536);
LUTf curve2 (65536);
LUTf curve (65536, 0);
LUTf satcurve (65536, 0);
LUTf lhskcurve (65536, 0);
LUTf lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation
LUTf clcurve (65536, 0);
LUTf clToningcurve;
LUTf cl2Toningcurve;
LUTf wavclCurve (65536, 0);
curve1(65536);
curve2(65536);
curve(65536, 0);
satcurve(65536, 0);
lhskcurve(65536, 0);
lumacurve(32770, 0); // lumacurve[32768] and lumacurve[32769] will be set to 32768 and 32769 later to allow linear interpolation
clcurve(65536, 0);
wavclCurve(65536, 0);
LUTf rCurve;
LUTf gCurve;
LUTf bCurve;
LUTu dummy;
ToneCurve customToneCurve1, customToneCurve2;
ColorGradientCurve ctColorCurve;
OpacityCurve ctOpacityCurve;
ColorAppearance customColCurve1, customColCurve2, customColCurve3 ;
ToneCurve customToneCurvebw1;
ToneCurve customToneCurvebw2;
//if(params.blackwhite.enabled) params.toneCurve.hrenabled=false;
CurveFactory::complexCurve (expcomp, black / 65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr,
@@ -824,7 +920,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
CurveFactory::curveToning(params.colorToning.cl2curve, cl2Toningcurve, 1);
}
LabImage* labView = new LabImage (fw, fh);
labView = new LabImage (fw, fh);
if(params.blackwhite.enabled) {
CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1);
@@ -894,6 +990,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if (pl) {
pl->setProgress (0.55);
}
}
void stage_6()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -904,13 +1007,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16.clear();
#ifdef _OPENMP
#pragma omp parallel
#pragma omp parallel
#endif
{
LUTu hist16thr (hist16.getSize()); // one temporary lookup table per thread
hist16thr.clear();
#ifdef _OPENMP
#pragma omp for schedule(static) nowait
#pragma omp for schedule(static) nowait
#endif
for (int i = 0; i < fh; i++)
@@ -918,7 +1021,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16thr[(int)((labView->L[i][j]))]++;
}
#pragma omp critical
#pragma omp critical
{
hist16 += hist16thr;
}
@@ -931,7 +1034,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
bool clcutili;
CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, 1);
bool autili, butili, ccutili, cclutili;
bool ccutili, cclutili;
CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,
params.labCurve.lccurve, curve1, curve2, satcurve, lhskcurve, 1);
@@ -1085,6 +1188,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
if (pl) {
pl->setProgress (0.60);
}
}
Image16 *stage_7()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
int imw, imh;
double tmpScale = ipf.resizeScale(&params, fw, fh, imw, imh);
@@ -1275,6 +1385,156 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
hist16C.reset();
*/
return readyImg;
}
void stage_early_resize()
{
ProcessingJobImpl* job = static_cast<ProcessingJobImpl*>(pjob);
procparams::ProcParams& params = job->pparams;
ImProcFunctions ipf (&params, true);
int imw, imh;
double tmpScale = ipf.resizeScale(&params, fw, fh, imw, imh);
// bool resize = params.resize.enabled;
LabImage *tmplab = new LabImage(fw, fh);
ipf.rgb2lab(*baseImg, *tmplab, params.icm.working);
// crop and convert to rgb16
int cx = 0, cy = 0, cw = fw, ch = fh;
if (params.crop.enabled) {
cx = params.crop.x;
cy = params.crop.y;
cw = params.crop.w;
ch = params.crop.h;
LabImage *cropped = new LabImage(cw, ch);
for(int row = 0; row < ch; row++) {
for(int col = 0; col < cw; col++) {
cropped->L[row][col] = tmplab->L[row + cy][col + cx];
cropped->a[row][col] = tmplab->a[row + cy][col + cx];
cropped->b[row][col] = tmplab->b[row + cy][col + cx];
}
}
delete tmplab;
tmplab = cropped;
cx = 0;
cy = 0;
params.crop.enabled = false;
}
if (params.resize.enabled) {
// resize image
LabImage *resized = new LabImage(imw, imh);
ipf.Lanczos(tmplab, resized, tmpScale);
delete tmplab;
tmplab = resized;
params.resize.enabled = false;
if (params.prsharpening.enabled) {
params.sharpening = params.prsharpening;
}
params.wavelet.strength =
int(float(params.wavelet.strength) * tmpScale);
params.dirpyrDenoise.luma *= tmpScale;
// params.dirpyrDenoise.smethod = "shal";
fw = imw;
fh = imh;
}
delete baseImg;
baseImg = new Imagefloat(fw, fh);
ipf.lab2rgb(*tmplab, *baseImg, params.icm.working);
delete tmplab;
}
private:
ProcessingJob* pjob;
int& errorCode;
ProgressListener* pl;
bool tunnelMetaData;
bool flush;
// internal state
InitialImage *ii;
ImageSource *imgsrc;
int fw;
int fh;
int tr;
PreviewProps pp;
NoiseCurve noiseLCurve;
NoiseCurve noiseCCurve;
Imagefloat *calclum;
float autoNR;
float autoNRmax;
int tilesize;
int overlap;
float *ch_M;
float *max_r;
float *max_b;
float *min_b;
float *min_r;
float *lumL;
float *chromC;
float *ry;
float *sk;
float *pcsk;
double expcomp;
int bright;
int contr;
int black;
int hlcompr;
int hlcomprthresh;
ColorTemp currWB;
Imagefloat *baseImg;
LabImage* labView;
LUTu hist16;
LUTf curve1;
LUTf curve2;
LUTf curve;
LUTf satcurve;
LUTf lhskcurve;
LUTf lumacurve;
LUTf clcurve;
LUTf clToningcurve;
LUTf cl2Toningcurve;
LUTf wavclCurve;
LUTf rCurve;
LUTf gCurve;
LUTf bCurve;
LUTu dummy;
ToneCurve customToneCurve1, customToneCurve2;
ColorGradientCurve ctColorCurve;
OpacityCurve ctOpacityCurve;
ColorAppearance customColCurve1, customColCurve2, customColCurve3 ;
ToneCurve customToneCurvebw1;
ToneCurve customToneCurvebw2;
bool autili, butili;
};
} // namespace
IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush)
{
ImageProcessor proc(pjob, errorCode, pl, tunnelMetaData, flush);
return proc(true);
}
void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData)