Message ID | 20250123114204.79321-11-stefan.klug@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Stefan, On Thu, Jan 23, 2025 at 12:41:00PM +0100, Stefan Klug wrote: > Now that libipa contains a bayes AWB algorithm, add it as supported > algorithm to the rkisp1 ipa. > > The decision between the grey world algorithm and the bayesian is done > based on the "algorithm" property of the "Awb" algorithm in the tuning > file. If the lux value in the frameContext is set by the Lux algorithm > it is taken into account. If the lux value is 0 the prior likelihood > estimation gets ignored in the AWB calculations. > > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> > Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> > Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> > > --- > > Changes in v2: > - Collected tags > --- > src/ipa/rkisp1/algorithms/awb.cpp | 52 +++++++++++++++++++++++-------- > 1 file changed, 39 insertions(+), 13 deletions(-) > > diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp > index b21d0d4c03bb..55e1b43c8cd2 100644 > --- a/src/ipa/rkisp1/algorithms/awb.cpp > +++ b/src/ipa/rkisp1/algorithms/awb.cpp > @@ -16,6 +16,7 @@ > > #include <libcamera/ipa/core_ipa_interface.h> > > +#include "libipa/awb_bayes.h" > #include "libipa/awb_grey.h" > #include "libipa/colours.h" > > @@ -45,13 +46,23 @@ class RkISP1AwbStats : public AwbStats > { > public: > RkISP1AwbStats(const RGB<double> &rgbMeans) > - : rgbMeans_(rgbMeans) {} > + : rgbMeans_(rgbMeans) > + { > + rg_ = rgbMeans_.r() / rgbMeans_.g(); > + bg_ = rgbMeans_.b() / rgbMeans_.g(); > + } > > - double computeColourError([[maybe_unused]] const RGB<double> &gains) const override > + double computeColourError(const RGB<double> &gains) const override > { > - LOG(RkISP1Awb, Error) > - << "RkISP1AwbStats::computeColourError is not implemented"; > - return 0.0; > + /* > + * Compute the sum of the squared colour error (non-greyness) as it > + * appears in the log likelihood equation. > + */ > + double deltaR = gains.r() * rg_ - 1.0; > + double deltaB = gains.b() * bg_ - 1.0; > + double delta2 = deltaR * deltaR + deltaB * deltaB; > + > + return delta2; > } > > RGB<double> getRGBMeans() const override > @@ -61,6 +72,8 @@ public: > > private: > RGB<double> rgbMeans_; > + double rg_; > + double bg_; > }; > > Awb::Awb() > @@ -78,13 +91,30 @@ int Awb::init(IPAContext &context, const YamlObject &tuningData) > kMaxColourTemperature, > kDefaultColourTemperature); > > - awbAlgo_ = std::make_unique<AwbGrey>(); > + if (!tuningData.contains("algorithm")) > + LOG(RkISP1Awb, Info) << "No awb algorithm specified." > + << " Default to grey world"; > + > + auto mode = tuningData["algorithm"].get<std::string>("grey"); > + if (mode == "grey") { > + awbAlgo_ = std::make_unique<AwbGrey>(); > + } else if (mode == "bayes") { > + awbAlgo_ = std::make_unique<AwbBayes>(); > + } else { > + LOG(RkISP1Awb, Error) << "Unknown awb algorithm: " << mode; > + return -EINVAL; > + } > + LOG(RkISP1Awb, Debug) << "Using awb algorithm: " << mode; > + > int ret = awbAlgo_->init(tuningData); > if (ret) { > LOG(RkISP1Awb, Error) << "Failed to init awb algorithm"; > return ret; > } > > + const auto &src = awbAlgo_->controls(); > + cmap.insert(src.begin(), src.end()); > + > return 0; > } > > @@ -131,6 +161,8 @@ void Awb::queueRequest(IPAContext &context, > << (*awbEnable ? "Enabling" : "Disabling") << " AWB"; > } > > + awbAlgo_->handleControls(controls); > + > frameContext.awb.autoEnabled = awb.autoEnabled; > > if (awb.autoEnabled) There's a comment a bit below that states /* * \todo: Colour temperature reported in metadata is now * incorrect, as we can't deduce the temperature from the gains. * This will be fixed with the bayes AWB algorithm. */ Has this been addressed, can it be removed ? > @@ -271,14 +303,8 @@ void Awb::process(IPAContext &context, > rgbMeans.b() < kMeanMinThreshold) > return; > > - /* > - * \Todo: Hardcode lux to a fixed value, until an estimation is > - * implemented. > - */ > - int lux = 1000; > - > RkISP1AwbStats awbStats{ rgbMeans }; > - AwbResult awbResult = awbAlgo_->calculateAwb(awbStats, lux); > + AwbResult awbResult = awbAlgo_->calculateAwb(awbStats, frameContext.lux.lux); > > activeState.awb.temperatureK = awbResult.colourTemperature; >
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp index b21d0d4c03bb..55e1b43c8cd2 100644 --- a/src/ipa/rkisp1/algorithms/awb.cpp +++ b/src/ipa/rkisp1/algorithms/awb.cpp @@ -16,6 +16,7 @@ #include <libcamera/ipa/core_ipa_interface.h> +#include "libipa/awb_bayes.h" #include "libipa/awb_grey.h" #include "libipa/colours.h" @@ -45,13 +46,23 @@ class RkISP1AwbStats : public AwbStats { public: RkISP1AwbStats(const RGB<double> &rgbMeans) - : rgbMeans_(rgbMeans) {} + : rgbMeans_(rgbMeans) + { + rg_ = rgbMeans_.r() / rgbMeans_.g(); + bg_ = rgbMeans_.b() / rgbMeans_.g(); + } - double computeColourError([[maybe_unused]] const RGB<double> &gains) const override + double computeColourError(const RGB<double> &gains) const override { - LOG(RkISP1Awb, Error) - << "RkISP1AwbStats::computeColourError is not implemented"; - return 0.0; + /* + * Compute the sum of the squared colour error (non-greyness) as it + * appears in the log likelihood equation. + */ + double deltaR = gains.r() * rg_ - 1.0; + double deltaB = gains.b() * bg_ - 1.0; + double delta2 = deltaR * deltaR + deltaB * deltaB; + + return delta2; } RGB<double> getRGBMeans() const override @@ -61,6 +72,8 @@ public: private: RGB<double> rgbMeans_; + double rg_; + double bg_; }; Awb::Awb() @@ -78,13 +91,30 @@ int Awb::init(IPAContext &context, const YamlObject &tuningData) kMaxColourTemperature, kDefaultColourTemperature); - awbAlgo_ = std::make_unique<AwbGrey>(); + if (!tuningData.contains("algorithm")) + LOG(RkISP1Awb, Info) << "No awb algorithm specified." + << " Default to grey world"; + + auto mode = tuningData["algorithm"].get<std::string>("grey"); + if (mode == "grey") { + awbAlgo_ = std::make_unique<AwbGrey>(); + } else if (mode == "bayes") { + awbAlgo_ = std::make_unique<AwbBayes>(); + } else { + LOG(RkISP1Awb, Error) << "Unknown awb algorithm: " << mode; + return -EINVAL; + } + LOG(RkISP1Awb, Debug) << "Using awb algorithm: " << mode; + int ret = awbAlgo_->init(tuningData); if (ret) { LOG(RkISP1Awb, Error) << "Failed to init awb algorithm"; return ret; } + const auto &src = awbAlgo_->controls(); + cmap.insert(src.begin(), src.end()); + return 0; } @@ -131,6 +161,8 @@ void Awb::queueRequest(IPAContext &context, << (*awbEnable ? "Enabling" : "Disabling") << " AWB"; } + awbAlgo_->handleControls(controls); + frameContext.awb.autoEnabled = awb.autoEnabled; if (awb.autoEnabled) @@ -271,14 +303,8 @@ void Awb::process(IPAContext &context, rgbMeans.b() < kMeanMinThreshold) return; - /* - * \Todo: Hardcode lux to a fixed value, until an estimation is - * implemented. - */ - int lux = 1000; - RkISP1AwbStats awbStats{ rgbMeans }; - AwbResult awbResult = awbAlgo_->calculateAwb(awbStats, lux); + AwbResult awbResult = awbAlgo_->calculateAwb(awbStats, frameContext.lux.lux); activeState.awb.temperatureK = awbResult.colourTemperature;