ipa: raspberrypi: Use YamlParser to replace dependency on boost
The Raspberry Pi IPA module depends on boost only to parse the JSON tuning data files. As libcamera depends on libyaml, use the YamlParser class to parse those files and drop the dependency on boost. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
This commit is contained in:
parent
735f0ffeaa
commit
c1597f9896
32 changed files with 375 additions and 278 deletions
|
@ -71,12 +71,6 @@ for improved debugging: [optional]
|
|||
information, and libunwind is not needed if both libdw and the glibc
|
||||
backtrace() function are available.
|
||||
|
||||
for the Raspberry Pi IPA: [optional]
|
||||
libboost-dev
|
||||
|
||||
Support for Raspberry Pi can be disabled through the meson
|
||||
'pipelines' option to avoid this dependency.
|
||||
|
||||
for device hotplug enumeration: [optional]
|
||||
libudev-dev
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
using namespace RPiController;
|
||||
|
||||
int Algorithm::read([[maybe_unused]] boost::property_tree::ptree const ¶ms)
|
||||
int Algorithm::read([[maybe_unused]] const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
#include "controller.h"
|
||||
#include "libcamera/internal/yaml_parser.h"
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include "controller.h"
|
||||
|
||||
namespace RPiController {
|
||||
|
||||
|
@ -35,7 +35,7 @@ public:
|
|||
virtual bool isPaused() const { return paused_; }
|
||||
virtual void pause() { paused_ = true; }
|
||||
virtual void resume() { paused_ = false; }
|
||||
virtual int read(boost::property_tree::ptree const ¶ms);
|
||||
virtual int read(const libcamera::YamlObject ¶ms);
|
||||
virtual void initialise();
|
||||
virtual void switchMode(CameraMode const &cameraMode, Metadata *metadata);
|
||||
virtual void prepare(Metadata *imageMetadata);
|
||||
|
|
|
@ -5,14 +5,16 @@
|
|||
* controller.cpp - ISP controller
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <libcamera/base/file.h>
|
||||
#include <libcamera/base/log.h>
|
||||
|
||||
#include "libcamera/internal/yaml_parser.h"
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "controller.h"
|
||||
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
using namespace RPiController;
|
||||
using namespace libcamera;
|
||||
|
||||
|
@ -34,18 +36,25 @@ Controller::~Controller() {}
|
|||
|
||||
int Controller::read(char const *filename)
|
||||
{
|
||||
boost::property_tree::ptree root;
|
||||
boost::property_tree::read_json(filename, root);
|
||||
for (auto const &keyAndValue : root) {
|
||||
Algorithm *algo = createAlgorithm(keyAndValue.first.c_str());
|
||||
File file(filename);
|
||||
if (!file.open(File::OpenModeFlag::ReadOnly)) {
|
||||
LOG(RPiController, Warning)
|
||||
<< "Failed to open tuning file '" << filename << "'";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
std::unique_ptr<YamlObject> root = YamlParser::parse(file);
|
||||
|
||||
for (auto const &[key, value] : root->asDict()) {
|
||||
Algorithm *algo = createAlgorithm(key.c_str());
|
||||
if (algo) {
|
||||
int ret = algo->read(keyAndValue.second);
|
||||
int ret = algo->read(value);
|
||||
if (ret)
|
||||
return ret;
|
||||
algorithms_.push_back(AlgorithmPtr(algo));
|
||||
} else
|
||||
LOG(RPiController, Warning)
|
||||
<< "No algorithm found for \"" << keyAndValue.first << "\"";
|
||||
<< "No algorithm found for \"" << key << "\"";
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -12,16 +12,27 @@
|
|||
|
||||
using namespace RPiController;
|
||||
|
||||
int Pwl::read(boost::property_tree::ptree const ¶ms)
|
||||
int Pwl::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
for (auto it = params.begin(); it != params.end(); it++) {
|
||||
double x = it->second.get_value<double>();
|
||||
assert(it == params.begin() || x > points_.back().x);
|
||||
it++;
|
||||
double y = it->second.get_value<double>();
|
||||
points_.push_back(Point(x, y));
|
||||
if (!params.size() || params.size() % 2)
|
||||
return -EINVAL;
|
||||
|
||||
const auto &list = params.asList();
|
||||
|
||||
for (auto it = list.begin(); it != list.end(); it++) {
|
||||
auto x = it->get<double>();
|
||||
if (!x)
|
||||
return -EINVAL;
|
||||
if (it != list.begin() && *x <= points_.back().x)
|
||||
return -EINVAL;
|
||||
|
||||
auto y = (++it)->get<double>();
|
||||
if (!y)
|
||||
return -EINVAL;
|
||||
|
||||
points_.push_back(Point(*x, *y));
|
||||
}
|
||||
assert(points_.size() >= 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <math.h>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include "libcamera/internal/yaml_parser.h"
|
||||
|
||||
namespace RPiController {
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
};
|
||||
Pwl() {}
|
||||
Pwl(std::vector<Point> const &points) : points_(points) {}
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
void append(double x, double y, const double eps = 1e-6);
|
||||
void prepend(double x, double y, const double eps = 1e-6);
|
||||
Interval domain() const;
|
||||
|
|
|
@ -31,67 +31,76 @@ LOG_DEFINE_CATEGORY(RPiAgc)
|
|||
|
||||
static constexpr unsigned int PipelineBits = 13; /* seems to be a 13-bit pipeline */
|
||||
|
||||
int AgcMeteringMode::read(boost::property_tree::ptree const ¶ms)
|
||||
int AgcMeteringMode::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
for (auto &p : params.get_child("weights")) {
|
||||
if (num == AgcStatsSize) {
|
||||
LOG(RPiAgc, Error) << "AgcMeteringMode: too many weights";
|
||||
return -EINVAL;
|
||||
}
|
||||
weights[num++] = p.second.get_value<double>();
|
||||
const YamlObject &yamlWeights = params["weights"];
|
||||
if (yamlWeights.size() != AgcStatsSize) {
|
||||
LOG(RPiAgc, Error) << "AgcMeteringMode: Incorrect number of weights";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (num != AgcStatsSize) {
|
||||
LOG(RPiAgc, Error) << "AgcMeteringMode: insufficient weights";
|
||||
return -EINVAL;
|
||||
unsigned int num = 0;
|
||||
for (const auto &p : yamlWeights.asList()) {
|
||||
auto value = p.get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
weights[num++] = *value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::tuple<int, std::string>
|
||||
readMeteringModes(std::map<std::string, AgcMeteringMode> &meteringModes,
|
||||
boost::property_tree::ptree const ¶ms)
|
||||
readMeteringModes(std::map<std::string, AgcMeteringMode> &metering_modes,
|
||||
const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
std::string first;
|
||||
int ret;
|
||||
|
||||
for (auto &p : params) {
|
||||
for (const auto &[key, value] : params.asDict()) {
|
||||
AgcMeteringMode meteringMode;
|
||||
ret = meteringMode.read(p.second);
|
||||
ret = meteringMode.read(value);
|
||||
if (ret)
|
||||
return { ret, {} };
|
||||
|
||||
meteringModes[p.first] = std::move(meteringMode);
|
||||
metering_modes[key] = std::move(meteringMode);
|
||||
if (first.empty())
|
||||
first = p.first;
|
||||
first = key;
|
||||
}
|
||||
|
||||
return { 0, first };
|
||||
}
|
||||
|
||||
static int readList(std::vector<double> &list,
|
||||
boost::property_tree::ptree const ¶ms)
|
||||
const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
for (auto &p : params)
|
||||
list.push_back(p.second.get_value<double>());
|
||||
for (const auto &p : params.asList()) {
|
||||
auto value = p.get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
list.push_back(*value);
|
||||
}
|
||||
|
||||
return list.size();
|
||||
}
|
||||
|
||||
static int readList(std::vector<Duration> &list,
|
||||
boost::property_tree::ptree const ¶ms)
|
||||
const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
for (auto &p : params)
|
||||
list.push_back(p.second.get_value<double>() * 1us);
|
||||
for (const auto &p : params.asList()) {
|
||||
auto value = p.get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
list.push_back(*value * 1us);
|
||||
}
|
||||
|
||||
return list.size();
|
||||
}
|
||||
|
||||
int AgcExposureMode::read(boost::property_tree::ptree const ¶ms)
|
||||
int AgcExposureMode::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
int numShutters = readList(shutter, params.get_child("shutter"));
|
||||
int numAgs = readList(gain, params.get_child("gain"));
|
||||
int numShutters = readList(shutter, params["shutter"]);
|
||||
int numAgs = readList(gain, params["gain"]);
|
||||
|
||||
if (numShutters < 2 || numAgs < 2) {
|
||||
LOG(RPiAgc, Error)
|
||||
|
@ -110,28 +119,28 @@ int AgcExposureMode::read(boost::property_tree::ptree const ¶ms)
|
|||
|
||||
static std::tuple<int, std::string>
|
||||
readExposureModes(std::map<std::string, AgcExposureMode> &exposureModes,
|
||||
boost::property_tree::ptree const ¶ms)
|
||||
const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
std::string first;
|
||||
int ret;
|
||||
|
||||
for (auto &p : params) {
|
||||
for (const auto &[key, value] : params.asDict()) {
|
||||
AgcExposureMode exposureMode;
|
||||
ret = exposureMode.read(p.second);
|
||||
ret = exposureMode.read(value);
|
||||
if (ret)
|
||||
return { ret, {} };
|
||||
|
||||
exposureModes[p.first] = std::move(exposureMode);
|
||||
exposureModes[key] = std::move(exposureMode);
|
||||
if (first.empty())
|
||||
first = p.first;
|
||||
first = key;
|
||||
}
|
||||
|
||||
return { 0, first };
|
||||
}
|
||||
|
||||
int AgcConstraint::read(boost::property_tree::ptree const ¶ms)
|
||||
int AgcConstraint::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
std::string boundString = params.get<std::string>("bound", "");
|
||||
std::string boundString = params["bound"].get<std::string>("");
|
||||
transform(boundString.begin(), boundString.end(),
|
||||
boundString.begin(), ::toupper);
|
||||
if (boundString != "UPPER" && boundString != "LOWER") {
|
||||
|
@ -139,20 +148,29 @@ int AgcConstraint::read(boost::property_tree::ptree const ¶ms)
|
|||
return -EINVAL;
|
||||
}
|
||||
bound = boundString == "UPPER" ? Bound::UPPER : Bound::LOWER;
|
||||
qLo = params.get<double>("q_lo");
|
||||
qHi = params.get<double>("q_hi");
|
||||
return yTarget.read(params.get_child("y_target"));
|
||||
|
||||
auto value = params["q_lo"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
qLo = *value;
|
||||
|
||||
value = params["q_hi"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
qHi = *value;
|
||||
|
||||
return yTarget.read(params["y_target"]);
|
||||
}
|
||||
|
||||
static std::tuple<int, AgcConstraintMode>
|
||||
readConstraintMode(boost::property_tree::ptree const ¶ms)
|
||||
readConstraintMode(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
AgcConstraintMode mode;
|
||||
int ret;
|
||||
|
||||
for (auto &p : params) {
|
||||
for (const auto &p : params.asList()) {
|
||||
AgcConstraint constraint;
|
||||
ret = constraint.read(p.second);
|
||||
ret = constraint.read(p);
|
||||
if (ret)
|
||||
return { ret, {} };
|
||||
|
||||
|
@ -164,53 +182,55 @@ readConstraintMode(boost::property_tree::ptree const ¶ms)
|
|||
|
||||
static std::tuple<int, std::string>
|
||||
readConstraintModes(std::map<std::string, AgcConstraintMode> &constraintModes,
|
||||
boost::property_tree::ptree const ¶ms)
|
||||
const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
std::string first;
|
||||
int ret;
|
||||
|
||||
for (auto &p : params) {
|
||||
std::tie(ret, constraintModes[p.first]) = readConstraintMode(p.second);
|
||||
for (const auto &[key, value] : params.asDict()) {
|
||||
std::tie(ret, constraintModes[key]) = readConstraintMode(value);
|
||||
if (ret)
|
||||
return { ret, {} };
|
||||
|
||||
if (first.empty())
|
||||
first = p.first;
|
||||
first = key;
|
||||
}
|
||||
|
||||
return { 0, first };
|
||||
}
|
||||
|
||||
int AgcConfig::read(boost::property_tree::ptree const ¶ms)
|
||||
int AgcConfig::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
LOG(RPiAgc, Debug) << "AgcConfig";
|
||||
int ret;
|
||||
|
||||
std::tie(ret, defaultMeteringMode) =
|
||||
readMeteringModes(meteringModes, params.get_child("metering_modes"));
|
||||
readMeteringModes(meteringModes, params["metering_modes"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
std::tie(ret, defaultExposureMode) =
|
||||
readExposureModes(exposureModes, params.get_child("exposure_modes"));
|
||||
readExposureModes(exposureModes, params["exposure_modes"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
std::tie(ret, defaultConstraintMode) =
|
||||
readConstraintModes(constraintModes, params.get_child("constraint_modes"));
|
||||
readConstraintModes(constraintModes, params["constraint_modes"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = yTarget.read(params.get_child("y_target"));
|
||||
ret = yTarget.read(params["y_target"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
speed = params.get<double>("speed", 0.2);
|
||||
startupFrames = params.get<uint16_t>("startup_frames", 10);
|
||||
convergenceFrames = params.get<unsigned int>("convergence_frames", 6);
|
||||
fastReduceThreshold = params.get<double>("fast_reduce_threshold", 0.4);
|
||||
baseEv = params.get<double>("base_ev", 1.0);
|
||||
speed = params["speed"].get<double>(0.2);
|
||||
startupFrames = params["startup_frames"].get<uint16_t>(10);
|
||||
convergenceFrames = params["convergence_frames"].get<unsigned int>(6);
|
||||
fastReduceThreshold = params["fast_reduce_threshold"].get<double>(0.4);
|
||||
baseEv = params["base_ev"].get<double>(1.0);
|
||||
|
||||
/* Start with quite a low value as ramping up is easier than ramping down. */
|
||||
defaultExposureTime = params.get<double>("default_exposure_time", 1000) * 1us;
|
||||
defaultAnalogueGain = params.get<double>("default_analogueGain", 1.0);
|
||||
defaultExposureTime = params["default_exposure_time"].get<double>(1000) * 1us;
|
||||
defaultAnalogueGain = params["default_analogue_gain"].get<double>(1.0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -242,7 +262,7 @@ char const *Agc::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Agc::read(boost::property_tree::ptree const ¶ms)
|
||||
int Agc::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
LOG(RPiAgc, Debug) << "Agc";
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@ namespace RPiController {
|
|||
|
||||
struct AgcMeteringMode {
|
||||
double weights[AgcStatsSize];
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
};
|
||||
|
||||
struct AgcExposureMode {
|
||||
std::vector<libcamera::utils::Duration> shutter;
|
||||
std::vector<double> gain;
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
};
|
||||
|
||||
struct AgcConstraint {
|
||||
|
@ -43,13 +43,13 @@ struct AgcConstraint {
|
|||
double qLo;
|
||||
double qHi;
|
||||
Pwl yTarget;
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
};
|
||||
|
||||
typedef std::vector<AgcConstraint> AgcConstraintMode;
|
||||
|
||||
struct AgcConfig {
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
std::map<std::string, AgcMeteringMode> meteringModes;
|
||||
std::map<std::string, AgcExposureMode> exposureModes;
|
||||
std::map<std::string, AgcConstraintMode> constraintModes;
|
||||
|
@ -74,7 +74,7 @@ class Agc : public AgcAlgorithm
|
|||
public:
|
||||
Agc(Controller *controller);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
/* AGC handles "pausing" for itself. */
|
||||
bool isPaused() const override;
|
||||
void pause() override;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* alsc.cpp - ALSC (auto lens shading correction) control algorithm
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
#include <math.h>
|
||||
#include <numeric>
|
||||
|
||||
|
@ -50,15 +51,15 @@ char const *Alsc::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
static int generateLut(double *lut, boost::property_tree::ptree const ¶ms)
|
||||
static int generateLut(double *lut, const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
double cstrength = params.get<double>("corner_strength", 2.0);
|
||||
double cstrength = params["corner_strength"].get<double>(2.0);
|
||||
if (cstrength <= 1.0) {
|
||||
LOG(RPiAlsc, Error) << "corner_strength must be > 1.0";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
double asymmetry = params.get<double>("asymmetry", 1.0);
|
||||
double asymmetry = params["asymmetry"].get<double>(1.0);
|
||||
if (asymmetry < 0) {
|
||||
LOG(RPiAlsc, Error) << "asymmetry must be >= 0";
|
||||
return -EINVAL;
|
||||
|
@ -80,34 +81,35 @@ static int generateLut(double *lut, boost::property_tree::ptree const ¶ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int readLut(double *lut, boost::property_tree::ptree const ¶ms)
|
||||
static int readLut(double *lut, const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
int num = 0;
|
||||
const int maxNum = XY;
|
||||
|
||||
for (auto &p : params) {
|
||||
if (num == maxNum) {
|
||||
LOG(RPiAlsc, Error) << "Too many entries in LSC table";
|
||||
return -EINVAL;
|
||||
}
|
||||
lut[num++] = p.second.get_value<double>();
|
||||
}
|
||||
|
||||
if (num < maxNum) {
|
||||
LOG(RPiAlsc, Error) << "Too few entries in LSC table";
|
||||
if (params.size() != XY) {
|
||||
LOG(RPiAlsc, Error) << "Invalid number of entries in LSC table";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int num = 0;
|
||||
for (const auto &p : params.asList()) {
|
||||
auto value = p.get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
lut[num++] = *value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int readCalibrations(std::vector<AlscCalibration> &calibrations,
|
||||
boost::property_tree::ptree const ¶ms,
|
||||
const libcamera::YamlObject ¶ms,
|
||||
std::string const &name)
|
||||
{
|
||||
if (params.get_child_optional(name)) {
|
||||
if (params.contains(name)) {
|
||||
double lastCt = 0;
|
||||
for (auto &p : params.get_child(name)) {
|
||||
double ct = p.second.get<double>("ct");
|
||||
for (const auto &p : params[name].asList()) {
|
||||
auto value = p["ct"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
double ct = *value;
|
||||
if (ct <= lastCt) {
|
||||
LOG(RPiAlsc, Error)
|
||||
<< "Entries in " << name << " must be in increasing ct order";
|
||||
|
@ -115,23 +117,23 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,
|
|||
}
|
||||
AlscCalibration calibration;
|
||||
calibration.ct = lastCt = ct;
|
||||
boost::property_tree::ptree const &table =
|
||||
p.second.get_child("table");
|
||||
int num = 0;
|
||||
for (auto it = table.begin(); it != table.end(); it++) {
|
||||
if (num == XY) {
|
||||
LOG(RPiAlsc, Error)
|
||||
<< "Too many values for ct " << ct << " in " << name;
|
||||
return -EINVAL;
|
||||
}
|
||||
calibration.table[num++] =
|
||||
it->second.get_value<double>();
|
||||
}
|
||||
if (num != XY) {
|
||||
|
||||
const libcamera::YamlObject &table = p["table"];
|
||||
if (table.size() != XY) {
|
||||
LOG(RPiAlsc, Error)
|
||||
<< "Too few values for ct " << ct << " in " << name;
|
||||
<< "Incorrect number of values for ct "
|
||||
<< ct << " in " << name;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int num = 0;
|
||||
for (const auto &elem : table.asList()) {
|
||||
value = elem.get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
calibration.table[num++] = *value;
|
||||
}
|
||||
|
||||
calibrations.push_back(calibration);
|
||||
LOG(RPiAlsc, Debug)
|
||||
<< "Read " << name << " calibration for ct " << ct;
|
||||
|
@ -140,30 +142,29 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Alsc::read(boost::property_tree::ptree const ¶ms)
|
||||
int Alsc::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
config_.framePeriod = params.get<uint16_t>("frame_period", 12);
|
||||
config_.startupFrames = params.get<uint16_t>("startup_frames", 10);
|
||||
config_.speed = params.get<double>("speed", 0.05);
|
||||
double sigma = params.get<double>("sigma", 0.01);
|
||||
config_.sigmaCr = params.get<double>("sigma_Cr", sigma);
|
||||
config_.sigmaCb = params.get<double>("sigma_Cb", sigma);
|
||||
config_.minCount = params.get<double>("min_count", 10.0);
|
||||
config_.minG = params.get<uint16_t>("min_G", 50);
|
||||
config_.omega = params.get<double>("omega", 1.3);
|
||||
config_.nIter = params.get<uint32_t>("n_iter", X + Y);
|
||||
config_.framePeriod = params["frame_period"].get<uint16_t>(12);
|
||||
config_.startupFrames = params["startup_frames"].get<uint16_t>(10);
|
||||
config_.speed = params["speed"].get<double>(0.05);
|
||||
double sigma = params["sigma"].get<double>(0.01);
|
||||
config_.sigmaCr = params["sigma_Cr"].get<double>(sigma);
|
||||
config_.sigmaCb = params["sigma_Cb"].get<double>(sigma);
|
||||
config_.minCount = params["min_count"].get<double>(10.0);
|
||||
config_.minG = params["min_G"].get<uint16_t>(50);
|
||||
config_.omega = params["omega"].get<double>(1.3);
|
||||
config_.nIter = params["n_iter"].get<uint32_t>(X + Y);
|
||||
config_.luminanceStrength =
|
||||
params.get<double>("luminance_strength", 1.0);
|
||||
params["luminance_strength"].get<double>(1.0);
|
||||
for (int i = 0; i < XY; i++)
|
||||
config_.luminanceLut[i] = 1.0;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (params.get_child_optional("corner_strength"))
|
||||
if (params.contains("corner_strength"))
|
||||
ret = generateLut(config_.luminanceLut, params);
|
||||
else if (params.get_child_optional("luminance_lut"))
|
||||
ret = readLut(config_.luminanceLut,
|
||||
params.get_child("luminance_lut"));
|
||||
else if (params.contains("luminance_lut"))
|
||||
ret = readLut(config_.luminanceLut, params["luminance_lut"]);
|
||||
else
|
||||
LOG(RPiAlsc, Warning)
|
||||
<< "no luminance table - assume unity everywhere";
|
||||
|
@ -177,9 +178,9 @@ int Alsc::read(boost::property_tree::ptree const ¶ms)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
config_.defaultCt = params.get<double>("default_ct", 4500.0);
|
||||
config_.threshold = params.get<double>("threshold", 1e-3);
|
||||
config_.lambdaBound = params.get<double>("lambda_bound", 0.05);
|
||||
config_.defaultCt = params["default_ct"].get<double>(4500.0);
|
||||
config_.threshold = params["threshold"].get<double>(1e-3);
|
||||
config_.lambdaBound = params["lambda_bound"].get<double>(0.05);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
char const *name() const override;
|
||||
void initialise() override;
|
||||
void switchMode(CameraMode const &cameraMode, Metadata *metadata) override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
void process(StatisticsPtr &stats, Metadata *imageMetadata) override;
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* awb.cpp - AWB control algorithm
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <libcamera/base/log.h>
|
||||
|
||||
#include "../lux_status.h"
|
||||
|
@ -26,62 +28,87 @@ static constexpr unsigned int AwbStatsSizeY = DEFAULT_AWB_REGIONS_Y;
|
|||
* elsewhere (ALSC and AGC).
|
||||
*/
|
||||
|
||||
int AwbMode::read(boost::property_tree::ptree const ¶ms)
|
||||
int AwbMode::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
ctLo = params.get<double>("lo");
|
||||
ctHi = params.get<double>("hi");
|
||||
auto value = params["lo"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
ctLo = *value;
|
||||
|
||||
value = params["hi"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
ctHi = *value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AwbPrior::read(boost::property_tree::ptree const ¶ms)
|
||||
int AwbPrior::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
lux = params.get<double>("lux");
|
||||
return prior.read(params.get_child("prior"));
|
||||
auto value = params["lux"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
lux = *value;
|
||||
|
||||
return prior.read(params["prior"]);
|
||||
}
|
||||
|
||||
static int readCtCurve(Pwl &ctR, Pwl &ctB,
|
||||
boost::property_tree::ptree const ¶ms)
|
||||
static int readCtCurve(Pwl &ctR, Pwl &ctB, const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
int num = 0;
|
||||
for (auto it = params.begin(); it != params.end(); it++) {
|
||||
double ct = it->second.get_value<double>();
|
||||
assert(it == params.begin() || ct != ctR.domain().end);
|
||||
if (++it == params.end()) {
|
||||
LOG(RPiAwb, Error) << "AwbConfig: incomplete CT curve entry";
|
||||
return -EINVAL;
|
||||
}
|
||||
ctR.append(ct, it->second.get_value<double>());
|
||||
if (++it == params.end()) {
|
||||
LOG(RPiAwb, Error) << "AwbConfig: incomplete CT curve entry";
|
||||
return -EINVAL;
|
||||
}
|
||||
ctB.append(ct, it->second.get_value<double>());
|
||||
num++;
|
||||
if (params.size() % 3) {
|
||||
LOG(RPiAwb, Error) << "AwbConfig: incomplete CT curve entry";
|
||||
return -EINVAL;
|
||||
}
|
||||
if (num < 2) {
|
||||
|
||||
if (params.size() < 6) {
|
||||
LOG(RPiAwb, Error) << "AwbConfig: insufficient points in CT curve";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
const auto &list = params.asList();
|
||||
|
||||
for (auto it = list.begin(); it != list.end(); it++) {
|
||||
auto value = it->get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
double ct = *value;
|
||||
|
||||
assert(it == list.begin() || ct != ctR.domain().end);
|
||||
|
||||
value = (++it)->get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
ctR.append(ct, *value);
|
||||
|
||||
value = (++it)->get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
ctB.append(ct, *value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AwbConfig::read(boost::property_tree::ptree const ¶ms)
|
||||
int AwbConfig::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
int ret;
|
||||
bayes = params.get<int>("bayes", 1);
|
||||
framePeriod = params.get<uint16_t>("framePeriod", 10);
|
||||
startupFrames = params.get<uint16_t>("startupFrames", 10);
|
||||
convergenceFrames = params.get<unsigned int>("convergence_frames", 3);
|
||||
speed = params.get<double>("speed", 0.05);
|
||||
if (params.get_child_optional("ct_curve")) {
|
||||
ret = readCtCurve(ctR, ctB, params.get_child("ct_curve"));
|
||||
|
||||
bayes = params["bayes"].get<int>(1);
|
||||
framePeriod = params["frame_period"].get<uint16_t>(10);
|
||||
startupFrames = params["startup_frames"].get<uint16_t>(10);
|
||||
convergenceFrames = params["convergence_frames"].get<unsigned int>(3);
|
||||
speed = params["speed"].get<double>(0.05);
|
||||
|
||||
if (params.contains("ct_curve")) {
|
||||
ret = readCtCurve(ctR, ctB, params["ct_curve"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (params.get_child_optional("priors")) {
|
||||
for (auto &p : params.get_child("priors")) {
|
||||
|
||||
if (params.contains("priors")) {
|
||||
for (const auto &p : params["priors"].asList()) {
|
||||
AwbPrior prior;
|
||||
ret = prior.read(p.second);
|
||||
ret = prior.read(p);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!priors.empty() && prior.lux <= priors.back().lux) {
|
||||
|
@ -95,32 +122,35 @@ int AwbConfig::read(boost::property_tree::ptree const ¶ms)
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
if (params.get_child_optional("modes")) {
|
||||
for (auto &p : params.get_child("modes")) {
|
||||
ret = modes[p.first].read(p.second);
|
||||
if (params.contains("modes")) {
|
||||
for (const auto &[key, value] : params["modes"].asDict()) {
|
||||
ret = modes[key].read(value);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (defaultMode == nullptr)
|
||||
defaultMode = &modes[p.first];
|
||||
defaultMode = &modes[key];
|
||||
}
|
||||
if (defaultMode == nullptr) {
|
||||
LOG(RPiAwb, Error) << "AwbConfig: no AWB modes configured";
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
minPixels = params.get<double>("min_pixels", 16.0);
|
||||
minG = params.get<uint16_t>("min_G", 32);
|
||||
minRegions = params.get<uint32_t>("min_regions", 10);
|
||||
deltaLimit = params.get<double>("delta_limit", 0.2);
|
||||
coarseStep = params.get<double>("coarse_step", 0.2);
|
||||
transversePos = params.get<double>("transverse_pos", 0.01);
|
||||
transverseNeg = params.get<double>("transverse_neg", 0.01);
|
||||
|
||||
minPixels = params["min_pixels"].get<double>(16.0);
|
||||
minG = params["min_G"].get<uint16_t>(32);
|
||||
minRegions = params["min_regions"].get<uint32_t>(10);
|
||||
deltaLimit = params["delta_limit"].get<double>(0.2);
|
||||
coarseStep = params["coarse_step"].get<double>(0.2);
|
||||
transversePos = params["transverse_pos"].get<double>(0.01);
|
||||
transverseNeg = params["transverse_neg"].get<double>(0.01);
|
||||
if (transversePos <= 0 || transverseNeg <= 0) {
|
||||
LOG(RPiAwb, Error) << "AwbConfig: transverse_pos/neg must be > 0";
|
||||
return -EINVAL;
|
||||
}
|
||||
sensitivityR = params.get<double>("sensitivity_r", 1.0);
|
||||
sensitivityB = params.get<double>("sensitivity_b", 1.0);
|
||||
|
||||
sensitivityR = params["sensitivity_r"].get<double>(1.0);
|
||||
sensitivityB = params["sensitivity_b"].get<double>(1.0);
|
||||
|
||||
if (bayes) {
|
||||
if (ctR.empty() || ctB.empty() || priors.empty() ||
|
||||
defaultMode == nullptr) {
|
||||
|
@ -129,9 +159,9 @@ int AwbConfig::read(boost::property_tree::ptree const ¶ms)
|
|||
bayes = false;
|
||||
}
|
||||
}
|
||||
fast = params.get<int>("fast", bayes); /* default to fast for Bayesian, otherwise slow */
|
||||
whitepointR = params.get<double>("whitepoint_r", 0.0);
|
||||
whitepointB = params.get<double>("whitepoint_b", 0.0);
|
||||
fast = params[fast].get<int>(bayes); /* default to fast for Bayesian, otherwise slow */
|
||||
whitepointR = params["whitepoint_r"].get<double>(0.0);
|
||||
whitepointB = params["whitepoint_b"].get<double>(0.0);
|
||||
if (bayes == false)
|
||||
sensitivityR = sensitivityB = 1.0; /* nor do sensitivities make any sense */
|
||||
return 0;
|
||||
|
@ -162,7 +192,7 @@ char const *Awb::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Awb::read(boost::property_tree::ptree const ¶ms)
|
||||
int Awb::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
return config_.read(params);
|
||||
}
|
||||
|
|
|
@ -19,20 +19,20 @@ namespace RPiController {
|
|||
/* Control algorithm to perform AWB calculations. */
|
||||
|
||||
struct AwbMode {
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
double ctLo; /* low CT value for search */
|
||||
double ctHi; /* high CT value for search */
|
||||
};
|
||||
|
||||
struct AwbPrior {
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
double lux; /* lux level */
|
||||
Pwl prior; /* maps CT to prior log likelihood for this lux level */
|
||||
};
|
||||
|
||||
struct AwbConfig {
|
||||
AwbConfig() : defaultMode(nullptr) {}
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
/* Only repeat the AWB calculation every "this many" frames */
|
||||
uint16_t framePeriod;
|
||||
/* number of initial frames for which speed taken as 1.0 (maximum) */
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
~Awb();
|
||||
char const *name() const override;
|
||||
void initialise() override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
/* AWB handles "pausing" for itself. */
|
||||
bool isPaused() const override;
|
||||
void pause() override;
|
||||
|
|
|
@ -31,13 +31,13 @@ char const *BlackLevel::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int BlackLevel::read(boost::property_tree::ptree const ¶ms)
|
||||
int BlackLevel::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
uint16_t blackLevel = params.get<uint16_t>(
|
||||
"black_level", 4096); /* 64 in 10 bits scaled to 16 bits */
|
||||
blackLevelR_ = params.get<uint16_t>("black_level_r", blackLevel);
|
||||
blackLevelG_ = params.get<uint16_t>("black_level_g", blackLevel);
|
||||
blackLevelB_ = params.get<uint16_t>("black_level_b", blackLevel);
|
||||
/* 64 in 10 bits scaled to 16 bits */
|
||||
uint16_t blackLevel = params["black_level"].get<uint16_t>(4096);
|
||||
blackLevelR_ = params["black_level_r"].get<uint16_t>(blackLevel);
|
||||
blackLevelG_ = params["black_level_g"].get<uint16_t>(blackLevel);
|
||||
blackLevelB_ = params["black_level_b"].get<uint16_t>(blackLevel);
|
||||
LOG(RPiBlackLevel, Debug)
|
||||
<< " Read black levels red " << blackLevelR_
|
||||
<< " green " << blackLevelG_
|
||||
|
|
|
@ -18,7 +18,7 @@ class BlackLevel : public Algorithm
|
|||
public:
|
||||
BlackLevel(Controller *controller);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -39,21 +39,22 @@ Matrix::Matrix(double m0, double m1, double m2, double m3, double m4, double m5,
|
|||
m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] = m4,
|
||||
m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8;
|
||||
}
|
||||
int Matrix::read(boost::property_tree::ptree const ¶ms)
|
||||
int Matrix::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
double *ptr = (double *)m;
|
||||
int n = 0;
|
||||
for (auto it = params.begin(); it != params.end(); it++) {
|
||||
if (n++ == 9) {
|
||||
LOG(RPiCcm, Error) << "Too many values in CCM";
|
||||
return -EINVAL;
|
||||
}
|
||||
*ptr++ = it->second.get_value<double>();
|
||||
}
|
||||
if (n < 9) {
|
||||
LOG(RPiCcm, Error) << "Too few values in CCM";
|
||||
|
||||
if (params.size() != 9) {
|
||||
LOG(RPiCcm, Error) << "Wrong number of values in CCM";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (const auto ¶m : params.asList()) {
|
||||
auto value = param.get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
*ptr++ = *value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -65,27 +66,33 @@ char const *Ccm::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Ccm::read(boost::property_tree::ptree const ¶ms)
|
||||
int Ccm::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (params.get_child_optional("saturation")) {
|
||||
ret = config_.saturation.read(params.get_child("saturation"));
|
||||
if (params.contains("saturation")) {
|
||||
ret = config_.saturation.read(params["saturation"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (auto &p : params.get_child("ccms")) {
|
||||
for (auto &p : params["ccms"].asList()) {
|
||||
auto value = p["ct"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
|
||||
CtCcm ctCcm;
|
||||
ctCcm.ct = p.second.get<double>("ct");
|
||||
ret = ctCcm.ccm.read(p.second.get_child("ccm"));
|
||||
ctCcm.ct = *value;
|
||||
ret = ctCcm.ccm.read(p["ccm"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!config_.ccms.empty() &&
|
||||
ctCcm.ct <= config_.ccms.back().ct) {
|
||||
LOG(RPiCcm, Error) << "CCM not in increasing colour temperature order";
|
||||
|
||||
if (!config_.ccms.empty() && ctCcm.ct <= config_.ccms.back().ct) {
|
||||
LOG(RPiCcm, Error)
|
||||
<< "CCM not in increasing colour temperature order";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config_.ccms.push_back(std::move(ctCcm));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ struct Matrix {
|
|||
double m6, double m7, double m8);
|
||||
Matrix();
|
||||
double m[3][3];
|
||||
int read(boost::property_tree::ptree const ¶ms);
|
||||
int read(const libcamera::YamlObject ¶ms);
|
||||
};
|
||||
static inline Matrix operator*(double d, Matrix const &m)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ class Ccm : public CcmAlgorithm
|
|||
public:
|
||||
Ccm(Controller *controller = NULL);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void setSaturation(double saturation) override;
|
||||
void initialise() override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
|
|
|
@ -38,21 +38,21 @@ char const *Contrast::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Contrast::read(boost::property_tree::ptree const ¶ms)
|
||||
int Contrast::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
/* enable adaptive enhancement by default */
|
||||
config_.ceEnable = params.get<int>("ce_enable", 1);
|
||||
/* the point near the bottom of the histogram to move */
|
||||
config_.loHistogram = params.get<double>("lo_histogram", 0.01);
|
||||
/* where in the range to try and move it to */
|
||||
config_.loLevel = params.get<double>("lo_level", 0.015);
|
||||
/* but don't move by more than this */
|
||||
config_.loMax = params.get<double>("lo_max", 500);
|
||||
/* equivalent values for the top of the histogram... */
|
||||
config_.hiHistogram = params.get<double>("hi_histogram", 0.95);
|
||||
config_.hiLevel = params.get<double>("hi_level", 0.95);
|
||||
config_.hiMax = params.get<double>("hi_max", 2000);
|
||||
return config_.gammaCurve.read(params.get_child("gamma_curve"));
|
||||
// enable adaptive enhancement by default
|
||||
config_.ceEnable = params["ce_enable"].get<int>(1);
|
||||
// the point near the bottom of the histogram to move
|
||||
config_.loHistogram = params["lo_histogram"].get<double>(0.01);
|
||||
// where in the range to try and move it to
|
||||
config_.loLevel = params["lo_level"].get<double>(0.015);
|
||||
// but don't move by more than this
|
||||
config_.loMax = params["lo_max"].get<double>(500);
|
||||
// equivalent values for the top of the histogram...
|
||||
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"]);
|
||||
}
|
||||
|
||||
void Contrast::setBrightness(double brightness)
|
||||
|
|
|
@ -34,7 +34,7 @@ class Contrast : public ContrastAlgorithm
|
|||
public:
|
||||
Contrast(Controller *controller = NULL);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void setBrightness(double brightness) override;
|
||||
void setContrast(double contrast) override;
|
||||
void initialise() override;
|
||||
|
|
|
@ -31,13 +31,14 @@ char const *Dpc::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Dpc::read(boost::property_tree::ptree const ¶ms)
|
||||
int Dpc::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
config_.strength = params.get<int>("strength", 1);
|
||||
config_.strength = params["strength"].get<int>(1);
|
||||
if (config_.strength < 0 || config_.strength > 2) {
|
||||
LOG(RPiDpc, Error) << "bad strength value";
|
||||
LOG(RPiDpc, Error) << "Bad strength value";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class Dpc : public Algorithm
|
|||
public:
|
||||
Dpc(Controller *controller);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -35,17 +35,17 @@ char const *Geq::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Geq::read(boost::property_tree::ptree const ¶ms)
|
||||
int Geq::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
config_.offset = params.get<uint16_t>("offset", 0);
|
||||
config_.slope = params.get<double>("slope", 0.0);
|
||||
config_.offset = params["offset"].get<uint16_t>(0);
|
||||
config_.slope = params["slope"].get<double>(0.0);
|
||||
if (config_.slope < 0.0 || config_.slope >= 1.0) {
|
||||
LOG(RPiGeq, Error) << "Bad slope value";
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params.get_child_optional("strength")) {
|
||||
int ret = config_.strength.read(params.get_child("strength"));
|
||||
if (params.contains("strength")) {
|
||||
int ret = config_.strength.read(params["strength"]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class Geq : public Algorithm
|
|||
public:
|
||||
Geq(Controller *controller);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -38,14 +38,30 @@ char const *Lux::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Lux::read(boost::property_tree::ptree const ¶ms)
|
||||
int Lux::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
referenceShutterSpeed_ =
|
||||
params.get<double>("reference_shutter_speed") * 1.0us;
|
||||
referenceGain_ = params.get<double>("reference_gain");
|
||||
referenceAperture_ = params.get<double>("reference_aperture", 1.0);
|
||||
referenceY_ = params.get<double>("reference_Y");
|
||||
referenceLux_ = params.get<double>("reference_lux");
|
||||
auto value = params["reference_shutter_speed"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
referenceShutterSpeed_ = *value * 1.0us;
|
||||
|
||||
value = params["reference_gain"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
referenceGain_ = *value;
|
||||
|
||||
referenceAperture_ = params["reference_aperture"].get<double>(1.0);
|
||||
|
||||
value = params["reference_Y"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
referenceY_ = *value;
|
||||
|
||||
value = params["reference_lux"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
referenceLux_ = *value;
|
||||
|
||||
currentAperture_ = referenceAperture_;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ class Lux : public Algorithm
|
|||
public:
|
||||
Lux(Controller *controller);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
void process(StatisticsPtr &stats, Metadata *imageMetadata) override;
|
||||
void setCurrentAperture(double aperture);
|
||||
|
|
|
@ -41,10 +41,18 @@ void Noise::switchMode(CameraMode const &cameraMode,
|
|||
modeFactor_ = std::max(1.0, cameraMode.noiseFactor);
|
||||
}
|
||||
|
||||
int Noise::read(boost::property_tree::ptree const ¶ms)
|
||||
int Noise::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
referenceConstant_ = params.get<double>("reference_constant");
|
||||
referenceSlope_ = params.get<double>("reference_slope");
|
||||
auto value = params["reference_constant"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
referenceConstant_ = *value;
|
||||
|
||||
value = params["reference_slope"].get<double>();
|
||||
if (!value)
|
||||
return -EINVAL;
|
||||
referenceSlope_ = *value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
Noise(Controller *controller);
|
||||
char const *name() const override;
|
||||
void switchMode(CameraMode const &cameraMode, Metadata *metadata) override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -34,10 +34,10 @@ char const *Sdn::name() const
|
|||
return NAME;
|
||||
}
|
||||
|
||||
int Sdn::read(boost::property_tree::ptree const ¶ms)
|
||||
int Sdn::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
deviation_ = params.get<double>("deviation", 3.2);
|
||||
strength_ = params.get<double>("strength", 0.75);
|
||||
deviation_ = params["deviation"].get<double>(3.2);
|
||||
strength_ = params["strength"].get<double>(0.75);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class Sdn : public DenoiseAlgorithm
|
|||
public:
|
||||
Sdn(Controller *controller = NULL);
|
||||
char const *name() const override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void initialise() override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
void setMode(DenoiseMode mode) override;
|
||||
|
|
|
@ -37,11 +37,11 @@ void Sharpen::switchMode(CameraMode const &cameraMode,
|
|||
modeFactor_ = std::max(1.0, cameraMode.noiseFactor);
|
||||
}
|
||||
|
||||
int Sharpen::read(boost::property_tree::ptree const ¶ms)
|
||||
int Sharpen::read(const libcamera::YamlObject ¶ms)
|
||||
{
|
||||
threshold_ = params.get<double>("threshold", 1.0);
|
||||
strength_ = params.get<double>("strength", 1.0);
|
||||
limit_ = params.get<double>("limit", 1.0);
|
||||
threshold_ = params["threshold"].get<double>(1.0);
|
||||
strength_ = params["strength"].get<double>(1.0);
|
||||
limit_ = params["limit"].get<double>(1.0);
|
||||
LOG(RPiSharpen, Debug)
|
||||
<< "Read threshold " << threshold_
|
||||
<< " strength " << strength_
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
Sharpen(Controller *controller);
|
||||
char const *name() const override;
|
||||
void switchMode(CameraMode const &cameraMode, Metadata *metadata) override;
|
||||
int read(boost::property_tree::ptree const ¶ms) override;
|
||||
int read(const libcamera::YamlObject ¶ms) override;
|
||||
void setStrength(double strength) override;
|
||||
void prepare(Metadata *imageMetadata) override;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ ipa_name = 'ipa_rpi'
|
|||
|
||||
rpi_ipa_deps = [
|
||||
libcamera_private,
|
||||
dependency('boost'),
|
||||
libatomic,
|
||||
]
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue