summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ipa/ipu3/algorithms/agc.cpp53
-rw-r--r--src/ipa/ipu3/algorithms/agc.h9
2 files changed, 33 insertions, 29 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_++;
}
diff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h
index 0c868d67..a04a81fb 100644
--- a/src/ipa/ipu3/algorithms/agc.h
+++ b/src/ipa/ipu3/algorithms/agc.h
@@ -31,10 +31,11 @@ public:
void process(IPAContext &context, const ipu3_uapi_stats_3a *stats) override;
private:
- void measureBrightness(const ipu3_uapi_stats_3a *stats,
- const ipu3_uapi_grid_config &grid);
+ double measureBrightness(const ipu3_uapi_stats_3a *stats,
+ const ipu3_uapi_grid_config &grid) const;
void filterExposure();
- void computeExposure(IPAFrameContext &frameContext, double yGain);
+ void computeExposure(IPAFrameContext &frameContext, double yGain,
+ double iqMeanGain);
double estimateLuminance(IPAFrameContext &frameContext,
const ipu3_uapi_grid_config &grid,
const ipu3_uapi_stats_3a *stats,
@@ -42,8 +43,6 @@ private:
uint64_t frameCount_;
- double iqMean_;
-
utils::Duration lineDuration_;
utils::Duration minShutterSpeed_;
utils::Duration maxShutterSpeed_;
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341