[RFC PATCH 11/11] ipa: rkisp1: awb: Replace manual calculations with Vector and Matrix
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sun Nov 17 23:17:12 CET 2024
Processing of the statistics and estimation of the colour temperature
involve linear algebra. Replace the manual calculations with usage of
the Vector and Matrix classes.
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
src/ipa/rkisp1/algorithms/awb.cpp | 44 +++++++++++++++++++------------
1 file changed, 27 insertions(+), 17 deletions(-)
diff --git a/src/ipa/rkisp1/algorithms/awb.cpp b/src/ipa/rkisp1/algorithms/awb.cpp
index 1c572055acdd..c089523c8bde 100644
--- a/src/ipa/rkisp1/algorithms/awb.cpp
+++ b/src/ipa/rkisp1/algorithms/awb.cpp
@@ -169,17 +169,21 @@ void Awb::prepare(IPAContext &context, const uint32_t frame,
uint32_t Awb::estimateCCT(const RGB<double> &rgb)
{
- /* Convert the RGB values to CIE tristimulus values (XYZ) */
- double X = -0.14282 * rgb.r() + 1.54924 * rgb.g() - 0.95641 * rgb.b();
- double Y = -0.32466 * rgb.r() + 1.57837 * rgb.g() - 0.73191 * rgb.b();
- double Z = -0.68202 * rgb.r() + 0.77073 * rgb.g() + 0.56332 * rgb.b();
+ /*
+ * Convert the RGB values to CIE tristimulus values (XYZ) and normalize
+ * it (xyz).
+ */
+ static const Matrix<double, 3, 3> rgb2xyz({
+ -0.14282, 1.54924, -0.95641,
+ -0.32466, 1.57837, -0.73191,
+ -0.68202, 0.77073, 0.56332
+ });
- /* Calculate the normalized chromaticity values */
- double x = X / (X + Y + Z);
- double y = Y / (X + Y + Z);
+ Vector<double, 3> xyz = rgb2xyz * rgb;
+ xyz.normalize();
/* Calculate CCT */
- double n = (x - 0.3320) / (0.1858 - y);
+ double n = (xyz.x() - 0.3320) / (0.1858 - xyz.y());
return 449 * n * n * n + 3525 * n * n + 6823.3 * n + 5520.33;
}
@@ -215,9 +219,11 @@ void Awb::process(IPAContext &context,
rgbMeans.b() = awb->awb_mean[0].mean_cb_or_b;
} else {
/* Get the YCbCr mean values */
- double yMean = awb->awb_mean[0].mean_y_or_g;
- double cbMean = awb->awb_mean[0].mean_cb_or_b;
- double crMean = awb->awb_mean[0].mean_cr_or_r;
+ Vector<double, 3> yuvMeans({
+ static_cast<double>(awb->awb_mean[0].mean_y_or_g),
+ static_cast<double>(awb->awb_mean[0].mean_cb_or_b),
+ static_cast<double>(awb->awb_mean[0].mean_cr_or_r)
+ });
/*
* Convert from YCbCr to RGB.
@@ -231,12 +237,16 @@ void Awb::process(IPAContext &context,
* [1,1636, -0,4045, -0,7949]
* [1,1636, 1,9912, -0,0250]]
*/
- yMean -= 16;
- cbMean -= 128;
- crMean -= 128;
- rgbMeans.r() = 1.1636 * yMean - 0.0623 * cbMean + 1.6008 * crMean;
- rgbMeans.g() = 1.1636 * yMean - 0.4045 * cbMean - 0.7949 * crMean;
- rgbMeans.b() = 1.1636 * yMean + 1.9912 * cbMean - 0.0250 * crMean;
+ static const Matrix<double, 3, 3> yuv2rgbMatrix({
+ 1.1636, -0.0623, 1.6008,
+ 1.1636, -0.4045, -0.7949,
+ 1.1636, 1.9912, -0.0250
+ });
+ static const Vector<double, 3> yuv2rgbOffset({
+ 16, 128, 128
+ });
+
+ rgbMeans = yuv2rgbMatrix * (yuvMeans - yuv2rgbOffset);
/*
* Due to hardware rounding errors in the YCbCr means, the
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list