ipa: rkisp1: Use grey world algorithm from libipa
Now that libipa contains a grey world algorithm, use that. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
This commit is contained in:
parent
b60bd37b1a
commit
deb3f05137
2 changed files with 52 additions and 27 deletions
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <libcamera/ipa/core_ipa_interface.h>
|
#include <libcamera/ipa/core_ipa_interface.h>
|
||||||
|
|
||||||
|
#include "libipa/awb_grey.h"
|
||||||
#include "libipa/colours.h"
|
#include "libipa/colours.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +41,30 @@ constexpr int32_t kDefaultColourTemperature = 5000;
|
||||||
/* Minimum mean value below which AWB can't operate. */
|
/* Minimum mean value below which AWB can't operate. */
|
||||||
constexpr double kMeanMinThreshold = 2.0;
|
constexpr double kMeanMinThreshold = 2.0;
|
||||||
|
|
||||||
|
class RkISP1AwbStats : public AwbStats
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RkISP1AwbStats(const RGB<double> &rgbMeans)
|
||||||
|
: rgbMeans_(rgbMeans)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
double computeColourError([[maybe_unused]] const RGB<double> &gains) const override
|
||||||
|
{
|
||||||
|
LOG(RkISP1Awb, Error)
|
||||||
|
<< "RkISP1AwbStats::computeColourError is not implemented";
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RGB<double> getRGBMeans() const override
|
||||||
|
{
|
||||||
|
return rgbMeans_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RGB<double> rgbMeans_;
|
||||||
|
};
|
||||||
|
|
||||||
Awb::Awb()
|
Awb::Awb()
|
||||||
: rgbMode_(false)
|
: rgbMode_(false)
|
||||||
{
|
{
|
||||||
|
@ -55,15 +80,12 @@ int Awb::init(IPAContext &context, const YamlObject &tuningData)
|
||||||
kMaxColourTemperature,
|
kMaxColourTemperature,
|
||||||
kDefaultColourTemperature);
|
kDefaultColourTemperature);
|
||||||
|
|
||||||
Interpolator<Vector<double, 2>> gainCurve;
|
awbAlgo_ = std::make_unique<AwbGrey>();
|
||||||
int ret = gainCurve.readYaml(tuningData["colourGains"], "ct", "gains");
|
int ret = awbAlgo_->init(tuningData);
|
||||||
if (ret < 0)
|
if (ret) {
|
||||||
LOG(RkISP1Awb, Warning)
|
LOG(RkISP1Awb, Error) << "Failed to init awb algorithm";
|
||||||
<< "Failed to parse 'colourGains' "
|
return ret;
|
||||||
<< "parameter from tuning file; "
|
}
|
||||||
<< "manual colour temperature will not work properly";
|
|
||||||
else
|
|
||||||
colourGainCurve_ = gainCurve;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -128,10 +150,10 @@ void Awb::queueRequest(IPAContext &context,
|
||||||
* This will be fixed with the bayes AWB algorithm.
|
* This will be fixed with the bayes AWB algorithm.
|
||||||
*/
|
*/
|
||||||
update = true;
|
update = true;
|
||||||
} else if (colourTemperature && colourGainCurve_) {
|
} else if (colourTemperature) {
|
||||||
const auto &gains = colourGainCurve_->getInterpolated(*colourTemperature);
|
const auto &gains = awbAlgo_->gainsFromColourTemperature(*colourTemperature);
|
||||||
awb.gains.manual.r() = gains[0];
|
awb.gains.manual.r() = gains.r();
|
||||||
awb.gains.manual.b() = gains[1];
|
awb.gains.manual.b() = gains.b();
|
||||||
awb.temperatureK = *colourTemperature;
|
awb.temperatureK = *colourTemperature;
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
@ -251,33 +273,34 @@ void Awb::process(IPAContext &context,
|
||||||
rgbMeans.b() < kMeanMinThreshold)
|
rgbMeans.b() < kMeanMinThreshold)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
activeState.awb.temperatureK = estimateCCT(rgbMeans);
|
/*
|
||||||
|
* \Todo: Hardcode lux to a fixed value, until an estimation is
|
||||||
|
* implemented.
|
||||||
|
*/
|
||||||
|
int lux = 1000;
|
||||||
|
|
||||||
|
RkISP1AwbStats awbStats{ rgbMeans };
|
||||||
|
AwbResult awbResult = awbAlgo_->calculateAwb(awbStats, lux);
|
||||||
|
|
||||||
|
activeState.awb.temperatureK = awbResult.colourTemperature;
|
||||||
|
|
||||||
/* Metadata shall contain the up to date measurement */
|
/* Metadata shall contain the up to date measurement */
|
||||||
metadata.set(controls::ColourTemperature, activeState.awb.temperatureK);
|
metadata.set(controls::ColourTemperature, activeState.awb.temperatureK);
|
||||||
|
|
||||||
/*
|
|
||||||
* Estimate the red and blue gains to apply in a grey world. The green
|
|
||||||
* gain is hardcoded to 1.0. Avoid divisions by zero by clamping the
|
|
||||||
* divisor to a minimum value of 1.0.
|
|
||||||
*/
|
|
||||||
RGB<double> gains({ rgbMeans.g() / std::max(rgbMeans.r(), 1.0),
|
|
||||||
1.0,
|
|
||||||
rgbMeans.g() / std::max(rgbMeans.b(), 1.0) });
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clamp the gain values to the hardware, which expresses gains as Q2.8
|
* Clamp the gain values to the hardware, which expresses gains as Q2.8
|
||||||
* unsigned integer values. Set the minimum just above zero to avoid
|
* unsigned integer values. Set the minimum just above zero to avoid
|
||||||
* divisions by zero when computing the raw means in subsequent
|
* divisions by zero when computing the raw means in subsequent
|
||||||
* iterations.
|
* iterations.
|
||||||
*/
|
*/
|
||||||
gains = gains.max(1.0 / 256).min(1023.0 / 256);
|
awbResult.gains = awbResult.gains.max(1.0 / 256).min(1023.0 / 256);
|
||||||
|
|
||||||
/* Filter the values to avoid oscillations. */
|
/* Filter the values to avoid oscillations. */
|
||||||
double speed = 0.2;
|
double speed = 0.2;
|
||||||
gains = gains * speed + activeState.awb.gains.automatic * (1 - speed);
|
awbResult.gains = awbResult.gains * speed +
|
||||||
|
activeState.awb.gains.automatic * (1 - speed);
|
||||||
|
|
||||||
activeState.awb.gains.automatic = gains;
|
activeState.awb.gains.automatic = awbResult.gains;
|
||||||
|
|
||||||
LOG(RkISP1Awb, Debug)
|
LOG(RkISP1Awb, Debug)
|
||||||
<< std::showpoint
|
<< std::showpoint
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "libcamera/internal/vector.h"
|
#include "libcamera/internal/vector.h"
|
||||||
|
|
||||||
|
#include "libipa/awb.h"
|
||||||
#include "libipa/interpolator.h"
|
#include "libipa/interpolator.h"
|
||||||
|
|
||||||
#include "algorithm.h"
|
#include "algorithm.h"
|
||||||
|
@ -42,7 +43,8 @@ private:
|
||||||
RGB<double> calculateRgbMeans(const IPAFrameContext &frameContext,
|
RGB<double> calculateRgbMeans(const IPAFrameContext &frameContext,
|
||||||
const rkisp1_cif_isp_awb_stat *awb) const;
|
const rkisp1_cif_isp_awb_stat *awb) const;
|
||||||
|
|
||||||
std::optional<Interpolator<Vector<double, 2>>> colourGainCurve_;
|
std::unique_ptr<AwbAlgorithm> awbAlgo_;
|
||||||
|
|
||||||
bool rgbMode_;
|
bool rgbMode_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue