summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Zamazal <mzamazal@redhat.com>2024-05-31 14:38:37 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2024-06-02 01:47:40 +0300
commit4e13c6f55bd667b39986d91ae06ed67ae5dabe68 (patch)
tree231806e22b1a609740ae7960b739d1ed2bb8952f
parent738bd37905060a9f1b493edb9265574b9d585be1 (diff)
libcamera: software_isp: Honor black level in AWB
The white balance computation didn't consider black level. This is wrong because then the computed ratios are off when they are computed from the whole brightness range rather than the sensor range. This patch adjusts white balance computation for the black level. There is no need to change white balance application in debayering as this is already applied after black level correction. Exposure computation already subtracts black level, no changes are needed there. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Andrei Konovalov <andrey.konovalov.ynk@gmail.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--src/ipa/simple/soft_simple.cpp35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
index a5bb2bbf..dbbeabbf 100644
--- a/src/ipa/simple/soft_simple.cpp
+++ b/src/ipa/simple/soft_simple.cpp
@@ -5,6 +5,8 @@
* Simple Software Image Processing Algorithm module
*/
+#include <numeric>
+#include <stdint.h>
#include <sys/mman.h>
#include <linux/v4l2-controls.h>
@@ -240,28 +242,35 @@ void IPASoftSimple::stop()
void IPASoftSimple::processStats(const ControlList &sensorControls)
{
+ SwIspStats::Histogram histogram = stats_->yHistogram;
+ if (ignoreUpdates_ > 0)
+ blackLevel_.update(histogram);
+ const uint8_t blackLevel = blackLevel_.get();
+ params_->blackLevel = blackLevel;
+
+ /*
+ * Black level must be subtracted to get the correct AWB ratios, they
+ * would be off if they were computed from the whole brightness range
+ * rather than from the sensor range.
+ */
+ const uint64_t nPixels = std::accumulate(
+ histogram.begin(), histogram.end(), 0);
+ const uint64_t offset = blackLevel * nPixels;
+ const uint64_t sumR = stats_->sumR_ - offset / 4;
+ const uint64_t sumG = stats_->sumG_ - offset / 2;
+ const uint64_t sumB = stats_->sumB_ - offset / 4;
+
/*
* Calculate red and blue gains for AWB.
* Clamp max gain at 4.0, this also avoids 0 division.
*/
- if (stats_->sumR_ <= stats_->sumG_ / 4)
- params_->gainR = 1024;
- else
- params_->gainR = 256 * stats_->sumG_ / stats_->sumR_;
-
- if (stats_->sumB_ <= stats_->sumG_ / 4)
- params_->gainB = 1024;
- else
- params_->gainB = 256 * stats_->sumG_ / stats_->sumB_;
+ params_->gainR = sumR <= sumG / 4 ? 1024 : 256 * sumG / sumR;
+ params_->gainB = sumB <= sumG / 4 ? 1024 : 256 * sumG / sumB;
/* Green gain and gamma values are fixed */
params_->gainG = 256;
params_->gamma = 0.5;
- if (ignoreUpdates_ > 0)
- blackLevel_.update(stats_->yHistogram);
- params_->blackLevel = blackLevel_.get();
-
setIspParams.emit();
/* \todo Switch to the libipa/algorithm.h API someday. */