@@ -11,6 +11,7 @@
#include <cmath>
#include <optional>
#include <stdint.h>
+#include <utility>
#include <libcamera/base/log.h>
@@ -66,19 +67,15 @@ static constexpr float kExpMaxStep = 0.15;
namespace {
-std::optional<float> calculateMSV(const Histogram &histogram, uint8_t blackLevel)
+std::optional<float> calculateMSV(const Histogram &histogram)
{
/*
* Calculate Mean Sample Value (MSV) according to formula from:
* https://www.araa.asn.au/acra/acra2007/papers/paper84final.pdf
*/
- const unsigned int blackLevelHistIdx =
- blackLevel * histogram.bins() / 256;
- const unsigned int histogramSize =
- histogram.bins() - blackLevelHistIdx;
- const unsigned int yHistValsPerBin = histogramSize / kExposureBinsCount;
+ const unsigned int yHistValsPerBin = histogram.bins() / kExposureBinsCount;
const unsigned int yHistValsPerBinMod =
- histogramSize / (histogramSize % kExposureBinsCount + 1);
+ histogram.bins() / (histogram.bins() % kExposureBinsCount + 1);
int exposureBins[kExposureBinsCount] = {};
unsigned int denom = 0;
unsigned int num = 0;
@@ -86,9 +83,9 @@ std::optional<float> calculateMSV(const Histogram &histogram, uint8_t blackLevel
if (yHistValsPerBin == 0)
return {};
- for (unsigned int i = 0; i < histogramSize; i++) {
+ for (unsigned int i = 0; i < histogram.bins(); i++) {
unsigned int idx = (i - (i / yHistValsPerBinMod)) / yHistValsPerBin;
- exposureBins[idx] += histogram[blackLevelHistIdx + i];
+ exposureBins[idx] += histogram[i];
}
for (unsigned int i = 0; i < kExposureBinsCount; i++) {
@@ -193,7 +190,14 @@ void Agc::process(IPAContext &context,
return;
}
- auto exposureMSV = calculateMSV({ stats->yHistogram }, context.activeState.blc.level);
+ auto histogram = stats->yHistogram;
+ const unsigned int blackLevelHistIdx =
+ context.activeState.blc.level * std::size(histogram) / 256;
+
+ for (unsigned int i = 1; i < blackLevelHistIdx; i++)
+ histogram[0] += std::exchange(histogram[i], 0);
+
+ auto exposureMSV = calculateMSV({ histogram });
if (!exposureMSV) {
LOG(IPASoftExposure, Debug)
<< "Not adjusting exposure due to insufficient histogram data";
Instead of providing the black separately, adjust the luminance histogram according to the current black level. This changes the behaviour slightly as previously everything under the black level was ignored, and only the remaining part was split into the 5 bins, but now the full histogram is split into the 5 bins. TODO: or should the previous behaviour be preserved and a smaller histogram be used without adjustments? TODO: is it `i < blackLevelHistIdx` or `i <= blackLevelHistIdx` ??? Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> --- src/ipa/simple/algorithms/agc.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)