ipa: ipu3: awb: Correct the relevant zones proportion
The algorithm uses the statistics of a cell only if there is not too much saturated pixels in it. The grey world algorithm works fine when there are a limited number of outliers. Consider a valid zone to be at least 80% of unsaturated cells in it. This value could very well be configurable, and make the algorithm more or less tolerant. While at it, implement it in a configure() call as it will not change during execution, and cache the cellsPerZone values estimated with std::round as we are using cmath. Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
195e6d0968
commit
3a240e56a8
2 changed files with 28 additions and 9 deletions
|
@ -17,7 +17,6 @@ namespace ipa::ipu3::algorithms {
|
||||||
|
|
||||||
LOG_DEFINE_CATEGORY(IPU3Awb)
|
LOG_DEFINE_CATEGORY(IPU3Awb)
|
||||||
|
|
||||||
static constexpr uint32_t kMinZonesCounted = 16;
|
|
||||||
static constexpr uint32_t kMinGreenLevelInZone = 32;
|
static constexpr uint32_t kMinGreenLevelInZone = 32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,6 +172,24 @@ Awb::Awb()
|
||||||
|
|
||||||
Awb::~Awb() = default;
|
Awb::~Awb() = default;
|
||||||
|
|
||||||
|
int Awb::configure(IPAContext &context,
|
||||||
|
[[maybe_unused]] const IPAConfigInfo &configInfo)
|
||||||
|
{
|
||||||
|
const ipu3_uapi_grid_config &grid = context.configuration.grid.bdsGrid;
|
||||||
|
|
||||||
|
cellsPerZoneX_ = std::round(grid.width / static_cast<double>(kAwbStatsSizeX));
|
||||||
|
cellsPerZoneY_ = std::round(grid.height / static_cast<double>(kAwbStatsSizeY));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure the minimum proportion of cells counted within a zone
|
||||||
|
* for it to be relevant for the grey world algorithm.
|
||||||
|
* \todo This proportion could be configured.
|
||||||
|
*/
|
||||||
|
cellsPerZoneThreshold_ = cellsPerZoneX_ * cellsPerZoneY_ * 80 / 100;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The function estimates the correlated color temperature using
|
* The function estimates the correlated color temperature using
|
||||||
* from RGB color space input.
|
* from RGB color space input.
|
||||||
|
@ -209,7 +226,7 @@ void Awb::generateZones(std::vector<RGB> &zones)
|
||||||
for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {
|
for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {
|
||||||
RGB zone;
|
RGB zone;
|
||||||
double counted = awbStats_[i].counted;
|
double counted = awbStats_[i].counted;
|
||||||
if (counted >= kMinZonesCounted) {
|
if (counted >= cellsPerZoneThreshold_) {
|
||||||
zone.G = awbStats_[i].sum.green / counted;
|
zone.G = awbStats_[i].sum.green / counted;
|
||||||
if (zone.G >= kMinGreenLevelInZone) {
|
if (zone.G >= kMinGreenLevelInZone) {
|
||||||
zone.R = awbStats_[i].sum.red / counted;
|
zone.R = awbStats_[i].sum.red / counted;
|
||||||
|
@ -224,19 +241,16 @@ void Awb::generateZones(std::vector<RGB> &zones)
|
||||||
void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,
|
void Awb::generateAwbStats(const ipu3_uapi_stats_3a *stats,
|
||||||
const ipu3_uapi_grid_config &grid)
|
const ipu3_uapi_grid_config &grid)
|
||||||
{
|
{
|
||||||
uint32_t cellsPerZoneX = round(grid.width / static_cast<double>(kAwbStatsSizeX));
|
|
||||||
uint32_t cellsPerZoneY = round(grid.height / static_cast<double>(kAwbStatsSizeY));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is
|
* Generate a (kAwbStatsSizeX x kAwbStatsSizeY) array from the IPU3 grid which is
|
||||||
* (grid.width x grid.height).
|
* (grid.width x grid.height).
|
||||||
*/
|
*/
|
||||||
for (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY; cellY++) {
|
for (unsigned int cellY = 0; cellY < kAwbStatsSizeY * cellsPerZoneY_; cellY++) {
|
||||||
for (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX; cellX++) {
|
for (unsigned int cellX = 0; cellX < kAwbStatsSizeX * cellsPerZoneX_; cellX++) {
|
||||||
uint32_t cellPosition = (cellY * grid.width + cellX)
|
uint32_t cellPosition = (cellY * grid.width + cellX)
|
||||||
* sizeof(Ipu3AwbCell);
|
* sizeof(Ipu3AwbCell);
|
||||||
uint32_t zoneX = cellX / cellsPerZoneX;
|
uint32_t zoneX = cellX / cellsPerZoneX_;
|
||||||
uint32_t zoneY = cellY / cellsPerZoneY;
|
uint32_t zoneY = cellY / cellsPerZoneY_;
|
||||||
|
|
||||||
uint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;
|
uint32_t awbZonePosition = zoneY * kAwbStatsSizeX + zoneX;
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
Awb();
|
Awb();
|
||||||
~Awb();
|
~Awb();
|
||||||
|
|
||||||
|
int configure(IPAContext &context, const IPAConfigInfo &configInfo) override;
|
||||||
void prepare(IPAContext &context, ipu3_uapi_params *params) override;
|
void prepare(IPAContext &context, ipu3_uapi_params *params) override;
|
||||||
void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;
|
void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;
|
||||||
|
|
||||||
|
@ -85,6 +86,10 @@ private:
|
||||||
std::vector<RGB> zones_;
|
std::vector<RGB> zones_;
|
||||||
Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
|
Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
|
||||||
AwbStatus asyncResults_;
|
AwbStatus asyncResults_;
|
||||||
|
|
||||||
|
uint32_t cellsPerZoneX_;
|
||||||
|
uint32_t cellsPerZoneY_;
|
||||||
|
uint32_t cellsPerZoneThreshold_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace ipa::ipu3::algorithms */
|
} /* namespace ipa::ipu3::algorithms */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue