capture sharpening: do not trigger demosaic when changing adjusters
This commit is contained in:
parent
ada08b3b71
commit
ba8c3d15bf
@ -83,7 +83,7 @@ public:
|
||||
virtual void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) {};
|
||||
virtual void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) {};
|
||||
virtual bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams& currentParams, std::array<float, 3>& newExps) { return false; };
|
||||
virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) {};
|
||||
virtual void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) {};
|
||||
virtual void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {};
|
||||
virtual void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {};
|
||||
virtual void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI) {};
|
||||
|
@ -332,26 +332,31 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
||||
}
|
||||
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicAutoContrast : params->raw.xtranssensor.dualDemosaicAutoContrast;
|
||||
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params->raw.bayersensor.dualDemosaicContrast : params->raw.xtranssensor.dualDemosaicContrast;
|
||||
imgsrc->demosaic(rp, autoContrast, contrastThreshold); //enabled demosaic
|
||||
imgsrc->demosaic(rp, autoContrast, contrastThreshold, params->pdsharpening.enabled);
|
||||
|
||||
if (imgsrc->getSensorType() == ST_BAYER && bayerAutoContrastListener && autoContrast) {
|
||||
bayerAutoContrastListener->autoContrastChanged(contrastThreshold);
|
||||
} else if (imgsrc->getSensorType() == ST_FUJI_XTRANS && xtransAutoContrastListener && autoContrast) {
|
||||
xtransAutoContrastListener->autoContrastChanged(autoContrast ? contrastThreshold : -1.0);
|
||||
}
|
||||
|
||||
if (params->pdsharpening.enabled) {
|
||||
double pdSharpencontrastThreshold = params->pdsharpening.contrast;
|
||||
imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold);
|
||||
if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) {
|
||||
pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if a demosaic happened we should also call getimage later, so we need to set the M_INIT flag
|
||||
todo |= M_INIT;
|
||||
|
||||
}
|
||||
|
||||
if ((todo & M_INIT) && params->pdsharpening.enabled) {
|
||||
double pdSharpencontrastThreshold = params->pdsharpening.contrast;
|
||||
imgsrc->captureSharpening(params->pdsharpening, sharpMask, pdSharpencontrastThreshold);
|
||||
if (pdSharpenAutoContrastListener && params->pdsharpening.autoContrast) {
|
||||
pdSharpenAutoContrastListener->autoContrastChanged(pdSharpencontrastThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((todo & M_RAW)
|
||||
|| (!highDetailRawComputed && highDetailNeeded)
|
||||
|| (params->toneCurve.hrenabled && params->toneCurve.method != "Color" && imgsrc->isRGBSourceModified())
|
||||
|| (!params->toneCurve.hrenabled && params->toneCurve.method == "Color" && imgsrc->isRGBSourceModified())) {
|
||||
if (highDetailNeeded) {
|
||||
highDetailRawComputed = true;
|
||||
} else {
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <omp.h>
|
||||
#endif
|
||||
#include "opthelper.h"
|
||||
#include "../rtgui/multilangmgr.h"
|
||||
#define clipretinex( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val )
|
||||
#undef CLIPD
|
||||
#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f)
|
||||
@ -457,6 +458,9 @@ RawImageSource::RawImageSource ()
|
||||
, green(0, 0)
|
||||
, red(0, 0)
|
||||
, blue(0, 0)
|
||||
, greenCache(nullptr)
|
||||
, redCache(nullptr)
|
||||
, blueCache(nullptr)
|
||||
, rawDirty(true)
|
||||
, histMatchingParams(new procparams::ColorManagementParams)
|
||||
{
|
||||
@ -474,6 +478,9 @@ RawImageSource::~RawImageSource ()
|
||||
{
|
||||
|
||||
delete idata;
|
||||
delete redCache;
|
||||
delete greenCache;
|
||||
delete blueCache;
|
||||
|
||||
for(size_t i = 0; i < numFrames; ++i) {
|
||||
delete riFrames[i];
|
||||
@ -1524,7 +1531,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
}
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold)
|
||||
void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache)
|
||||
{
|
||||
MyTime t1, t2;
|
||||
t1.set();
|
||||
@ -1595,7 +1602,49 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
|
||||
|
||||
rgbSourceModified = false;
|
||||
|
||||
|
||||
if (cache) {
|
||||
if (!redCache) {
|
||||
redCache = new array2D<float>(W, H);
|
||||
greenCache = new array2D<float>(W, H);
|
||||
blueCache = new array2D<float>(W, H);
|
||||
}
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel sections
|
||||
#endif
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
#pragma omp section
|
||||
#endif
|
||||
for (int i = 0; i < H; ++i) {
|
||||
for (int j = 0; j < W; ++j) {
|
||||
(*redCache)[i][j] = red[i][j];
|
||||
}
|
||||
}
|
||||
#ifdef _OPENMP
|
||||
#pragma omp section
|
||||
#endif
|
||||
for (int i = 0; i < H; ++i) {
|
||||
for (int j = 0; j < W; ++j) {
|
||||
(*greenCache)[i][j] = green[i][j];
|
||||
}
|
||||
}
|
||||
#ifdef _OPENMP
|
||||
#pragma omp section
|
||||
#endif
|
||||
for (int i = 0; i < H; ++i) {
|
||||
for (int j = 0; j < W; ++j) {
|
||||
(*blueCache)[i][j] = blue[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
delete redCache;
|
||||
redCache = nullptr;
|
||||
delete greenCache;
|
||||
greenCache = nullptr;
|
||||
delete blueCache;
|
||||
blueCache = nullptr;
|
||||
}
|
||||
if( settings->verbose ) {
|
||||
if (getSensorType() == ST_BAYER) {
|
||||
printf("Demosaicing Bayer data: %s - %d usec\n", raw.bayersensor.method.c_str(), t2.etime(t1));
|
||||
@ -4954,6 +5003,12 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int
|
||||
void RawImageSource::captureSharpening(const procparams::SharpeningParams &sharpeningParams, bool showMask, double &conrastThreshold) {
|
||||
BENCHFUN
|
||||
|
||||
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(0.0);
|
||||
}
|
||||
|
||||
const float xyz_rgb[3][3] = { // XYZ from RGB
|
||||
{ 0.412453, 0.357580, 0.180423 },
|
||||
{ 0.212671, 0.715160, 0.072169 },
|
||||
@ -4962,6 +5017,10 @@ BENCHFUN
|
||||
|
||||
float contrast = conrastThreshold / 100.f;
|
||||
|
||||
array2D<float>& redVals = redCache ? *redCache : red;
|
||||
array2D<float>& greenVals = greenCache ? *greenCache : green;
|
||||
array2D<float>& blueVals = blueCache ? *blueCache : blue;
|
||||
|
||||
if (showMask) {
|
||||
StopWatch Stop1("Show mask");
|
||||
array2D<float>& L = blue; // blue will be overridden anyway => we can use its buffer to store L
|
||||
@ -4970,10 +5029,18 @@ BENCHFUN
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < H; ++i) {
|
||||
Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W);
|
||||
Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W);
|
||||
}
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(0.1);
|
||||
}
|
||||
array2D<float>& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask
|
||||
buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast);
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(0.2);
|
||||
}
|
||||
conrastThreshold = contrast * 100.f;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
@ -4983,6 +5050,10 @@ BENCHFUN
|
||||
red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f;
|
||||
}
|
||||
}
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(1.0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4995,12 +5066,20 @@ BENCHFUN
|
||||
#pragma omp parallel for schedule(dynamic, 16)
|
||||
#endif
|
||||
for (int i = 0; i < H; ++i) {
|
||||
Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, W);
|
||||
Color::RGB2Y(red[i], green[i], blue[i], YOld[i], YNew[i], sharpeningParams.gamma, W);
|
||||
Color::RGB2L(redVals[i], greenVals[i], blueVals[i], L[i], xyz_rgb, W);
|
||||
Color::RGB2Y(redVals[i], greenVals[i], blueVals[i], YOld[i], YNew[i], sharpeningParams.gamma, W);
|
||||
}
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(0.1);
|
||||
}
|
||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||
JaggedArray<float> blend(W, H);
|
||||
buildBlendMask(L, blend, W, H, contrast, 1.f, sharpeningParams.autoContrast);
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(0.2);
|
||||
}
|
||||
conrastThreshold = contrast * 100.f;
|
||||
|
||||
Stop1.stop();
|
||||
@ -5008,6 +5087,10 @@ BENCHFUN
|
||||
ProcParams dummy;
|
||||
ImProcFunctions ipf(&dummy);
|
||||
ipf.deconvsharpening(YNew, tmp, blend, W, H, sharpeningParams, 1.0);
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(0.9);
|
||||
}
|
||||
StopWatch Stop2("Y2RGB");
|
||||
const float gamma = sharpeningParams.gamma;
|
||||
#ifdef _OPENMP
|
||||
@ -5019,20 +5102,24 @@ BENCHFUN
|
||||
const vfloat gammav = F2V(gamma);
|
||||
for (; j < W - 3; j += 4) {
|
||||
const vfloat factor = pow_F(LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f)), gammav);
|
||||
STVFU(red[i][j], LVFU(red[i][j]) * factor);
|
||||
STVFU(green[i][j], LVFU(green[i][j]) * factor);
|
||||
STVFU(blue[i][j], LVFU(blue[i][j]) * factor);
|
||||
STVFU(red[i][j], LVFU(redVals[i][j]) * factor);
|
||||
STVFU(green[i][j], LVFU(greenVals[i][j]) * factor);
|
||||
STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor);
|
||||
}
|
||||
|
||||
#endif
|
||||
for (; j < W; ++j) {
|
||||
const float factor = pow_F(YNew[i][j] / std::max(YOld[i][j], 0.00001f), gamma);
|
||||
red[i][j] *= factor;
|
||||
green[i][j] *= factor;
|
||||
blue[i][j] *= factor;
|
||||
red[i][j] = redVals[i][j] * factor;
|
||||
green[i][j] = greenVals[i][j] * factor;
|
||||
blue[i][j] = blueVals[i][j] * factor;
|
||||
}
|
||||
}
|
||||
Stop2.stop();
|
||||
if (plistener) {
|
||||
plistener->setProgressStr(M("TP_PDSHARPENING_LABEL"));
|
||||
plistener->setProgress(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void RawImageSource::cleanup ()
|
||||
|
@ -88,6 +88,12 @@ protected:
|
||||
array2D<float> red;
|
||||
// the interpolated blue plane:
|
||||
array2D<float> blue;
|
||||
// the interpolated green plane:
|
||||
array2D<float>* greenCache;
|
||||
// the interpolated red plane:
|
||||
array2D<float>* redCache;
|
||||
// the interpolated blue plane:
|
||||
array2D<float>* blueCache;
|
||||
bool rawDirty;
|
||||
float psRedBrightness[4];
|
||||
float psGreenBrightness[4];
|
||||
@ -117,7 +123,7 @@ public:
|
||||
void preprocess (const procparams::RAWParams &raw, const procparams::LensProfParams &lensProf, const procparams::CoarseTransformParams& coarse, bool prepareDenoise = true) override;
|
||||
void filmNegativeProcess (const procparams::FilmNegativeParams ¶ms) override;
|
||||
bool getFilmNegativeExponents (Coord2D spotA, Coord2D spotB, int tran, const FilmNegativeParams ¤tParams, std::array<float, 3>& newExps) override;
|
||||
void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold) override;
|
||||
void demosaic (const procparams::RAWParams &raw, bool autoContrast, double &contrastThreshold, bool cache = false) override;
|
||||
void retinex (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &deh, const procparams::ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) override;
|
||||
void retinexPrepareCurves (const procparams::RetinexParams &retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, RetinexgaintransmissionCurve &retinexgaintransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) override;
|
||||
void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D<float, 4> &conversionBuffer, LUTu &lhist16RETI) override;
|
||||
|
@ -220,7 +220,7 @@ private:
|
||||
bool autoContrast = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicAutoContrast : params.raw.xtranssensor.dualDemosaicAutoContrast;
|
||||
double contrastThreshold = imgsrc->getSensorType() == ST_BAYER ? params.raw.bayersensor.dualDemosaicContrast : params.raw.xtranssensor.dualDemosaicContrast;
|
||||
|
||||
imgsrc->demosaic (params.raw, autoContrast, contrastThreshold);
|
||||
imgsrc->demosaic (params.raw, autoContrast, contrastThreshold, params.pdsharpening.enabled && pl);
|
||||
if (params.pdsharpening.enabled) {
|
||||
imgsrc->captureSharpening(params.pdsharpening, false, params.pdsharpening.contrast);
|
||||
}
|
||||
|
@ -30,11 +30,11 @@ PdSharpening::PdSharpening() : FoldableToolPanel(this, "pdsharpening", M("TP_PDS
|
||||
{
|
||||
|
||||
auto m = ProcEventMapper::getInstance();
|
||||
EvPdShrContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_CONTRAST");
|
||||
EvPdSharpenGamma = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_GAMMA");
|
||||
EvPdShrDRadius = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_RADIUS");
|
||||
EvPdShrDIterations = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_ITERATIONS");
|
||||
EvPdShrAutoContrast = m->newEvent(DEMOSAIC, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST");
|
||||
EvPdShrContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_CONTRAST");
|
||||
EvPdSharpenGamma = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_GAMMA");
|
||||
EvPdShrDRadius = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_RADIUS");
|
||||
EvPdShrDIterations = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_ITERATIONS");
|
||||
EvPdShrAutoContrast = m->newEvent(ALLNORAW, "HISTORY_MSG_PDSHARPEN_AUTO_CONTRAST");
|
||||
|
||||
Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
|
||||
hb->show();
|
||||
|
Loading…
x
Reference in New Issue
Block a user