[RFC PATCH v2 12/12] ipa: rkisp1: awb: Replace manual calculations with Vector and Matrix
Milan Zamazal
mzamazal at redhat.com
Mon Nov 18 14:52:09 CET 2024
Laurent Pinchart <laurent.pinchart at ideasonboard.com> writes:
> 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>
Reviewed-by: Milan Zamazal <mzamazal at redhat.com>
> ---
> Changes since v1:
>
> - Adapt to Vector::normalize() being dropped
> ---
> 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..97163e0fa45c 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 divide by
> + * the sum of X, Y and Z to calculate the CIE xy chromaticity.
> + */
> + 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 /= xyz.sum();
>
> /* 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
More information about the libcamera-devel
mailing list