libipa: awb: Make result of gainsFromColourTemp optional

In the grey world AWB case, if no colour gains are contained in the
tuning file, the colour gains get reset to 1 when the colour temperature
is set manually. This is unexpected and undesirable. Allow the
gainsFromColourTemp() function to return a std::nullopt to handle that
case.

While at it, remove an unnecessary import from rkisp1/algorithms/awb.h.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
Stefan Klug 2025-04-03 17:49:18 +02:00
parent 66e9604684
commit c699d26573
8 changed files with 22 additions and 17 deletions

View file

@ -114,7 +114,7 @@ namespace ipa {
* does not take any statistics into account. It is used to compute the colour * does not take any statistics into account. It is used to compute the colour
* gains when the user manually specifies a colour temperature. * gains when the user manually specifies a colour temperature.
* *
* \return The colour gains * \return The colour gains or std::nullopt if the conversion is not possible
*/ */
/** /**

View file

@ -8,6 +8,7 @@
#pragma once #pragma once
#include <map> #include <map>
#include <optional>
#include <libcamera/control_ids.h> #include <libcamera/control_ids.h>
#include <libcamera/controls.h> #include <libcamera/controls.h>
@ -39,7 +40,7 @@ public:
virtual int init(const YamlObject &tuningData) = 0; virtual int init(const YamlObject &tuningData) = 0;
virtual AwbResult calculateAwb(const AwbStats &stats, unsigned int lux) = 0; virtual AwbResult calculateAwb(const AwbStats &stats, unsigned int lux) = 0;
virtual RGB<double> gainsFromColourTemperature(double colourTemperature) = 0; virtual std::optional<RGB<double>> gainsFromColourTemperature(double colourTemperature) = 0;
const ControlInfoMap::Map &controls() const const ControlInfoMap::Map &controls() const
{ {

View file

@ -270,7 +270,7 @@ void AwbBayes::handleControls(const ControlList &controls)
} }
} }
RGB<double> AwbBayes::gainsFromColourTemperature(double colourTemperature) std::optional<RGB<double>> AwbBayes::gainsFromColourTemperature(double colourTemperature)
{ {
/* /*
* \todo In the RaspberryPi code, the ct curve was interpolated in * \todo In the RaspberryPi code, the ct curve was interpolated in
@ -278,7 +278,7 @@ RGB<double> AwbBayes::gainsFromColourTemperature(double colourTemperature)
* intuitive, as the gains are in linear space. But I can't prove it. * intuitive, as the gains are in linear space. But I can't prove it.
*/ */
const auto &gains = colourGainCurve_.getInterpolated(colourTemperature); const auto &gains = colourGainCurve_.getInterpolated(colourTemperature);
return { { gains[0], 1.0, gains[1] } }; return RGB<double>{ { gains[0], 1.0, gains[1] } };
} }
AwbResult AwbBayes::calculateAwb(const AwbStats &stats, unsigned int lux) AwbResult AwbBayes::calculateAwb(const AwbStats &stats, unsigned int lux)

View file

@ -27,7 +27,7 @@ public:
int init(const YamlObject &tuningData) override; int init(const YamlObject &tuningData) override;
AwbResult calculateAwb(const AwbStats &stats, unsigned int lux) override; AwbResult calculateAwb(const AwbStats &stats, unsigned int lux) override;
RGB<double> gainsFromColourTemperature(double temperatureK) override; std::optional<RGB<double>> gainsFromColourTemperature(double temperatureK) override;
void handleControls(const ControlList &controls) override; void handleControls(const ControlList &controls) override;
private: private:

View file

@ -98,15 +98,15 @@ AwbResult AwbGrey::calculateAwb(const AwbStats &stats, [[maybe_unused]] unsigned
* \return The colour gains if a colour temperature curve is available, * \return The colour gains if a colour temperature curve is available,
* [1, 1, 1] otherwise. * [1, 1, 1] otherwise.
*/ */
RGB<double> AwbGrey::gainsFromColourTemperature(double colourTemperature) std::optional<RGB<double>> AwbGrey::gainsFromColourTemperature(double colourTemperature)
{ {
if (!colourGainCurve_) { if (!colourGainCurve_) {
LOG(Awb, Error) << "No gains defined"; LOG(Awb, Error) << "No gains defined";
return RGB<double>({ 1.0, 1.0, 1.0 }); return std::nullopt;
} }
auto gains = colourGainCurve_->getInterpolated(colourTemperature); auto gains = colourGainCurve_->getInterpolated(colourTemperature);
return { { gains[0], 1.0, gains[1] } }; return RGB<double>{ { gains[0], 1.0, gains[1] } };
} }
} /* namespace ipa */ } /* namespace ipa */

View file

@ -25,7 +25,7 @@ public:
int init(const YamlObject &tuningData) override; int init(const YamlObject &tuningData) override;
AwbResult calculateAwb(const AwbStats &stats, unsigned int lux) override; AwbResult calculateAwb(const AwbStats &stats, unsigned int lux) override;
RGB<double> gainsFromColourTemperature(double colourTemperature) override; std::optional<RGB<double>> gainsFromColourTemperature(double colourTemperature) override;
private: private:
std::optional<Interpolator<Vector<double, 2>>> colourGainCurve_; std::optional<Interpolator<Vector<double, 2>>> colourGainCurve_;

View file

@ -127,8 +127,12 @@ int Awb::configure(IPAContext &context,
const IPACameraSensorInfo &configInfo) const IPACameraSensorInfo &configInfo)
{ {
context.activeState.awb.manual.gains = RGB<double>{ 1.0 }; context.activeState.awb.manual.gains = RGB<double>{ 1.0 };
context.activeState.awb.automatic.gains = auto gains = awbAlgo_->gainsFromColourTemperature(kDefaultColourTemperature);
awbAlgo_->gainsFromColourTemperature(kDefaultColourTemperature); if (gains)
context.activeState.awb.automatic.gains = *gains;
else
context.activeState.awb.automatic.gains = RGB<double>{ 1.0 };
context.activeState.awb.autoEnabled = true; context.activeState.awb.autoEnabled = true;
context.activeState.awb.manual.temperatureK = kDefaultColourTemperature; context.activeState.awb.manual.temperatureK = kDefaultColourTemperature;
context.activeState.awb.automatic.temperatureK = kDefaultColourTemperature; context.activeState.awb.automatic.temperatureK = kDefaultColourTemperature;
@ -185,11 +189,13 @@ void Awb::queueRequest(IPAContext &context,
*/ */
update = true; update = true;
} else if (colourTemperature) { } else if (colourTemperature) {
const auto &gains = awbAlgo_->gainsFromColourTemperature(*colourTemperature);
awb.manual.gains.r() = gains.r();
awb.manual.gains.b() = gains.b();
awb.manual.temperatureK = *colourTemperature; awb.manual.temperatureK = *colourTemperature;
update = true; const auto &gains = awbAlgo_->gainsFromColourTemperature(*colourTemperature);
if (gains) {
awb.manual.gains.r() = gains->r();
awb.manual.gains.b() = gains->b();
update = true;
}
} }
if (update) if (update)

View file

@ -7,8 +7,6 @@
#pragma once #pragma once
#include <optional>
#include "libcamera/internal/vector.h" #include "libcamera/internal/vector.h"
#include "libipa/awb.h" #include "libipa/awb.h"