summaryrefslogtreecommitdiff
path: root/src/ipa/rpi/controller/rpi
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipa/rpi/controller/rpi')
-rw-r--r--src/ipa/rpi/controller/rpi/af.cpp6
-rw-r--r--src/ipa/rpi/controller/rpi/af.h7
-rw-r--r--src/ipa/rpi/controller/rpi/agc.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/agc.h2
-rw-r--r--src/ipa/rpi/controller/rpi/agc_channel.cpp10
-rw-r--r--src/ipa/rpi/controller/rpi/agc_channel.h9
-rw-r--r--src/ipa/rpi/controller/rpi/alsc.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/alsc.h2
-rw-r--r--src/ipa/rpi/controller/rpi/awb.cpp86
-rw-r--r--src/ipa/rpi/controller/rpi/awb.h25
-rw-r--r--src/ipa/rpi/controller/rpi/black_level.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/black_level.h2
-rw-r--r--src/ipa/rpi/controller/rpi/cac.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/ccm.cpp6
-rw-r--r--src/ipa/rpi/controller/rpi/ccm.h7
-rw-r--r--src/ipa/rpi/controller/rpi/contrast.cpp16
-rw-r--r--src/ipa/rpi/controller/rpi/contrast.h7
-rw-r--r--src/ipa/rpi/controller/rpi/denoise.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/dpc.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/dpc.h2
-rw-r--r--src/ipa/rpi/controller/rpi/focus.h2
-rw-r--r--src/ipa/rpi/controller/rpi/geq.cpp7
-rw-r--r--src/ipa/rpi/controller/rpi/geq.h6
-rw-r--r--src/ipa/rpi/controller/rpi/hdr.cpp118
-rw-r--r--src/ipa/rpi/controller/rpi/hdr.h19
-rw-r--r--src/ipa/rpi/controller/rpi/lux.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/lux.h2
-rw-r--r--src/ipa/rpi/controller/rpi/noise.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/noise.h2
-rw-r--r--src/ipa/rpi/controller/rpi/saturation.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/sdn.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/sdn.h2
-rw-r--r--src/ipa/rpi/controller/rpi/sharpen.cpp2
-rw-r--r--src/ipa/rpi/controller/rpi/sharpen.h2
-rw-r--r--src/ipa/rpi/controller/rpi/tonemap.cpp4
-rw-r--r--src/ipa/rpi/controller/rpi/tonemap.h5
36 files changed, 238 insertions, 140 deletions
diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp
index ed0c8a94..304629d6 100644
--- a/src/ipa/rpi/controller/rpi/af.cpp
+++ b/src/ipa/rpi/controller/rpi/af.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2022-2023, Raspberry Pi Ltd
*
- * af.cpp - Autofocus control algorithm
+ * Autofocus control algorithm
*/
#include "af.h"
@@ -139,7 +139,7 @@ int Af::CfgParams::read(const libcamera::YamlObject &params)
readNumber<uint32_t>(skipFrames, params, "skip_frames");
if (params.contains("map"))
- map.read(params["map"]);
+ map.readYaml(params["map"]);
else
LOG(RPiAf, Warning) << "No map defined";
@@ -721,7 +721,7 @@ bool Af::setLensPosition(double dioptres, int *hwpos)
if (mode_ == AfModeManual) {
LOG(RPiAf, Debug) << "setLensPosition: " << dioptres;
- ftarget_ = cfg_.map.domain().clip(dioptres);
+ ftarget_ = cfg_.map.domain().clamp(dioptres);
changed = !(initted_ && fsmooth_ == ftarget_);
updateLensPosition();
}
diff --git a/src/ipa/rpi/controller/rpi/af.h b/src/ipa/rpi/controller/rpi/af.h
index 6d2bae67..317a51f3 100644
--- a/src/ipa/rpi/controller/rpi/af.h
+++ b/src/ipa/rpi/controller/rpi/af.h
@@ -2,14 +2,15 @@
/*
* Copyright (C) 2022-2023, Raspberry Pi Ltd
*
- * af.h - Autofocus control algorithm
+ * Autofocus control algorithm
*/
#pragma once
#include "../af_algorithm.h"
#include "../af_status.h"
#include "../pdaf_data.h"
-#include "../pwl.h"
+
+#include "libipa/pwl.h"
/*
* This algorithm implements a hybrid of CDAF and PDAF, favouring PDAF.
@@ -100,7 +101,7 @@ private:
uint32_t confThresh; /* PDAF confidence cell min (sensor-specific) */
uint32_t confClip; /* PDAF confidence cell max (sensor-specific) */
uint32_t skipFrames; /* frames to skip at start or modeswitch */
- Pwl map; /* converts dioptres -> lens driver position */
+ libcamera::ipa::Pwl map; /* converts dioptres -> lens driver position */
CfgParams();
int read(const libcamera::YamlObject &params);
diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
index 6549dedd..fcf7aec9 100644
--- a/src/ipa/rpi/controller/rpi/agc.cpp
+++ b/src/ipa/rpi/controller/rpi/agc.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * agc.cpp - AGC/AEC control algorithm
+ * AGC/AEC control algorithm
*/
#include "agc.h"
diff --git a/src/ipa/rpi/controller/rpi/agc.h b/src/ipa/rpi/controller/rpi/agc.h
index 7d26bdf6..5d056f02 100644
--- a/src/ipa/rpi/controller/rpi/agc.h
+++ b/src/ipa/rpi/controller/rpi/agc.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * agc.h - AGC/AEC control algorithm
+ * AGC/AEC control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
index 8116c6c1..a381dd97 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
+++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2023, Raspberry Pi Ltd
*
- * agc_channel.cpp - AGC/AEC control algorithm
+ * AGC/AEC control algorithm
*/
#include "agc_channel.h"
@@ -130,7 +130,7 @@ int AgcConstraint::read(const libcamera::YamlObject &params)
return -EINVAL;
qHi = *value;
- return yTarget.read(params["y_target"]);
+ return yTarget.readYaml(params["y_target"]);
}
static std::tuple<int, AgcConstraintMode>
@@ -237,7 +237,7 @@ int AgcConfig::read(const libcamera::YamlObject &params)
return ret;
}
- ret = yTarget.read(params["y_target"]);
+ ret = yTarget.readYaml(params["y_target"]);
if (ret)
return ret;
@@ -715,7 +715,7 @@ static constexpr double EvGainYTargetLimit = 0.9;
static double constraintComputeGain(AgcConstraint &c, const Histogram &h, double lux,
double evGain, double &targetY)
{
- targetY = c.yTarget.eval(c.yTarget.domain().clip(lux));
+ targetY = c.yTarget.eval(c.yTarget.domain().clamp(lux));
targetY = std::min(EvGainYTargetLimit, targetY * evGain);
double iqm = h.interQuantileMean(c.qLo, c.qHi);
return (targetY * h.bins()) / iqm;
@@ -734,7 +734,7 @@ void AgcChannel::computeGain(StatisticsPtr &statistics, Metadata *imageMetadata,
* The initial gain and target_Y come from some of the regions. After
* that we consider the histogram constraints.
*/
- targetY = config_.yTarget.eval(config_.yTarget.domain().clip(lux.lux));
+ targetY = config_.yTarget.eval(config_.yTarget.domain().clamp(lux.lux));
targetY = std::min(EvGainYTargetLimit, targetY * evGain);
/*
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.h b/src/ipa/rpi/controller/rpi/agc_channel.h
index 4cf7233e..58368889 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.h
+++ b/src/ipa/rpi/controller/rpi/agc_channel.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2023, Raspberry Pi Ltd
*
- * agc_channel.h - AGC/AEC control algorithm
+ * AGC/AEC control algorithm
*/
#pragma once
@@ -12,10 +12,11 @@
#include <libcamera/base/utils.h>
+#include <libipa/pwl.h>
+
#include "../agc_status.h"
#include "../awb_status.h"
#include "../controller.h"
-#include "../pwl.h"
/* This is our implementation of AGC. */
@@ -40,7 +41,7 @@ struct AgcConstraint {
Bound bound;
double qLo;
double qHi;
- Pwl yTarget;
+ libcamera::ipa::Pwl yTarget;
int read(const libcamera::YamlObject &params);
};
@@ -61,7 +62,7 @@ struct AgcConfig {
std::map<std::string, AgcExposureMode> exposureModes;
std::map<std::string, AgcConstraintMode> constraintModes;
std::vector<AgcChannelConstraint> channelConstraints;
- Pwl yTarget;
+ libcamera::ipa::Pwl yTarget;
double speed;
uint16_t startupFrames;
unsigned int convergenceFrames;
diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp
index 8a205c60..67029fc3 100644
--- a/src/ipa/rpi/controller/rpi/alsc.cpp
+++ b/src/ipa/rpi/controller/rpi/alsc.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * alsc.cpp - ALSC (auto lens shading correction) control algorithm
+ * ALSC (auto lens shading correction) control algorithm
*/
#include <algorithm>
diff --git a/src/ipa/rpi/controller/rpi/alsc.h b/src/ipa/rpi/controller/rpi/alsc.h
index 0b6d9478..31087982 100644
--- a/src/ipa/rpi/controller/rpi/alsc.h
+++ b/src/ipa/rpi/controller/rpi/alsc.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * alsc.h - ALSC (auto lens shading correction) control algorithm
+ * ALSC (auto lens shading correction) control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp
index dde5785a..603953d7 100644
--- a/src/ipa/rpi/controller/rpi/awb.cpp
+++ b/src/ipa/rpi/controller/rpi/awb.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * awb.cpp - AWB control algorithm
+ * AWB control algorithm
*/
#include <assert.h>
@@ -49,10 +49,10 @@ int AwbPrior::read(const libcamera::YamlObject &params)
return -EINVAL;
lux = *value;
- return prior.read(params["prior"]);
+ return prior.readYaml(params["prior"]);
}
-static int readCtCurve(Pwl &ctR, Pwl &ctB, const libcamera::YamlObject &params)
+static int readCtCurve(ipa::Pwl &ctR, ipa::Pwl &ctB, const libcamera::YamlObject &params)
{
if (params.size() % 3) {
LOG(RPiAwb, Error) << "AwbConfig: incomplete CT curve entry";
@@ -103,8 +103,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
if (ret)
return ret;
/* We will want the inverse functions of these too. */
- ctRInverse = ctR.inverse();
- ctBInverse = ctB.inverse();
+ ctRInverse = ctR.inverse().first;
+ ctBInverse = ctB.inverse().first;
}
if (params.contains("priors")) {
@@ -207,7 +207,7 @@ void Awb::initialise()
* them.
*/
if (!config_.ctR.empty() && !config_.ctB.empty()) {
- syncResults_.temperatureK = config_.ctR.domain().clip(4000);
+ syncResults_.temperatureK = config_.ctR.domain().clamp(4000);
syncResults_.gainR = 1.0 / config_.ctR.eval(syncResults_.temperatureK);
syncResults_.gainG = 1.0;
syncResults_.gainB = 1.0 / config_.ctB.eval(syncResults_.temperatureK);
@@ -273,8 +273,8 @@ void Awb::setManualGains(double manualR, double manualB)
syncResults_.gainB = prevSyncResults_.gainB = manualB_;
if (config_.bayes) {
/* Also estimate the best corresponding colour temperature from the curves. */
- double ctR = config_.ctRInverse.eval(config_.ctRInverse.domain().clip(1 / manualR_));
- double ctB = config_.ctBInverse.eval(config_.ctBInverse.domain().clip(1 / manualB_));
+ double ctR = config_.ctRInverse.eval(config_.ctRInverse.domain().clamp(1 / manualR_));
+ double ctB = config_.ctBInverse.eval(config_.ctBInverse.domain().clamp(1 / manualB_));
prevSyncResults_.temperatureK = (ctR + ctB) / 2;
syncResults_.temperatureK = prevSyncResults_.temperatureK;
}
@@ -468,7 +468,7 @@ double Awb::computeDelta2Sum(double gainR, double gainB)
return delta2Sum;
}
-Pwl Awb::interpolatePrior()
+ipa::Pwl Awb::interpolatePrior()
{
/*
* Interpolate the prior log likelihood function for our current lux
@@ -485,7 +485,7 @@ Pwl Awb::interpolatePrior()
idx++;
double lux0 = config_.priors[idx].lux,
lux1 = config_.priors[idx + 1].lux;
- return Pwl::combine(config_.priors[idx].prior,
+ return ipa::Pwl::combine(config_.priors[idx].prior,
config_.priors[idx + 1].prior,
[&](double /*x*/, double y0, double y1) {
return y0 + (y1 - y0) *
@@ -494,26 +494,26 @@ Pwl Awb::interpolatePrior()
}
}
-static double interpolateQuadatric(Pwl::Point const &a, Pwl::Point const &b,
- Pwl::Point const &c)
+static double interpolateQuadatric(ipa::Pwl::Point const &a, ipa::Pwl::Point const &b,
+ ipa::Pwl::Point const &c)
{
/*
* Given 3 points on a curve, find the extremum of the function in that
* interval by fitting a quadratic.
*/
const double eps = 1e-3;
- Pwl::Point ca = c - a, ba = b - a;
- double denominator = 2 * (ba.y * ca.x - ca.y * ba.x);
+ ipa::Pwl::Point ca = c - a, ba = b - a;
+ double denominator = 2 * (ba.y() * ca.x() - ca.y() * ba.x());
if (abs(denominator) > eps) {
- double numerator = ba.y * ca.x * ca.x - ca.y * ba.x * ba.x;
- double result = numerator / denominator + a.x;
- return std::max(a.x, std::min(c.x, result));
+ double numerator = ba.y() * ca.x() * ca.x() - ca.y() * ba.x() * ba.x();
+ double result = numerator / denominator + a.x();
+ return std::max(a.x(), std::min(c.x(), result));
}
/* has degenerated to straight line segment */
- return a.y < c.y - eps ? a.x : (c.y < a.y - eps ? c.x : b.x);
+ return a.y() < c.y() - eps ? a.x() : (c.y() < a.y() - eps ? c.x() : b.x());
}
-double Awb::coarseSearch(Pwl const &prior)
+double Awb::coarseSearch(ipa::Pwl const &prior)
{
points_.clear(); /* assume doesn't deallocate memory */
size_t bestPoint = 0;
@@ -525,22 +525,22 @@ double Awb::coarseSearch(Pwl const &prior)
double b = config_.ctB.eval(t, &spanB);
double gainR = 1 / r, gainB = 1 / b;
double delta2Sum = computeDelta2Sum(gainR, gainB);
- double priorLogLikelihood = prior.eval(prior.domain().clip(t));
+ double priorLogLikelihood = prior.eval(prior.domain().clamp(t));
double finalLogLikelihood = delta2Sum - priorLogLikelihood;
LOG(RPiAwb, Debug)
<< "t: " << t << " gain R " << gainR << " gain B "
<< gainB << " delta2_sum " << delta2Sum
<< " prior " << priorLogLikelihood << " final "
<< finalLogLikelihood;
- points_.push_back(Pwl::Point(t, finalLogLikelihood));
- if (points_.back().y < points_[bestPoint].y)
+ points_.push_back(ipa::Pwl::Point({ t, finalLogLikelihood }));
+ if (points_.back().y() < points_[bestPoint].y())
bestPoint = points_.size() - 1;
if (t == mode_->ctHi)
break;
/* for even steps along the r/b curve scale them by the current t */
t = std::min(t + t / 10 * config_.coarseStep, mode_->ctHi);
}
- t = points_[bestPoint].x;
+ t = points_[bestPoint].x();
LOG(RPiAwb, Debug) << "Coarse search found CT " << t;
/*
* We have the best point of the search, but refine it with a quadratic
@@ -559,7 +559,7 @@ double Awb::coarseSearch(Pwl const &prior)
return t;
}
-void Awb::fineSearch(double &t, double &r, double &b, Pwl const &prior)
+void Awb::fineSearch(double &t, double &r, double &b, ipa::Pwl const &prior)
{
int spanR = -1, spanB = -1;
config_.ctR.eval(t, &spanR);
@@ -570,14 +570,14 @@ void Awb::fineSearch(double &t, double &r, double &b, Pwl const &prior)
config_.ctR.eval(t - nsteps * step, &spanR);
double bDiff = config_.ctB.eval(t + nsteps * step, &spanB) -
config_.ctB.eval(t - nsteps * step, &spanB);
- Pwl::Point transverse(bDiff, -rDiff);
- if (transverse.len2() < 1e-6)
+ ipa::Pwl::Point transverse({ bDiff, -rDiff });
+ if (transverse.length2() < 1e-6)
return;
/*
* unit vector orthogonal to the b vs. r function (pointing outwards
* with r and b increasing)
*/
- transverse = transverse / transverse.len();
+ transverse = transverse / transverse.length();
double bestLogLikelihood = 0, bestT = 0, bestR = 0, bestB = 0;
double transverseRange = config_.transverseNeg + config_.transversePos;
const int maxNumDeltas = 12;
@@ -592,26 +592,26 @@ void Awb::fineSearch(double &t, double &r, double &b, Pwl const &prior)
for (int i = -nsteps; i <= nsteps; i++) {
double tTest = t + i * step;
double priorLogLikelihood =
- prior.eval(prior.domain().clip(tTest));
+ prior.eval(prior.domain().clamp(tTest));
double rCurve = config_.ctR.eval(tTest, &spanR);
double bCurve = config_.ctB.eval(tTest, &spanB);
/* x will be distance off the curve, y the log likelihood there */
- Pwl::Point points[maxNumDeltas];
+ ipa::Pwl::Point points[maxNumDeltas];
int bestPoint = 0;
/* Take some measurements transversely *off* the CT curve. */
for (int j = 0; j < numDeltas; j++) {
- points[j].x = -config_.transverseNeg +
- (transverseRange * j) / (numDeltas - 1);
- Pwl::Point rbTest = Pwl::Point(rCurve, bCurve) +
- transverse * points[j].x;
- double rTest = rbTest.x, bTest = rbTest.y;
+ points[j][0] = -config_.transverseNeg +
+ (transverseRange * j) / (numDeltas - 1);
+ ipa::Pwl::Point rbTest = ipa::Pwl::Point({ rCurve, bCurve }) +
+ transverse * points[j].x();
+ double rTest = rbTest.x(), bTest = rbTest.y();
double gainR = 1 / rTest, gainB = 1 / bTest;
double delta2Sum = computeDelta2Sum(gainR, gainB);
- points[j].y = delta2Sum - priorLogLikelihood;
+ points[j][1] = delta2Sum - priorLogLikelihood;
LOG(RPiAwb, Debug)
<< "At t " << tTest << " r " << rTest << " b "
- << bTest << ": " << points[j].y;
- if (points[j].y < points[bestPoint].y)
+ << bTest << ": " << points[j].y();
+ if (points[j].y() < points[bestPoint].y())
bestPoint = j;
}
/*
@@ -619,11 +619,11 @@ void Awb::fineSearch(double &t, double &r, double &b, Pwl const &prior)
* now let's do a quadratic interpolation for the best result.
*/
bestPoint = std::max(1, std::min(bestPoint, numDeltas - 2));
- Pwl::Point rbTest = Pwl::Point(rCurve, bCurve) +
- transverse * interpolateQuadatric(points[bestPoint - 1],
- points[bestPoint],
- points[bestPoint + 1]);
- double rTest = rbTest.x, bTest = rbTest.y;
+ ipa::Pwl::Point rbTest = ipa::Pwl::Point({ rCurve, bCurve }) +
+ transverse * interpolateQuadatric(points[bestPoint - 1],
+ points[bestPoint],
+ points[bestPoint + 1]);
+ double rTest = rbTest.x(), bTest = rbTest.y();
double gainR = 1 / rTest, gainB = 1 / bTest;
double delta2Sum = computeDelta2Sum(gainR, gainB);
double finalLogLikelihood = delta2Sum - priorLogLikelihood;
@@ -653,7 +653,7 @@ void Awb::awbBayes()
* Get the current prior, and scale according to how many zones are
* valid... not entirely sure about this.
*/
- Pwl prior = interpolatePrior();
+ ipa::Pwl prior = interpolatePrior();
prior *= zones_.size() / (double)(statistics_->awbRegions.numRegions());
prior.map([](double x, double y) {
LOG(RPiAwb, Debug) << "(" << x << "," << y << ")";
diff --git a/src/ipa/rpi/controller/rpi/awb.h b/src/ipa/rpi/controller/rpi/awb.h
index cde6a62f..ab30f4fa 100644
--- a/src/ipa/rpi/controller/rpi/awb.h
+++ b/src/ipa/rpi/controller/rpi/awb.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * awb.h - AWB control algorithm
+ * AWB control algorithm
*/
#pragma once
@@ -10,11 +10,14 @@
#include <condition_variable>
#include <thread>
+#include <libcamera/geometry.h>
+
#include "../awb_algorithm.h"
-#include "../pwl.h"
#include "../awb_status.h"
#include "../statistics.h"
+#include "libipa/pwl.h"
+
namespace RPiController {
/* Control algorithm to perform AWB calculations. */
@@ -28,7 +31,7 @@ struct AwbMode {
struct AwbPrior {
int read(const libcamera::YamlObject &params);
double lux; /* lux level */
- Pwl prior; /* maps CT to prior log likelihood for this lux level */
+ libcamera::ipa::Pwl prior; /* maps CT to prior log likelihood for this lux level */
};
struct AwbConfig {
@@ -41,10 +44,10 @@ struct AwbConfig {
unsigned int convergenceFrames; /* approx number of frames to converge */
double speed; /* IIR filter speed applied to algorithm results */
bool fast; /* "fast" mode uses a 16x16 rather than 32x32 grid */
- Pwl ctR; /* function maps CT to r (= R/G) */
- Pwl ctB; /* function maps CT to b (= B/G) */
- Pwl ctRInverse; /* inverse of ctR */
- Pwl ctBInverse; /* inverse of ctB */
+ libcamera::ipa::Pwl ctR; /* function maps CT to r (= R/G) */
+ libcamera::ipa::Pwl ctB; /* function maps CT to b (= B/G) */
+ libcamera::ipa::Pwl ctRInverse; /* inverse of ctR */
+ libcamera::ipa::Pwl ctBInverse; /* inverse of ctB */
/* table of illuminant priors at different lux levels */
std::vector<AwbPrior> priors;
/* AWB "modes" (determines the search range) */
@@ -161,11 +164,11 @@ private:
void awbGrey();
void prepareStats();
double computeDelta2Sum(double gainR, double gainB);
- Pwl interpolatePrior();
- double coarseSearch(Pwl const &prior);
- void fineSearch(double &t, double &r, double &b, Pwl const &prior);
+ libcamera::ipa::Pwl interpolatePrior();
+ double coarseSearch(libcamera::ipa::Pwl const &prior);
+ void fineSearch(double &t, double &r, double &b, libcamera::ipa::Pwl const &prior);
std::vector<RGB> zones_;
- std::vector<Pwl::Point> points_;
+ std::vector<libcamera::ipa::Pwl::Point> points_;
/* manual r setting */
double manualR_;
/* manual b setting */
diff --git a/src/ipa/rpi/controller/rpi/black_level.cpp b/src/ipa/rpi/controller/rpi/black_level.cpp
index 2e3db51f..ea991df9 100644
--- a/src/ipa/rpi/controller/rpi/black_level.cpp
+++ b/src/ipa/rpi/controller/rpi/black_level.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * black_level.cpp - black level control algorithm
+ * black level control algorithm
*/
#include <math.h>
diff --git a/src/ipa/rpi/controller/rpi/black_level.h b/src/ipa/rpi/controller/rpi/black_level.h
index d8c41c62..f50729db 100644
--- a/src/ipa/rpi/controller/rpi/black_level.h
+++ b/src/ipa/rpi/controller/rpi/black_level.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * black_level.h - black level control algorithm
+ * black level control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/cac.cpp b/src/ipa/rpi/controller/rpi/cac.cpp
index f2c8d282..17779ad5 100644
--- a/src/ipa/rpi/controller/rpi/cac.cpp
+++ b/src/ipa/rpi/controller/rpi/cac.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2023 Raspberry Pi Ltd
*
- * cac.cpp - Chromatic Aberration Correction algorithm
+ * Chromatic Aberration Correction algorithm
*/
#include "cac.h"
diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp
index 2e2e6664..3272a141 100644
--- a/src/ipa/rpi/controller/rpi/ccm.cpp
+++ b/src/ipa/rpi/controller/rpi/ccm.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * ccm.cpp - CCM (colour correction matrix) control algorithm
+ * CCM (colour correction matrix) control algorithm
*/
#include <libcamera/base/log.h>
@@ -71,7 +71,7 @@ int Ccm::read(const libcamera::YamlObject &params)
int ret;
if (params.contains("saturation")) {
- ret = config_.saturation.read(params["saturation"]);
+ ret = config_.saturation.readYaml(params["saturation"]);
if (ret)
return ret;
}
@@ -172,7 +172,7 @@ void Ccm::prepare(Metadata *imageMetadata)
ccmStatus.saturation = saturation;
if (!config_.saturation.empty())
saturation *= config_.saturation.eval(
- config_.saturation.domain().clip(lux.lux));
+ config_.saturation.domain().clamp(lux.lux));
ccm = applySaturation(ccm, saturation);
for (int j = 0; j < 3; j++)
for (int i = 0; i < 3; i++)
diff --git a/src/ipa/rpi/controller/rpi/ccm.h b/src/ipa/rpi/controller/rpi/ccm.h
index 286d0b33..4e5b33fe 100644
--- a/src/ipa/rpi/controller/rpi/ccm.h
+++ b/src/ipa/rpi/controller/rpi/ccm.h
@@ -2,14 +2,15 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * ccm.h - CCM (colour correction matrix) control algorithm
+ * CCM (colour correction matrix) control algorithm
*/
#pragma once
#include <vector>
+#include <libipa/pwl.h>
+
#include "../ccm_algorithm.h"
-#include "../pwl.h"
namespace RPiController {
@@ -54,7 +55,7 @@ struct CtCcm {
struct CcmConfig {
std::vector<CtCcm> ccms;
- Pwl saturation;
+ libcamera::ipa::Pwl saturation;
};
class Ccm : public CcmAlgorithm
diff --git a/src/ipa/rpi/controller/rpi/contrast.cpp b/src/ipa/rpi/controller/rpi/contrast.cpp
index 4e038a02..66871a61 100644
--- a/src/ipa/rpi/controller/rpi/contrast.cpp
+++ b/src/ipa/rpi/controller/rpi/contrast.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * contrast.cpp - contrast (gamma) control algorithm
+ * contrast (gamma) control algorithm
*/
#include <stdint.h>
@@ -53,7 +53,7 @@ int Contrast::read(const libcamera::YamlObject &params)
config_.hiHistogram = params["hi_histogram"].get<double>(0.95);
config_.hiLevel = params["hi_level"].get<double>(0.95);
config_.hiMax = params["hi_max"].get<double>(2000);
- return config_.gammaCurve.read(params["gamma_curve"]);
+ return config_.gammaCurve.readYaml(params["gamma_curve"]);
}
void Contrast::setBrightness(double brightness)
@@ -92,10 +92,10 @@ void Contrast::prepare(Metadata *imageMetadata)
imageMetadata->set("contrast.status", status_);
}
-Pwl computeStretchCurve(Histogram const &histogram,
+ipa::Pwl computeStretchCurve(Histogram const &histogram,
ContrastConfig const &config)
{
- Pwl enhance;
+ ipa::Pwl enhance;
enhance.append(0, 0);
/*
* If the start of the histogram is rather empty, try to pull it down a
@@ -136,10 +136,10 @@ Pwl computeStretchCurve(Histogram const &histogram,
return enhance;
}
-Pwl applyManualContrast(Pwl const &gammaCurve, double brightness,
- double contrast)
+ipa::Pwl applyManualContrast(ipa::Pwl const &gammaCurve, double brightness,
+ double contrast)
{
- Pwl newGammaCurve;
+ ipa::Pwl newGammaCurve;
LOG(RPiContrast, Debug)
<< "Manual brightness " << brightness << " contrast " << contrast;
gammaCurve.map([&](double x, double y) {
@@ -160,7 +160,7 @@ void Contrast::process(StatisticsPtr &stats,
* ways: 1. Adjust the gamma curve so as to pull the start of the
* histogram down, and possibly push the end up.
*/
- Pwl gammaCurve = config_.gammaCurve;
+ ipa::Pwl gammaCurve = config_.gammaCurve;
if (ceEnable_) {
if (config_.loMax != 0 || config_.hiMax != 0)
gammaCurve = computeStretchCurve(histogram, config_).compose(gammaCurve);
diff --git a/src/ipa/rpi/controller/rpi/contrast.h b/src/ipa/rpi/controller/rpi/contrast.h
index 59aa70dc..c0f7db98 100644
--- a/src/ipa/rpi/controller/rpi/contrast.h
+++ b/src/ipa/rpi/controller/rpi/contrast.h
@@ -2,14 +2,15 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * contrast.h - contrast (gamma) control algorithm
+ * contrast (gamma) control algorithm
*/
#pragma once
#include <mutex>
+#include <libipa/pwl.h>
+
#include "../contrast_algorithm.h"
-#include "../pwl.h"
namespace RPiController {
@@ -26,7 +27,7 @@ struct ContrastConfig {
double hiHistogram;
double hiLevel;
double hiMax;
- Pwl gammaCurve;
+ libcamera::ipa::Pwl gammaCurve;
};
class Contrast : public ContrastAlgorithm
diff --git a/src/ipa/rpi/controller/rpi/denoise.cpp b/src/ipa/rpi/controller/rpi/denoise.cpp
index 154ee604..ba851658 100644
--- a/src/ipa/rpi/controller/rpi/denoise.cpp
+++ b/src/ipa/rpi/controller/rpi/denoise.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2022 Raspberry Pi Ltd
*
- * Denoise.cpp - Denoise (spatial, colour, temporal) control algorithm
+ * Denoise (spatial, colour, temporal) control algorithm
*/
#include "denoise.h"
diff --git a/src/ipa/rpi/controller/rpi/dpc.cpp b/src/ipa/rpi/controller/rpi/dpc.cpp
index be3871df..8aac03f7 100644
--- a/src/ipa/rpi/controller/rpi/dpc.cpp
+++ b/src/ipa/rpi/controller/rpi/dpc.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * dpc.cpp - DPC (defective pixel correction) control algorithm
+ * DPC (defective pixel correction) control algorithm
*/
#include <libcamera/base/log.h>
diff --git a/src/ipa/rpi/controller/rpi/dpc.h b/src/ipa/rpi/controller/rpi/dpc.h
index 84a05604..9cefb06d 100644
--- a/src/ipa/rpi/controller/rpi/dpc.h
+++ b/src/ipa/rpi/controller/rpi/dpc.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * dpc.h - DPC (defective pixel correction) control algorithm
+ * DPC (defective pixel correction) control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/focus.h b/src/ipa/rpi/controller/rpi/focus.h
index 8556039d..ee014be9 100644
--- a/src/ipa/rpi/controller/rpi/focus.h
+++ b/src/ipa/rpi/controller/rpi/focus.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2020, Raspberry Pi Ltd
*
- * focus.h - focus algorithm
+ * focus algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp
index 510870e9..c9c38ebf 100644
--- a/src/ipa/rpi/controller/rpi/geq.cpp
+++ b/src/ipa/rpi/controller/rpi/geq.cpp
@@ -2,14 +2,13 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * geq.cpp - GEQ (green equalisation) control algorithm
+ * GEQ (green equalisation) control algorithm
*/
#include <libcamera/base/log.h>
#include "../device_status.h"
#include "../lux_status.h"
-#include "../pwl.h"
#include "geq.h"
@@ -45,7 +44,7 @@ int Geq::read(const libcamera::YamlObject &params)
}
if (params.contains("strength")) {
- int ret = config_.strength.read(params["strength"]);
+ int ret = config_.strength.readYaml(params["strength"]);
if (ret)
return ret;
}
@@ -67,7 +66,7 @@ void Geq::prepare(Metadata *imageMetadata)
GeqStatus geqStatus = {};
double strength = config_.strength.empty()
? 1.0
- : config_.strength.eval(config_.strength.domain().clip(luxStatus.lux));
+ : config_.strength.eval(config_.strength.domain().clamp(luxStatus.lux));
strength *= deviceStatus.analogueGain;
double offset = config_.offset * strength;
double slope = config_.slope * strength;
diff --git a/src/ipa/rpi/controller/rpi/geq.h b/src/ipa/rpi/controller/rpi/geq.h
index ee3a52ff..e8b9f427 100644
--- a/src/ipa/rpi/controller/rpi/geq.h
+++ b/src/ipa/rpi/controller/rpi/geq.h
@@ -2,10 +2,12 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * geq.h - GEQ (green equalisation) control algorithm
+ * GEQ (green equalisation) control algorithm
*/
#pragma once
+#include <libipa/pwl.h>
+
#include "../algorithm.h"
#include "../geq_status.h"
@@ -16,7 +18,7 @@ namespace RPiController {
struct GeqConfig {
uint16_t offset;
double slope;
- Pwl strength; /* lux to strength factor */
+ libcamera::ipa::Pwl strength; /* lux to strength factor */
};
class Geq : public Algorithm
diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp
index fb580548..d533a4ea 100644
--- a/src/ipa/rpi/controller/rpi/hdr.cpp
+++ b/src/ipa/rpi/controller/rpi/hdr.cpp
@@ -2,11 +2,13 @@
/*
* Copyright (C) 2023 Raspberry Pi Ltd
*
- * hdr.cpp - HDR control algorithm
+ * HDR control algorithm
*/
#include "hdr.h"
+#include <cmath>
+
#include <libcamera/base/log.h>
#include "../agc_status.h"
@@ -39,25 +41,52 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
channelMap[v.get<unsigned int>().value()] = k;
/* Lens shading related parameters. */
- if (params.contains("spatial_gain")) {
- spatialGain.read(params["spatial_gain"]);
- diffusion = params["diffusion"].get<unsigned int>(3);
- /* Clip to an arbitrary limit just to stop typos from killing the system! */
- const unsigned int MAX_DIFFUSION = 15;
- if (diffusion > MAX_DIFFUSION) {
- diffusion = MAX_DIFFUSION;
- LOG(RPiHdr, Warning) << "Diffusion value clipped to " << MAX_DIFFUSION;
- }
+ if (params.contains("spatial_gain_curve")) {
+ spatialGainCurve.readYaml(params["spatial_gain_curve"]);
+ } else if (params.contains("spatial_gain")) {
+ double spatialGain = params["spatial_gain"].get<double>(2.0);
+ spatialGainCurve.append(0.0, spatialGain);
+ spatialGainCurve.append(0.01, spatialGain);
+ spatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */
+ spatialGainCurve.append(1.0, 1.0);
+ }
+
+ diffusion = params["diffusion"].get<unsigned int>(3);
+ /* Clip to an arbitrary limit just to stop typos from killing the system! */
+ const unsigned int MAX_DIFFUSION = 15;
+ if (diffusion > MAX_DIFFUSION) {
+ diffusion = MAX_DIFFUSION;
+ LOG(RPiHdr, Warning) << "Diffusion value clipped to " << MAX_DIFFUSION;
}
/* Read any tonemap parameters. */
tonemapEnable = params["tonemap_enable"].get<int>(0);
- detailConstant = params["detail_constant"].get<uint16_t>(50);
- detailSlope = params["detail_slope"].get<double>(8.0);
+ detailConstant = params["detail_constant"].get<uint16_t>(0);
+ detailSlope = params["detail_slope"].get<double>(0.0);
iirStrength = params["iir_strength"].get<double>(8.0);
strength = params["strength"].get<double>(1.5);
if (tonemapEnable)
- tonemap.read(params["tonemap"]);
+ tonemap.readYaml(params["tonemap"]);
+ speed = params["speed"].get<double>(1.0);
+ if (params.contains("hi_quantile_targets")) {
+ hiQuantileTargets = params["hi_quantile_targets"].getList<double>().value();
+ if (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)
+ LOG(RPiHdr, Fatal) << "hi_quantile_targets much be even and non-empty";
+ } else
+ hiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };
+ hiQuantileMaxGain = params["hi_quantile_max_gain"].get<double>(1.6);
+ if (params.contains("quantile_targets")) {
+ quantileTargets = params["quantile_targets"].getList<double>().value();
+ if (quantileTargets.empty() || quantileTargets.size() % 2)
+ LOG(RPiHdr, Fatal) << "quantile_targets much be even and non-empty";
+ } else
+ quantileTargets = { 0.2, 0.03, 1.0, 0.15 };
+ powerMin = params["power_min"].get<double>(0.65);
+ powerMax = params["power_max"].get<double>(1.0);
+ if (params.contains("contrast_adjustments")) {
+ contrastAdjustments = params["contrast_adjustments"].getList<double>().value();
+ } else
+ contrastAdjustments = { 0.5, 0.75 };
/* Read any stitch parameters. */
stitchEnable = params["stitch_enable"].get<int>(0);
@@ -159,7 +188,7 @@ void Hdr::prepare(Metadata *imageMetadata)
}
HdrConfig &config = it->second;
- if (config.spatialGain.empty())
+ if (config.spatialGainCurve.empty())
return;
AlscStatus alscStatus{}; /* some compilers seem to require the braces */
@@ -183,7 +212,7 @@ bool Hdr::updateTonemap([[maybe_unused]] StatisticsPtr &stats, HdrConfig &config
/* When there's a change of HDR mode we start over with a new tonemap curve. */
if (delayedStatus_.mode != previousMode_) {
previousMode_ = delayedStatus_.mode;
- tonemap_ = Pwl();
+ tonemap_ = ipa::Pwl();
}
/* No tonemapping. No need to output a tonemap.status. */
@@ -205,10 +234,61 @@ bool Hdr::updateTonemap([[maybe_unused]] StatisticsPtr &stats, HdrConfig &config
return true;
/*
- * If we wanted to build or adjust tonemaps dynamically, this would be the place
- * to do it. But for now we seem to be getting by without.
+ * Create a tonemap dynamically. We have three ingredients.
+ *
+ * 1. We have a list of "hi quantiles" and "targets". We use these to judge if
+ * the image does seem to be reasonably saturated. If it isn't, we calculate
+ * a gain that we will feed as a linear factor into the tonemap generation.
+ * This prevents unsaturated images from beoming quite so "flat".
+ *
+ * 2. We have a list of quantile/target pairs for the bottom of the histogram.
+ * We use these to calculate how much gain we must apply to the bottom of the
+ * tonemap. We apply this gain as a power curve so as not to blow out the top
+ * end.
+ *
+ * 3. Finally, when we generate the tonemap, we have some contrast adjustments
+ * for the bottom because we know that power curves can start quite steeply and
+ * cause a washed-out look.
*/
+ /* Compute the linear gain from the headroom for saturation at the top. */
+ double gain = 10; /* arbitrary, but hiQuantileMaxGain will clamp it later */
+ for (unsigned int i = 0; i < config.hiQuantileTargets.size(); i += 2) {
+ double quantile = config.hiQuantileTargets[i];
+ double target = config.hiQuantileTargets[i + 1];
+ double value = stats->yHist.interQuantileMean(quantile, 1.0) / 1024.0;
+ double newGain = target / (value + 0.01);
+ gain = std::min(gain, newGain);
+ }
+ gain = std::clamp(gain, 1.0, config.hiQuantileMaxGain);
+
+ /* Compute the power curve from the amount of gain needed at the bottom. */
+ double min_power = 2; /* arbitrary, but config.powerMax will clamp it later */
+ for (unsigned int i = 0; i < config.quantileTargets.size(); i += 2) {
+ double quantile = config.quantileTargets[i];
+ double target = config.quantileTargets[i + 1];
+ double value = stats->yHist.interQuantileMean(0, quantile) / 1024.0;
+ value = std::min(value * gain, 1.0);
+ double power = log(target + 1e-6) / log(value + 1e-6);
+ min_power = std::min(min_power, power);
+ }
+ double power = std::clamp(min_power, config.powerMin, config.powerMax);
+
+ /* Generate the tonemap, including the contrast adjustment factors. */
+ libcamera::ipa::Pwl tonemap;
+ tonemap.append(0, 0);
+ for (unsigned int i = 0; i <= 6; i++) {
+ double x = 1 << (i + 9); /* x loops from 512 to 32768 inclusive */
+ double y = pow(std::min(x * gain, 65535.0) / 65536.0, power) * 65536;
+ if (i < config.contrastAdjustments.size())
+ y *= config.contrastAdjustments[i];
+ if (!tonemap_.empty())
+ y = y * config.speed + tonemap_.eval(x) * (1 - config.speed);
+ tonemap.append(x, y);
+ }
+ tonemap.append(65535, 65535);
+ tonemap_ = tonemap;
+
return true;
}
@@ -255,7 +335,7 @@ static void averageGains(std::vector<double> &src, std::vector<double> &dst, con
void Hdr::updateGains(StatisticsPtr &stats, HdrConfig &config)
{
- if (config.spatialGain.empty())
+ if (config.spatialGainCurve.empty())
return;
/* When alternating exposures, only compute these gains for the short frame. */
@@ -270,7 +350,7 @@ void Hdr::updateGains(StatisticsPtr &stats, HdrConfig &config)
double g = region.val.gSum / counted;
double b = region.val.bSum / counted;
double brightness = std::max({ r, g, b }) / 65535;
- gains_[0][i] = config.spatialGain.eval(brightness);
+ gains_[0][i] = config.spatialGainCurve.eval(brightness);
}
/* Ping-pong between the two gains_ buffers. */
diff --git a/src/ipa/rpi/controller/rpi/hdr.h b/src/ipa/rpi/controller/rpi/hdr.h
index 980aa3d1..5c2f3988 100644
--- a/src/ipa/rpi/controller/rpi/hdr.h
+++ b/src/ipa/rpi/controller/rpi/hdr.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2023, Raspberry Pi Ltd
*
- * hdr.h - HDR control algorithm
+ * HDR control algorithm
*/
#pragma once
@@ -12,9 +12,10 @@
#include <libcamera/geometry.h>
+#include <libipa/pwl.h>
+
#include "../hdr_algorithm.h"
#include "../hdr_status.h"
-#include "../pwl.h"
/* This is our implementation of an HDR algorithm. */
@@ -26,7 +27,7 @@ struct HdrConfig {
std::map<unsigned int, std::string> channelMap;
/* Lens shading related parameters. */
- Pwl spatialGain; /* Brightness to gain curve for different image regions. */
+ libcamera::ipa::Pwl spatialGainCurve; /* Brightness to gain curve for different image regions. */
unsigned int diffusion; /* How much to diffuse the gain spatially. */
/* Tonemap related parameters. */
@@ -35,7 +36,15 @@ struct HdrConfig {
double detailSlope;
double iirStrength;
double strength;
- Pwl tonemap;
+ libcamera::ipa::Pwl tonemap;
+ /* These relate to adaptive tonemap calculation. */
+ double speed;
+ std::vector<double> hiQuantileTargets; /* quantiles to check for unsaturated images */
+ double hiQuantileMaxGain; /* the max gain we'll apply when unsaturated */
+ std::vector<double> quantileTargets; /* target values for histogram quantiles */
+ double powerMin; /* minimum tonemap power */
+ double powerMax; /* maximum tonemap power */
+ std::vector<double> contrastAdjustments; /* any contrast adjustment factors */
/* Stitch related parameters. */
bool stitchEnable;
@@ -67,7 +76,7 @@ private:
HdrStatus status_; /* track the current HDR mode and channel */
HdrStatus delayedStatus_; /* track the delayed HDR mode and channel */
std::string previousMode_;
- Pwl tonemap_;
+ libcamera::ipa::Pwl tonemap_;
libcamera::Size regions_; /* stats regions */
unsigned int numRegions_; /* total number of stats regions */
std::vector<double> gains_[2];
diff --git a/src/ipa/rpi/controller/rpi/lux.cpp b/src/ipa/rpi/controller/rpi/lux.cpp
index 06625f3a..7b31faab 100644
--- a/src/ipa/rpi/controller/rpi/lux.cpp
+++ b/src/ipa/rpi/controller/rpi/lux.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * lux.cpp - Lux control algorithm
+ * Lux control algorithm
*/
#include <math.h>
diff --git a/src/ipa/rpi/controller/rpi/lux.h b/src/ipa/rpi/controller/rpi/lux.h
index 89411a54..89f441fc 100644
--- a/src/ipa/rpi/controller/rpi/lux.h
+++ b/src/ipa/rpi/controller/rpi/lux.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * lux.h - Lux control algorithm
+ * Lux control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/noise.cpp b/src/ipa/rpi/controller/rpi/noise.cpp
index bcd8b9ed..3f1c62cf 100644
--- a/src/ipa/rpi/controller/rpi/noise.cpp
+++ b/src/ipa/rpi/controller/rpi/noise.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * noise.cpp - Noise control algorithm
+ * Noise control algorithm
*/
#include <math.h>
diff --git a/src/ipa/rpi/controller/rpi/noise.h b/src/ipa/rpi/controller/rpi/noise.h
index 74c31e64..6deae1f0 100644
--- a/src/ipa/rpi/controller/rpi/noise.h
+++ b/src/ipa/rpi/controller/rpi/noise.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * noise.h - Noise control algorithm
+ * Noise control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/saturation.cpp b/src/ipa/rpi/controller/rpi/saturation.cpp
index 813540e5..b83c5887 100644
--- a/src/ipa/rpi/controller/rpi/saturation.cpp
+++ b/src/ipa/rpi/controller/rpi/saturation.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2022 Raspberry Pi Ltd
*
- * saturation.cpp - Saturation control algorithm
+ * Saturation control algorithm
*/
#include "saturation.h"
diff --git a/src/ipa/rpi/controller/rpi/sdn.cpp b/src/ipa/rpi/controller/rpi/sdn.cpp
index 2f777dd7..619178a8 100644
--- a/src/ipa/rpi/controller/rpi/sdn.cpp
+++ b/src/ipa/rpi/controller/rpi/sdn.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019-2021, Raspberry Pi Ltd
*
- * sdn.cpp - SDN (spatial denoise) control algorithm
+ * SDN (spatial denoise) control algorithm
*/
#include <libcamera/base/log.h>
diff --git a/src/ipa/rpi/controller/rpi/sdn.h b/src/ipa/rpi/controller/rpi/sdn.h
index 9dd73c38..cb226de8 100644
--- a/src/ipa/rpi/controller/rpi/sdn.h
+++ b/src/ipa/rpi/controller/rpi/sdn.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * sdn.h - SDN (spatial denoise) control algorithm
+ * SDN (spatial denoise) control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/sharpen.cpp b/src/ipa/rpi/controller/rpi/sharpen.cpp
index 4f6f020a..39537f4a 100644
--- a/src/ipa/rpi/controller/rpi/sharpen.cpp
+++ b/src/ipa/rpi/controller/rpi/sharpen.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * sharpen.cpp - sharpening control algorithm
+ * sharpening control algorithm
*/
#include <math.h>
diff --git a/src/ipa/rpi/controller/rpi/sharpen.h b/src/ipa/rpi/controller/rpi/sharpen.h
index 8bb7631e..96ccd609 100644
--- a/src/ipa/rpi/controller/rpi/sharpen.h
+++ b/src/ipa/rpi/controller/rpi/sharpen.h
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2019, Raspberry Pi Ltd
*
- * sharpen.h - sharpening control algorithm
+ * sharpening control algorithm
*/
#pragma once
diff --git a/src/ipa/rpi/controller/rpi/tonemap.cpp b/src/ipa/rpi/controller/rpi/tonemap.cpp
index 5f8b2bf2..2dc50dfc 100644
--- a/src/ipa/rpi/controller/rpi/tonemap.cpp
+++ b/src/ipa/rpi/controller/rpi/tonemap.cpp
@@ -2,7 +2,7 @@
/*
* Copyright (C) 2022 Raspberry Pi Ltd
*
- * tonemap.cpp - Tonemap control algorithm
+ * Tonemap control algorithm
*/
#include "tonemap.h"
@@ -33,7 +33,7 @@ int Tonemap::read(const libcamera::YamlObject &params)
config_.detailSlope = params["detail_slope"].get<double>(0.1);
config_.iirStrength = params["iir_strength"].get<double>(1.0);
config_.strength = params["strength"].get<double>(1.0);
- config_.tonemap.read(params["tone_curve"]);
+ config_.tonemap.readYaml(params["tone_curve"]);
return 0;
}
diff --git a/src/ipa/rpi/controller/rpi/tonemap.h b/src/ipa/rpi/controller/rpi/tonemap.h
index f25aa47f..ba0cf5c4 100644
--- a/src/ipa/rpi/controller/rpi/tonemap.h
+++ b/src/ipa/rpi/controller/rpi/tonemap.h
@@ -6,8 +6,9 @@
*/
#pragma once
+#include <libipa/pwl.h>
+
#include "algorithm.h"
-#include "pwl.h"
namespace RPiController {
@@ -16,7 +17,7 @@ struct TonemapConfig {
double detailSlope;
double iirStrength;
double strength;
- Pwl tonemap;
+ libcamera::ipa::Pwl tonemap;
};
class Tonemap : public Algorithm