ipa: rpi: ccm: Replace local matrix implementation with the libcamera one
The RaspberryPi IPA contains a private Matrix3x3 class inside the ccm algorithm. Replace it with the Matrix class available in libcamera/internal. While at it, mark the matrices RGB2Y and Y2RGB as static const. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Naushir Patuck <naush@raspberrypi.com>
This commit is contained in:
parent
5b7f89d9b8
commit
0c43b77759
2 changed files with 22 additions and 72 deletions
|
@ -29,34 +29,7 @@ LOG_DEFINE_CATEGORY(RPiCcm)
|
||||||
|
|
||||||
#define NAME "rpi.ccm"
|
#define NAME "rpi.ccm"
|
||||||
|
|
||||||
Matrix3x3::Matrix3x3()
|
using Matrix3x3 = Matrix<double, 3, 3>;
|
||||||
{
|
|
||||||
memset(m, 0, sizeof(m));
|
|
||||||
}
|
|
||||||
Matrix3x3::Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5,
|
|
||||||
double m6, double m7, double m8)
|
|
||||||
{
|
|
||||||
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 Matrix3x3::read(const libcamera::YamlObject ¶ms)
|
|
||||||
{
|
|
||||||
double *ptr = (double *)m;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ccm::Ccm(Controller *controller)
|
Ccm::Ccm(Controller *controller)
|
||||||
: CcmAlgorithm(controller), saturation_(1.0) {}
|
: CcmAlgorithm(controller), saturation_(1.0) {}
|
||||||
|
@ -68,8 +41,6 @@ char const *Ccm::name() const
|
||||||
|
|
||||||
int Ccm::read(const libcamera::YamlObject ¶ms)
|
int Ccm::read(const libcamera::YamlObject ¶ms)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (params.contains("saturation")) {
|
if (params.contains("saturation")) {
|
||||||
config_.saturation = params["saturation"].get<ipa::Pwl>(ipa::Pwl{});
|
config_.saturation = params["saturation"].get<ipa::Pwl>(ipa::Pwl{});
|
||||||
if (config_.saturation.empty())
|
if (config_.saturation.empty())
|
||||||
|
@ -83,9 +54,12 @@ int Ccm::read(const libcamera::YamlObject ¶ms)
|
||||||
|
|
||||||
CtCcm ctCcm;
|
CtCcm ctCcm;
|
||||||
ctCcm.ct = *value;
|
ctCcm.ct = *value;
|
||||||
ret = ctCcm.ccm.read(p["ccm"]);
|
|
||||||
if (ret)
|
auto ccm = p["ccm"].get<Matrix3x3>();
|
||||||
return ret;
|
if (!ccm)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ctCcm.ccm = *ccm;
|
||||||
|
|
||||||
if (!config_.ccms.empty() && ctCcm.ct <= config_.ccms.back().ct) {
|
if (!config_.ccms.empty() && ctCcm.ct <= config_.ccms.back().ct) {
|
||||||
LOG(RPiCcm, Error)
|
LOG(RPiCcm, Error)
|
||||||
|
@ -143,11 +117,18 @@ Matrix3x3 calculateCcm(std::vector<CtCcm> const &ccms, double ct)
|
||||||
|
|
||||||
Matrix3x3 applySaturation(Matrix3x3 const &ccm, double saturation)
|
Matrix3x3 applySaturation(Matrix3x3 const &ccm, double saturation)
|
||||||
{
|
{
|
||||||
Matrix3x3 RGB2Y(0.299, 0.587, 0.114, -0.169, -0.331, 0.500, 0.500, -0.419,
|
static const Matrix3x3 RGB2Y({ 0.299, 0.587, 0.114,
|
||||||
-0.081);
|
-0.169, -0.331, 0.500,
|
||||||
Matrix3x3 Y2RGB(1.000, 0.000, 1.402, 1.000, -0.345, -0.714, 1.000, 1.771,
|
0.500, -0.419, -0.081 });
|
||||||
0.000);
|
|
||||||
Matrix3x3 S(1, 0, 0, 0, saturation, 0, 0, 0, saturation);
|
static const Matrix3x3 Y2RGB({ 1.000, 0.000, 1.402,
|
||||||
|
1.000, -0.345, -0.714,
|
||||||
|
1.000, 1.771, 0.000 });
|
||||||
|
|
||||||
|
Matrix3x3 S({ 1, 0, 0,
|
||||||
|
0, saturation, 0,
|
||||||
|
0, 0, saturation });
|
||||||
|
|
||||||
return Y2RGB * S * RGB2Y * ccm;
|
return Y2RGB * S * RGB2Y * ccm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +162,7 @@ void Ccm::prepare(Metadata *imageMetadata)
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
ccmStatus.matrix[j * 3 + i] =
|
ccmStatus.matrix[j * 3 + i] =
|
||||||
std::max(-8.0, std::min(7.9999, ccm.m[j][i]));
|
std::max(-8.0, std::min(7.9999, ccm[j][i]));
|
||||||
LOG(RPiCcm, Debug)
|
LOG(RPiCcm, Debug)
|
||||||
<< "colour temperature " << awb.temperatureK << "K";
|
<< "colour temperature " << awb.temperatureK << "K";
|
||||||
LOG(RPiCcm, Debug)
|
LOG(RPiCcm, Debug)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "libcamera/internal/matrix.h"
|
||||||
#include <libipa/pwl.h>
|
#include <libipa/pwl.h>
|
||||||
|
|
||||||
#include "../ccm_algorithm.h"
|
#include "../ccm_algorithm.h"
|
||||||
|
@ -16,41 +17,9 @@ namespace RPiController {
|
||||||
|
|
||||||
/* Algorithm to calculate colour matrix. Should be placed after AWB. */
|
/* Algorithm to calculate colour matrix. Should be placed after AWB. */
|
||||||
|
|
||||||
struct Matrix3x3 {
|
|
||||||
Matrix3x3(double m0, double m1, double m2, double m3, double m4, double m5,
|
|
||||||
double m6, double m7, double m8);
|
|
||||||
Matrix3x3();
|
|
||||||
double m[3][3];
|
|
||||||
int read(const libcamera::YamlObject ¶ms);
|
|
||||||
};
|
|
||||||
static inline Matrix3x3 operator*(double d, Matrix3x3 const &m)
|
|
||||||
{
|
|
||||||
return Matrix3x3(m.m[0][0] * d, m.m[0][1] * d, m.m[0][2] * d,
|
|
||||||
m.m[1][0] * d, m.m[1][1] * d, m.m[1][2] * d,
|
|
||||||
m.m[2][0] * d, m.m[2][1] * d, m.m[2][2] * d);
|
|
||||||
}
|
|
||||||
static inline Matrix3x3 operator*(Matrix3x3 const &m1, Matrix3x3 const &m2)
|
|
||||||
{
|
|
||||||
Matrix3x3 m;
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
m.m[i][j] = m1.m[i][0] * m2.m[0][j] +
|
|
||||||
m1.m[i][1] * m2.m[1][j] +
|
|
||||||
m1.m[i][2] * m2.m[2][j];
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
static inline Matrix3x3 operator+(Matrix3x3 const &m1, Matrix3x3 const &m2)
|
|
||||||
{
|
|
||||||
Matrix3x3 m;
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
m.m[i][j] = m1.m[i][j] + m2.m[i][j];
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CtCcm {
|
struct CtCcm {
|
||||||
double ct;
|
double ct;
|
||||||
Matrix3x3 ccm;
|
libcamera::Matrix<double, 3, 3> ccm;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CcmConfig {
|
struct CcmConfig {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue