[RFC,v2,12/12] ipa: rkisp1: awb: Replace manual calculations with Vector and Matrix
diff mbox series

Message ID 20241118000738.18977-13-laurent.pinchart@ideasonboard.com
State New
Headers show
Series
  • Improve linear algebra helpers in libipa
Related show

Commit Message

Laurent Pinchart Nov. 18, 2024, 12:07 a.m. UTC
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@ideasonboard.com>
---
Changes since v1:

- Adapt to Vector::normalize() being dropped
---
 src/ipa/rkisp1/algorithms/awb.cpp | 44 +++++++++++++++++++------------
 1 file changed, 27 insertions(+), 17 deletions(-)

Comments

Milan Zamazal Nov. 18, 2024, 1:52 p.m. UTC | #1
Laurent Pinchart <laurent.pinchart@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@ideasonboard.com>

Reviewed-by: Milan Zamazal <mzamazal@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

Patch
diff mbox series

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