From d8821fda391984bccc7856f8d62d7849ea71a83b Mon Sep 17 00:00:00 2001 From: David Plowman Date: Fri, 8 Aug 2025 16:12:41 +0100 Subject: [PATCH] ipa: rpi:: denoise: Implement TDN back-off for CDN deviation The CDN (colour denoise) deviation gets gradually reduced frame by frame as TDN (temporal denoise) comes in and has more effect. The tuning file parameters are chosen so that existing tuning files don't have to be updated and will carry on working "mostly like they did" (apart from the new back-off). Signed-off-by: David Plowman --- src/ipa/rpi/controller/rpi/denoise.cpp | 22 +++++++++++++++++++--- src/ipa/rpi/controller/rpi/denoise.h | 4 +++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/ipa/rpi/controller/rpi/denoise.cpp b/src/ipa/rpi/controller/rpi/denoise.cpp index ba851658d..d9bbeddda 100644 --- a/src/ipa/rpi/controller/rpi/denoise.cpp +++ b/src/ipa/rpi/controller/rpi/denoise.cpp @@ -37,7 +37,17 @@ int DenoiseConfig::read(const libcamera::YamlObject ¶ms) cdnEnable = params.contains("cdn"); if (cdnEnable) { auto &cdnParams = params["cdn"]; - cdnDeviation = cdnParams["deviation"].get(120); + cdnDeviationNoTdn = cdnParams["deviation_no_tdn"].get(150); + /* + * For backwards compatibility with existing tuning files, interpret "deviation" + * as giving the "no TDN" deviation, where present. + */ + cdnDeviationNoTdn = cdnParams["deviation"].get(cdnDeviationNoTdn); + /* + * A third the value of the no TDN deviation is about right for with-TDN, if + * the user hasn't specified otherwise. + */ + cdnDeviationWithTdn = cdnParams["deviation_with_tdn"].get(cdnDeviationNoTdn / 3); cdnStrength = cdnParams["strength"].get(0.2); } @@ -48,13 +58,14 @@ int DenoiseConfig::read(const libcamera::YamlObject ¶ms) tdnThreshold = tdnParams["threshold"].get(0.75); } else if (sdnEnable) { /* - * If SDN is enabled but TDN isn't, overwrite all the SDN settings + * If SDN is enabled but TDN isn't, overwrite all the SDN/CDN settings * with the "no TDN" versions. This makes it easier to enable or * disable TDN in the tuning file without editing all the other * parameters. */ sdnDeviation = sdnDeviation2 = sdnDeviationNoTdn; sdnStrength = sdnStrengthNoTdn; + cdnDeviationWithTdn = cdnDeviationNoTdn; } return 0; @@ -107,6 +118,7 @@ void Denoise::switchMode([[maybe_unused]] CameraMode const &cameraMode, currentSdnDeviation_ = currentConfig_->sdnDeviationNoTdn; currentSdnStrength_ = currentConfig_->sdnStrengthNoTdn; currentSdnDeviation2_ = currentConfig_->sdnDeviationNoTdn; + currentCdnDeviation_ = currentConfig_->cdnDeviationNoTdn; } void Denoise::prepare(Metadata *imageMetadata) @@ -159,8 +171,12 @@ void Denoise::prepare(Metadata *imageMetadata) if (currentConfig_->cdnEnable && mode_ != DenoiseMode::ColourOff) { struct CdnStatus cdn; - cdn.threshold = currentConfig_->cdnDeviation * noiseStatus.noiseSlope + noiseStatus.noiseConstant; + cdn.threshold = currentCdnDeviation_ * noiseStatus.noiseSlope + noiseStatus.noiseConstant; cdn.strength = currentConfig_->cdnStrength; + /* For the next frame, we back off the CDN deviation as TDN ramps up. */ + double f = currentConfig_->sdnTdnBackoff; + currentCdnDeviation_ = f * currentCdnDeviation_ + (1 - f) * currentConfig_->cdnDeviationWithTdn; + imageMetadata->set("cdn.status", cdn); LOG(RPiDenoise, Debug) << "programmed cdn threshold " << cdn.threshold diff --git a/src/ipa/rpi/controller/rpi/denoise.h b/src/ipa/rpi/controller/rpi/denoise.h index 92ff4f93e..6e3e06d86 100644 --- a/src/ipa/rpi/controller/rpi/denoise.h +++ b/src/ipa/rpi/controller/rpi/denoise.h @@ -23,7 +23,8 @@ struct DenoiseConfig { double sdnDeviationNoTdn; double sdnStrengthNoTdn; double sdnTdnBackoff; - double cdnDeviation; + double cdnDeviationNoTdn; + double cdnDeviationWithTdn; double cdnStrength; double tdnDeviation; double tdnThreshold; @@ -54,6 +55,7 @@ class Denoise : public DenoiseAlgorithm double currentSdnDeviation_; double currentSdnStrength_; double currentSdnDeviation2_; + double currentCdnDeviation_; }; } // namespace RPiController