diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2021-11-16 16:29:23 +0200 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2021-11-23 10:29:30 +0200 |
commit | a2b4975a1ca0ec122227d5c8c2ef6a6aa28803e5 (patch) | |
tree | d6aa98131faad9f7f2b78423f3026fca69fc1e1d /src/ipa/ipu3/algorithms/agc.cpp | |
parent | 6e02f674578e3c40ab3f140b25422ed195e4fc28 (diff) |
ipa: ipu3: agc: Return the inter-quantile mean from measureBrightness()
The inter-quantile mean is a value that is computed as part of the AGC
run. It doesn't need to be stored in a member variable. Return it from
measureBrightness(), which makes the flow of data easier to follow.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Diffstat (limited to 'src/ipa/ipu3/algorithms/agc.cpp')
-rw-r--r-- | src/ipa/ipu3/algorithms/agc.cpp | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp index 2d196fd6..c39e213f 100644 --- a/src/ipa/ipu3/algorithms/agc.cpp +++ b/src/ipa/ipu3/algorithms/agc.cpp @@ -70,7 +70,7 @@ static constexpr uint32_t kNumStartupFrames = 10; static constexpr double kRelativeLuminanceTarget = 0.16; Agc::Agc() - : frameCount_(0), iqMean_(0.0), lineDuration_(0s), minShutterSpeed_(0s), + : frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s), maxShutterSpeed_(0s), filteredExposure_(0s), currentExposure_(0s) { } @@ -108,9 +108,10 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo) * \brief Estimate the mean value of the top 2% of the histogram * \param[in] stats The statistics computed by the ImgU * \param[in] grid The grid used to store the statistics in the IPU3 + * \return The mean value of the top 2% of the histogram */ -void Agc::measureBrightness(const ipu3_uapi_stats_3a *stats, - const ipu3_uapi_grid_config &grid) +double Agc::measureBrightness(const ipu3_uapi_stats_3a *stats, + const ipu3_uapi_grid_config &grid) const { /* Initialise the histogram array */ uint32_t hist[knumHistogramBins] = { 0 }; @@ -135,8 +136,8 @@ void Agc::measureBrightness(const ipu3_uapi_stats_3a *stats, } } - /* Estimate the quantile mean of the top 2% of the histogram */ - iqMean_ = Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0); + /* Estimate the quantile mean of the top 2% of the histogram. */ + return Histogram(Span<uint32_t>(hist)).interQuantileMean(0.98, 1.0); } /** @@ -174,28 +175,22 @@ void Agc::filterExposure() * \brief Estimate the new exposure and gain values * \param[inout] frameContext The shared IPA frame Context * \param[in] yGain The gain calculated based on the relative luminance target + * \param[in] iqMeanGain The gain calculated based on the relative luminance target */ -void Agc::computeExposure(IPAFrameContext &frameContext, double yGain) +void Agc::computeExposure(IPAFrameContext &frameContext, double yGain, + double iqMeanGain) { /* Get the effective exposure and gain applied on the sensor. */ uint32_t exposure = frameContext.sensor.exposure; double analogueGain = frameContext.sensor.gain; - /* - * Estimate the gain needed to have the proportion of pixels in a given - * desired range. iqMean_ returns the mean value of the top 2% of the - * cumulative histogram, and we want it to be as close as possible to a - * configured target. - */ - double evGain = kEvGainTarget * knumHistogramBins / iqMean_; - - if (evGain < yGain) - evGain = yGain; + /* Use the highest of the two gain estimates. */ + double evGain = std::max(yGain, iqMeanGain); /* Consider within 1% of the target as correctly exposed */ if (std::abs(evGain - 1.0) < 0.01) - LOG(IPU3Agc, Debug) << "We are well exposed (iqMean = " - << iqMean_ << ")"; + LOG(IPU3Agc, Debug) << "We are well exposed (evGain = " + << evGain << ")"; /* extracted from Rpi::Agc::computeTargetExposure */ @@ -308,15 +303,25 @@ double Agc::estimateLuminance(IPAFrameContext &frameContext, */ void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) { - measureBrightness(stats, context.configuration.grid.bdsGrid); + /* + * Estimate the gain needed to have the proportion of pixels in a given + * desired range. iqMean is the mean value of the top 2% of the + * cumulative histogram, and we want it to be as close as possible to a + * configured target. + */ + double iqMean = measureBrightness(stats, context.configuration.grid.bdsGrid); + double iqMeanGain = kEvGainTarget * knumHistogramBins / iqMean; + /* + * Estimate the gain needed to achieve a relative luminance target. To + * account for non-linearity caused by saturation, the value needs to be + * estimated in an iterative process, as multiplying by a gain will not + * increase the relative luminance by the same factor if some image + * regions are saturated. + */ double yGain = 1.0; double yTarget = kRelativeLuminanceTarget; - /* - * Do this calculation a few times as brightness increase can be - * non-linear when there are saturated regions. - */ for (unsigned int i = 0; i < 8; i++) { double yValue = estimateLuminance(context.frameContext, context.configuration.grid.bdsGrid, @@ -331,7 +336,7 @@ void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats) break; } - computeExposure(context.frameContext, yGain); + computeExposure(context.frameContext, yGain, iqMeanGain); frameCount_++; } |