[v3,12/17] ipa: ipu3: awb: Replace Awb::RGB class with ipa::RGB
diff mbox series

Message ID 20241118221618.13953-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, 10:16 p.m. UTC
Now that libipa has a generic RGB class, replaces the local
implementation from the IPU3 AWB algorithm.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/ipa/ipu3/algorithms/awb.cpp | 37 ++++++++++++++++++---------------
 src/ipa/ipu3/algorithms/awb.h   | 18 +++-------------
 2 files changed, 23 insertions(+), 32 deletions(-)

Comments

Milan Zamazal Nov. 19, 2024, 10:31 a.m. UTC | #1
Laurent Pinchart <laurent.pinchart@ideasonboard.com> writes:

> Now that libipa has a generic RGB class, replaces the local
> implementation from the IPU3 AWB algorithm.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Milan Zamazal <mzamazal@redhat.com>

> ---
>  src/ipa/ipu3/algorithms/awb.cpp | 37 ++++++++++++++++++---------------
>  src/ipa/ipu3/algorithms/awb.h   | 18 +++-------------
>  2 files changed, 23 insertions(+), 32 deletions(-)
>
> diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp
> index c3c8b0740f36..7c6bff09147c 100644
> --- a/src/ipa/ipu3/algorithms/awb.cpp
> +++ b/src/ipa/ipu3/algorithms/awb.cpp
> @@ -309,15 +309,18 @@ void Awb::generateZones()
>  	zones_.clear();
>  
>  	for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {
> -		RGB zone;
>  		double counted = awbStats_[i].counted;
>  		if (counted >= cellsPerZoneThreshold_) {
> -			zone.G = awbStats_[i].sum.green / counted;
> -			if (zone.G >= kMinGreenLevelInZone) {
> -				zone.R = awbStats_[i].sum.red / counted;
> -				zone.B = awbStats_[i].sum.blue / counted;
> +			RGB<double> zone{{
> +				static_cast<double>(awbStats_[i].sum.red),
> +				static_cast<double>(awbStats_[i].sum.green),
> +				static_cast<double>(awbStats_[i].sum.blue)
> +			}};
> +
> +			zone /= counted;
> +
> +			if (zone.g() >= kMinGreenLevelInZone)
>  				zones_.push_back(zone);
> -			}
>  		}
>  	}
>  }
> @@ -384,32 +387,32 @@ void Awb::awbGreyWorld()
>  	 * consider some variations, such as normalising all the zones first, or
>  	 * doing an L2 average etc.
>  	 */
> -	std::vector<RGB> &redDerivative(zones_);
> -	std::vector<RGB> blueDerivative(redDerivative);
> +	std::vector<RGB<double>> &redDerivative(zones_);
> +	std::vector<RGB<double>> blueDerivative(redDerivative);
>  	std::sort(redDerivative.begin(), redDerivative.end(),
> -		  [](RGB const &a, RGB const &b) {
> -			  return a.G * b.R < b.G * a.R;
> +		  [](RGB<double> const &a, RGB<double> const &b) {
> +			  return a.g() * b.r() < b.g() * a.r();
>  		  });
>  	std::sort(blueDerivative.begin(), blueDerivative.end(),
> -		  [](RGB const &a, RGB const &b) {
> -			  return a.G * b.B < b.G * a.B;
> +		  [](RGB<double> const &a, RGB<double> const &b) {
> +			  return a.g() * b.b() < b.g() * a.b();
>  		  });
>  
>  	/* Average the middle half of the values. */
>  	int discard = redDerivative.size() / 4;
>  
> -	RGB sumRed(0, 0, 0);
> -	RGB sumBlue(0, 0, 0);
> +	RGB<double> sumRed{ 0.0 };
> +	RGB<double> sumBlue{ 0.0 };
>  	for (auto ri = redDerivative.begin() + discard,
>  		  bi = blueDerivative.begin() + discard;
>  	     ri != redDerivative.end() - discard; ri++, bi++)
>  		sumRed += *ri, sumBlue += *bi;
>  
> -	double redGain = sumRed.G / (sumRed.R + 1),
> -	       blueGain = sumBlue.G / (sumBlue.B + 1);
> +	double redGain = sumRed.g() / (sumRed.r() + 1),
> +	       blueGain = sumBlue.g() / (sumBlue.b() + 1);
>  
>  	/* Color temperature is not relevant in Grey world but still useful to estimate it :-) */
> -	asyncResults_.temperatureK = estimateCCT(sumRed.R, sumRed.G, sumBlue.B);
> +	asyncResults_.temperatureK = estimateCCT(sumRed.r(), sumRed.g(), sumBlue.b());
>  
>  	/*
>  	 * Gain values are unsigned integer value ranging [0, 8) with 13 bit
> diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h
> index a13c49acc1fe..1916990a5364 100644
> --- a/src/ipa/ipu3/algorithms/awb.h
> +++ b/src/ipa/ipu3/algorithms/awb.h
> @@ -13,6 +13,8 @@
>  
>  #include <libcamera/geometry.h>
>  
> +#include "libipa/vector.h"
> +
>  #include "algorithm.h"
>  
>  namespace libcamera {
> @@ -48,20 +50,6 @@ public:
>  		     ControlList &metadata) override;
>  
>  private:
> -	/* \todo Make these structs available to all the ISPs ? */
> -	struct RGB {
> -		RGB(double _R = 0, double _G = 0, double _B = 0)
> -			: R(_R), G(_G), B(_B)
> -		{
> -		}
> -		double R, G, B;
> -		RGB &operator+=(RGB const &other)
> -		{
> -			R += other.R, G += other.G, B += other.B;
> -			return *this;
> -		}
> -	};
> -
>  	struct AwbStatus {
>  		double temperatureK;
>  		double redGain;
> @@ -78,7 +66,7 @@ private:
>  	static constexpr uint16_t threshold(float value);
>  	static constexpr uint16_t gainValue(double gain);
>  
> -	std::vector<RGB> zones_;
> +	std::vector<RGB<double>> zones_;
>  	Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
>  	AwbStatus asyncResults_;

Patch
diff mbox series

diff --git a/src/ipa/ipu3/algorithms/awb.cpp b/src/ipa/ipu3/algorithms/awb.cpp
index c3c8b0740f36..7c6bff09147c 100644
--- a/src/ipa/ipu3/algorithms/awb.cpp
+++ b/src/ipa/ipu3/algorithms/awb.cpp
@@ -309,15 +309,18 @@  void Awb::generateZones()
 	zones_.clear();
 
 	for (unsigned int i = 0; i < kAwbStatsSizeX * kAwbStatsSizeY; i++) {
-		RGB zone;
 		double counted = awbStats_[i].counted;
 		if (counted >= cellsPerZoneThreshold_) {
-			zone.G = awbStats_[i].sum.green / counted;
-			if (zone.G >= kMinGreenLevelInZone) {
-				zone.R = awbStats_[i].sum.red / counted;
-				zone.B = awbStats_[i].sum.blue / counted;
+			RGB<double> zone{{
+				static_cast<double>(awbStats_[i].sum.red),
+				static_cast<double>(awbStats_[i].sum.green),
+				static_cast<double>(awbStats_[i].sum.blue)
+			}};
+
+			zone /= counted;
+
+			if (zone.g() >= kMinGreenLevelInZone)
 				zones_.push_back(zone);
-			}
 		}
 	}
 }
@@ -384,32 +387,32 @@  void Awb::awbGreyWorld()
 	 * consider some variations, such as normalising all the zones first, or
 	 * doing an L2 average etc.
 	 */
-	std::vector<RGB> &redDerivative(zones_);
-	std::vector<RGB> blueDerivative(redDerivative);
+	std::vector<RGB<double>> &redDerivative(zones_);
+	std::vector<RGB<double>> blueDerivative(redDerivative);
 	std::sort(redDerivative.begin(), redDerivative.end(),
-		  [](RGB const &a, RGB const &b) {
-			  return a.G * b.R < b.G * a.R;
+		  [](RGB<double> const &a, RGB<double> const &b) {
+			  return a.g() * b.r() < b.g() * a.r();
 		  });
 	std::sort(blueDerivative.begin(), blueDerivative.end(),
-		  [](RGB const &a, RGB const &b) {
-			  return a.G * b.B < b.G * a.B;
+		  [](RGB<double> const &a, RGB<double> const &b) {
+			  return a.g() * b.b() < b.g() * a.b();
 		  });
 
 	/* Average the middle half of the values. */
 	int discard = redDerivative.size() / 4;
 
-	RGB sumRed(0, 0, 0);
-	RGB sumBlue(0, 0, 0);
+	RGB<double> sumRed{ 0.0 };
+	RGB<double> sumBlue{ 0.0 };
 	for (auto ri = redDerivative.begin() + discard,
 		  bi = blueDerivative.begin() + discard;
 	     ri != redDerivative.end() - discard; ri++, bi++)
 		sumRed += *ri, sumBlue += *bi;
 
-	double redGain = sumRed.G / (sumRed.R + 1),
-	       blueGain = sumBlue.G / (sumBlue.B + 1);
+	double redGain = sumRed.g() / (sumRed.r() + 1),
+	       blueGain = sumBlue.g() / (sumBlue.b() + 1);
 
 	/* Color temperature is not relevant in Grey world but still useful to estimate it :-) */
-	asyncResults_.temperatureK = estimateCCT(sumRed.R, sumRed.G, sumBlue.B);
+	asyncResults_.temperatureK = estimateCCT(sumRed.r(), sumRed.g(), sumBlue.b());
 
 	/*
 	 * Gain values are unsigned integer value ranging [0, 8) with 13 bit
diff --git a/src/ipa/ipu3/algorithms/awb.h b/src/ipa/ipu3/algorithms/awb.h
index a13c49acc1fe..1916990a5364 100644
--- a/src/ipa/ipu3/algorithms/awb.h
+++ b/src/ipa/ipu3/algorithms/awb.h
@@ -13,6 +13,8 @@ 
 
 #include <libcamera/geometry.h>
 
+#include "libipa/vector.h"
+
 #include "algorithm.h"
 
 namespace libcamera {
@@ -48,20 +50,6 @@  public:
 		     ControlList &metadata) override;
 
 private:
-	/* \todo Make these structs available to all the ISPs ? */
-	struct RGB {
-		RGB(double _R = 0, double _G = 0, double _B = 0)
-			: R(_R), G(_G), B(_B)
-		{
-		}
-		double R, G, B;
-		RGB &operator+=(RGB const &other)
-		{
-			R += other.R, G += other.G, B += other.B;
-			return *this;
-		}
-	};
-
 	struct AwbStatus {
 		double temperatureK;
 		double redGain;
@@ -78,7 +66,7 @@  private:
 	static constexpr uint16_t threshold(float value);
 	static constexpr uint16_t gainValue(double gain);
 
-	std::vector<RGB> zones_;
+	std::vector<RGB<double>> zones_;
 	Accumulator awbStats_[kAwbStatsSizeX * kAwbStatsSizeY];
 	AwbStatus asyncResults_;