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