| Message ID | 20260506230722.1041596-3-devve.3@gmail.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
d3vv3 <devve.3@gmail.com> writes: > Add configurable YAML parameters maxGainR, maxGainB, and speed to AWB. > Replace the single hardcoded max gain (4.0x) with per-channel limits, > and apply exponential moving average smoothing to reduce colour > temperature oscillation between frames. > > Signed-off-by: d3vv3 <devve.3@gmail.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com> > --- > src/ipa/simple/algorithms/awb.cpp | 34 ++++++++++++++++++++++++++----- > src/ipa/simple/algorithms/awb.h | 6 ++++++ > 2 files changed, 35 insertions(+), 5 deletions(-) > > diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp > index f5c88ea6..937aabc8 100644 > --- a/src/ipa/simple/algorithms/awb.cpp > +++ b/src/ipa/simple/algorithms/awb.cpp > @@ -14,6 +14,8 @@ > > #include <libcamera/control_ids.h> > > +#include "libcamera/internal/yaml_parser.h" > + > #include "libipa/colours.h" > #include "simple/ipa_context.h" > > @@ -23,6 +25,21 @@ LOG_DEFINE_CATEGORY(IPASoftAwb) > > namespace ipa::soft::algorithms { > > +int Awb::init([[maybe_unused]] IPAContext &context, > + const ValueNode &tuningData) > +{ > + maxGainR_ = tuningData["maxGainR"].get<float>().value_or(4.0f); > + maxGainB_ = tuningData["maxGainB"].get<float>().value_or(4.0f); > + speed_ = tuningData["speed"].get<float>().value_or(1.0f); > + > + LOG(IPASoftAwb, Debug) > + << "AWB: maxGainR " << maxGainR_ > + << ", maxGainB " << maxGainB_ > + << ", speed " << speed_; > + > + return 0; > +} > + > int Awb::configure(IPAContext &context, > [[maybe_unused]] const IPAConfigInfo &configInfo) > { > @@ -84,14 +101,21 @@ void Awb::process(IPAContext &context, > const RGB<uint64_t> sum = stats->sum_.max(offset + minValid) - offset; > > /* > - * Calculate red and blue gains for AWB. > - * Clamp max gain at 4.0, this also avoids 0 division. > + * Calculate red and blue gains for AWB. Clamp max gain to avoid > + * division by zero and extreme color casts. > */ > auto &gains = context.activeState.awb.gains; > + float rawRGain = sum.r() <= sum.g() / maxGainR_ ? maxGainR_ : > + static_cast<float>(sum.g()) / sum.r(); > + float rawBGain = sum.b() <= sum.g() / maxGainB_ ? maxGainB_ : > + static_cast<float>(sum.g()) / sum.b(); > + > + /* Apply temporal smoothing to avoid rapid white balance changes. */ > + float alpha = std::clamp(speed_, 0.01f, 1.0f); > gains = { { > - sum.r() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.r(), > - 1.0, > - sum.b() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.b(), > + gains.r() * (1.0f - alpha) + rawRGain * alpha, > + 1.0f, > + gains.b() * (1.0f - alpha) + rawBGain * alpha, > } }; > > RGB<double> rgbGains{ { 1 / gains.r(), 1 / gains.g(), 1 / gains.b() } }; > diff --git a/src/ipa/simple/algorithms/awb.h b/src/ipa/simple/algorithms/awb.h > index ad993f39..0aedc1d1 100644 > --- a/src/ipa/simple/algorithms/awb.h > +++ b/src/ipa/simple/algorithms/awb.h > @@ -19,6 +19,7 @@ public: > Awb() = default; > ~Awb() = default; > > + int init(IPAContext &context, const ValueNode &tuningData) override; > int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; > void prepare(IPAContext &context, > const uint32_t frame, > @@ -29,6 +30,11 @@ public: > IPAFrameContext &frameContext, > const SwIspStats *stats, > ControlList &metadata) override; > + > +private: > + float maxGainR_; > + float maxGainB_; > + float speed_; > }; > > } /* namespace ipa::soft::algorithms */
diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp index f5c88ea6..937aabc8 100644 --- a/src/ipa/simple/algorithms/awb.cpp +++ b/src/ipa/simple/algorithms/awb.cpp @@ -14,6 +14,8 @@ #include <libcamera/control_ids.h> +#include "libcamera/internal/yaml_parser.h" + #include "libipa/colours.h" #include "simple/ipa_context.h" @@ -23,6 +25,21 @@ LOG_DEFINE_CATEGORY(IPASoftAwb) namespace ipa::soft::algorithms { +int Awb::init([[maybe_unused]] IPAContext &context, + const ValueNode &tuningData) +{ + maxGainR_ = tuningData["maxGainR"].get<float>().value_or(4.0f); + maxGainB_ = tuningData["maxGainB"].get<float>().value_or(4.0f); + speed_ = tuningData["speed"].get<float>().value_or(1.0f); + + LOG(IPASoftAwb, Debug) + << "AWB: maxGainR " << maxGainR_ + << ", maxGainB " << maxGainB_ + << ", speed " << speed_; + + return 0; +} + int Awb::configure(IPAContext &context, [[maybe_unused]] const IPAConfigInfo &configInfo) { @@ -84,14 +101,21 @@ void Awb::process(IPAContext &context, const RGB<uint64_t> sum = stats->sum_.max(offset + minValid) - offset; /* - * Calculate red and blue gains for AWB. - * Clamp max gain at 4.0, this also avoids 0 division. + * Calculate red and blue gains for AWB. Clamp max gain to avoid + * division by zero and extreme color casts. */ auto &gains = context.activeState.awb.gains; + float rawRGain = sum.r() <= sum.g() / maxGainR_ ? maxGainR_ : + static_cast<float>(sum.g()) / sum.r(); + float rawBGain = sum.b() <= sum.g() / maxGainB_ ? maxGainB_ : + static_cast<float>(sum.g()) / sum.b(); + + /* Apply temporal smoothing to avoid rapid white balance changes. */ + float alpha = std::clamp(speed_, 0.01f, 1.0f); gains = { { - sum.r() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.r(), - 1.0, - sum.b() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.b(), + gains.r() * (1.0f - alpha) + rawRGain * alpha, + 1.0f, + gains.b() * (1.0f - alpha) + rawBGain * alpha, } }; RGB<double> rgbGains{ { 1 / gains.r(), 1 / gains.g(), 1 / gains.b() } }; diff --git a/src/ipa/simple/algorithms/awb.h b/src/ipa/simple/algorithms/awb.h index ad993f39..0aedc1d1 100644 --- a/src/ipa/simple/algorithms/awb.h +++ b/src/ipa/simple/algorithms/awb.h @@ -19,6 +19,7 @@ public: Awb() = default; ~Awb() = default; + int init(IPAContext &context, const ValueNode &tuningData) override; int configure(IPAContext &context, const IPAConfigInfo &configInfo) override; void prepare(IPAContext &context, const uint32_t frame, @@ -29,6 +30,11 @@ public: IPAFrameContext &frameContext, const SwIspStats *stats, ControlList &metadata) override; + +private: + float maxGainR_; + float maxGainB_; + float speed_; }; } /* namespace ipa::soft::algorithms */
Add configurable YAML parameters maxGainR, maxGainB, and speed to AWB. Replace the single hardcoded max gain (4.0x) with per-channel limits, and apply exponential moving average smoothing to reduce colour temperature oscillation between frames. Signed-off-by: d3vv3 <devve.3@gmail.com> --- src/ipa/simple/algorithms/awb.cpp | 34 ++++++++++++++++++++++++++----- src/ipa/simple/algorithms/awb.h | 6 ++++++ 2 files changed, 35 insertions(+), 5 deletions(-)