mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 07:19:45 +03:00
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:
parent
4251193c35
commit
cb3e3095d6
2 changed files with 23 additions and 32 deletions
|
@ -309,17 +309,20 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translate the IPU3 statistics into the default statistics zone array */
|
/* Translate the IPU3 statistics into the default statistics zone array */
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue