ipa: ipu3: awb: Replace Awb::RGB class with ipa::RGB

Now that libipa has a generic RGB class, replaces the local
implementation from the IPU3 AWB algorithm.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
This commit is contained in:
Laurent Pinchart 2024-11-18 21:27:56 +02:00
parent 4251193c35
commit cb3e3095d6
2 changed files with 23 additions and 32 deletions

View file

@ -309,15 +309,18 @@ void Awb::generateZones()
zones_.clear(); zones_.clear();
for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) { for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {
RGB zone;
double counted = awbStats_[i].counted; double counted = awbStats_[i].counted;
if (counted >= cellsPerZoneThreshold_) { if (counted >= cellsPerZoneThreshold_) {
zone.G = awbStats_[i].sum.green / counted; RGB<double> zone{{
if (zone.G >= kMinGreenLevelInZone) { static_cast<double>(awbStats_[i].sum.red),
zone.R = awbStats_[i].sum.red / counted; static_cast<double>(awbStats_[i].sum.green),
zone.B = awbStats_[i].sum.blue / counted; static_cast<double>(awbStats_[i].sum.blue)
}};
zone /= counted;
if (zone.g() >= kMinGreenLevelInZone)
zones_.push_back(zone); zones_.push_back(zone);
}
} }
} }
} }
@ -384,32 +387,32 @@ void Awb::awbGreyWorld()
* consider some variations, such as normalising all the zones first, or * consider some variations, such as normalising all the zones first, or
* doing an L2 average etc. * doing an L2 average etc.
*/ */
std::vector<RGB> &redDerivative(zones_); std::vector<RGB<double>> &redDerivative(zones_);
std::vector<RGB> blueDerivative(redDerivative); std::vector<RGB<double>> blueDerivative(redDerivative);
std::sort(redDerivative.begin(), redDerivative.end(), std::sort(redDerivative.begin(), redDerivative.end(),
[](RGB const &a, RGB const &b) { [](RGB<double> const &a, RGB<double> const &b) {
return a.G * b.R < b.G * a.R; return a.g() * b.r() < b.g() * a.r();
}); });
std::sort(blueDerivative.begin(), blueDerivative.end(), std::sort(blueDerivative.begin(), blueDerivative.end(),
[](RGB const &a, RGB const &b) { [](RGB<double> const &a, RGB<double> const &b) {
return a.G * b.B < b.G * a.B; return a.g() * b.b() < b.g() * a.b();
}); });
/* Average the middle half of the values. */ /* Average the middle half of the values. */
int discard = redDerivative.size() / 4; int discard = redDerivative.size() / 4;
RGB sumRed(0, 0, 0); RGB<double> sumRed{ 0.0 };
RGB sumBlue(0, 0, 0); RGB<double> sumBlue{ 0.0 };
for (auto ri = redDerivative.begin() + discard, for (auto ri = redDerivative.begin() + discard,
bi = blueDerivative.begin() + discard; bi = blueDerivative.begin() + discard;
ri != redDerivative.end() - discard; ri++, bi++) ri != redDerivative.end() - discard; ri++, bi++)
sumRed += *ri, sumBlue += *bi; sumRed += *ri, sumBlue += *bi;
double redGain = sumRed.G / (sumRed.R + 1), double redGain = sumRed.g() / (sumRed.r() + 1),
blueGain = sumBlue.G / (sumBlue.B + 1); blueGain = sumBlue.g() / (sumBlue.b() + 1);
/* Color temperature is not relevant in Grey world but still useful to estimate it :-) */ /* Color temperature is not relevant in Grey world but still useful to estimate it :-) */
asyncResults_.temperatureK = estimateCCT(sumRed.R, sumRed.G, sumBlue.B); asyncResults_.temperatureK = estimateCCT(sumRed.r(), sumRed.g(), sumBlue.b());
/* /*
* Gain values are unsigned integer value ranging [0, 8) with 13 bit * Gain values are unsigned integer value ranging [0, 8) with 13 bit

View file

@ -13,6 +13,8 @@
#include <libcamera/geometry.h> #include <libcamera/geometry.h>
#include "libipa/vector.h"
#include "algorithm.h" #include "algorithm.h"
namespace libcamera { namespace libcamera {
@ -48,20 +50,6 @@ public:
ControlList &metadata) override; ControlList &metadata) override;
private: private:
/* \todo Make these structs available to all the ISPs ? */
struct RGB {
RGB(double _R = 0, double _G = 0, double _B = 0)
: R(_R), G(_G), B(_B)
{
}
double R, G, B;
RGB &operator+=(RGB const &other)
{
R += other.R, G += other.G, B += other.B;
return *this;
}
};
struct AwbStatus { struct AwbStatus {
double temperatureK; double temperatureK;
double redGain; double redGain;
@ -78,7 +66,7 @@ private:
static constexpr uint16_t threshold(float value); static constexpr uint16_t threshold(float value);
static constexpr uint16_t gainValue(double gain); static constexpr uint16_t gainValue(double gain);
std::vector<RGB> zones_; std::vector<RGB<double>> zones_;
Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY]; Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
AwbStatus asyncResults_; AwbStatus asyncResults_;