From e265d23e76ee787acdfe4d6c2aae1b9153feefcd Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Fri, 2 Feb 2018 13:57:43 +0100 Subject: [PATCH] made histogram matching depend on the input profile This improves the accuracy of the matching when using non-default profiles --- rtengine/histmatching.cc | 21 +++++++++++++++++++-- rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 2 +- rtengine/rawimagesource.h | 3 ++- rtengine/refreshmap.cc | 6 +++--- rtengine/simpleprocess.cc | 2 +- 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index f0b49cddd..d63428738 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -169,7 +169,7 @@ void mappingToCurve(const std::vector &mapping, std::vector &curve) } // namespace -void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) +void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, std::vector &outCurve) { BENCHFUN @@ -177,7 +177,18 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) std::cout << "performing histogram matching for " << getFileName() << " on the embedded thumbnail" << std::endl; } - if (!histMatchingCache.empty()) { + const auto same_profile = + [](const ColorManagementParams &a, const ColorManagementParams &b) -> bool + { + return (a.input == b.input + && a.toneCurve == b.toneCurve + && a.applyLookTable == b.applyLookTable + && a.applyBaselineExposureOffset == b.applyBaselineExposureOffset + && a.applyHueSatMap == b.applyHueSatMap + && a.dcpIlluminant == b.dcpIlluminant); + }; + + if (!histMatchingCache.empty() && same_profile(histMatchingParams, cp)) { if (settings->verbose) { std::cout << "tone curve found in cache" << std::endl; } @@ -196,9 +207,12 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) } ProcParams neutral; + neutral.icm = cp; neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST); neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST); neutral.icm.output = "sRGB"; + neutral.icm.gamma = "default"; + neutral.icm.freegamma = false; std::unique_ptr source; { @@ -211,6 +225,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) std::cout << "histogram matching: no thumbnail found, generating a neutral curve" << std::endl; } histMatchingCache = outCurve; + histMatchingParams = cp; return; } skip = LIM(skip * fh / h, 6, 10); // adjust the skip factor -- the larger the thumbnail, the less we should skip to get a good match @@ -233,6 +248,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) std::cout << "histogram matching: raw decoding failed, generating a neutral curve" << std::endl; } histMatchingCache = outCurve; + histMatchingParams = cp; return; } target.reset(thumb->processImage(neutral, sensor_type, fh / skip, TI_Nearest, getMetaData(), scale, false, true)); @@ -304,6 +320,7 @@ void RawImageSource::getAutoMatchedToneCurve(std::vector &outCurve) } histMatchingCache = outCurve; + histMatchingParams = cp; } } // namespace rtengine diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 675243b65..af9eecc35 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -139,7 +139,7 @@ public: } // for RAW files, compute a tone curve using histogram matching on the embedded thumbnail - virtual void getAutoMatchedToneCurve(std::vector &outCurve) + virtual void getAutoMatchedToneCurve(const ColorManagementParams &cp, std::vector &outCurve) { outCurve = { 0.0 }; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 62891a03f..3c0a8e450 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -447,7 +447,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, params.toneCurve.hrenabled); } if (params.toneCurve.histmatching) { - imgsrc->getAutoMatchedToneCurve(params.toneCurve.curve); + imgsrc->getAutoMatchedToneCurve(params.icm, params.toneCurve.curve); if (params.toneCurve.autoexp) { params.toneCurve.expcomp = 0.0; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 59316eccf..ff7d2c1f9 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -96,6 +96,7 @@ protected: float psBlueBrightness[4]; std::vector histMatchingCache; + ColorManagementParams histMatchingParams; void hphd_vertical (float** hpmap, int col_from, int col_to); void hphd_horizontal (float** hpmap, int row_from, int row_to); @@ -186,7 +187,7 @@ public: } void getAutoExpHistogram (LUTu & histogram, int& histcompr); void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw); - void getAutoMatchedToneCurve(std::vector &outCurve); + void getAutoMatchedToneCurve(const ColorManagementParams &cp, std::vector &outCurve); DCPProfile *getDCP(const ColorManagementParams &cmp, DCPProfile::ApplyState &as); void convertColorSpace(Imagefloat* image, const ColorManagementParams &cmp, const ColorTemp &wb); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index e76338fc0..b467c5564 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -74,7 +74,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { 0, // EvLDNEdgeTolerance: obsolete, 0, // EvCDNEnabled:obsolete, 0, // free entry - RGBCURVE, // EvDCPToneCurve, + RGBCURVE|M_AUTOEXP, // EvDCPToneCurve, ALLNORAW, // EvDCPIlluminant, RETINEX, // EvSHEnabled, RGBCURVE, // EvSHHighlights, @@ -419,8 +419,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DIRPYREQUALIZER, // EvWavgreenlow DIRPYREQUALIZER, // EvWavbluelow DIRPYREQUALIZER, // EvWavNeutral - RGBCURVE, // EvDCPApplyLookTable, - RGBCURVE, // EvDCPApplyBaselineExposureOffset, + RGBCURVE|M_AUTOEXP, // EvDCPApplyLookTable, + RGBCURVE|M_AUTOEXP, // EvDCPApplyBaselineExposureOffset, ALLNORAW, // EvDCPApplyHueSatMap DIRPYREQUALIZER, // EvWavenacont DIRPYREQUALIZER, // EvWavenachrom diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 685e1d53e..06e811420 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -741,7 +741,7 @@ private: ipf.getAutoExp (aehist, aehistcompr, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); } if (params.toneCurve.histmatching) { - imgsrc->getAutoMatchedToneCurve(params.toneCurve.curve); + imgsrc->getAutoMatchedToneCurve(params.icm, params.toneCurve.curve); if (params.toneCurve.autoexp) { params.toneCurve.expcomp = 0.0;