[libcamera-devel] [PATCH 4/5] libcamera: raspberrypi: ALSC: Handle transform in colour tables

David Plowman david.plowman at raspberrypi.com
Wed Jul 29 11:31:53 CEST 2020


This commit updates ALSC (Auto Lens Shading Correction) to handle the
transform now passed in the SwitchMode method.

The transform is applied by the sensor, so the statistics we get
already incorporates it, and the adpative algorithm is agnostic to
it. That leaves only the calibrated tables (assumed measured without
any user transform) that need to be flipped, and resample_cal_table -
where we resample the calibrated table anyway - is an easy place to do
it.
---
 src/ipa/raspberrypi/controller/rpi/alsc.cpp | 22 ++++++++++++++-------
 src/ipa/raspberrypi/controller/rpi/alsc.hpp |  3 ++-
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
index 5fac9dd..33c1a88 100644
--- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp
+++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
@@ -151,8 +151,9 @@ static void get_cal_table(double ct,
 			  std::vector<AlscCalibration> const &calibrations,
 			  double cal_table[XY]);
 static void resample_cal_table(double const cal_table_in[XY],
-			       CameraMode const &camera_mode,
-			       double cal_table_out[XY]);
+							   CameraMode const &camera_mode,
+							   Transform transform,
+							   double cal_table_out[XY]);
 static void compensate_lambdas_for_cal(double const cal_table[XY],
 				       double const old_lambdas[XY],
 				       double new_lambdas[XY]);
@@ -187,6 +188,7 @@ void Alsc::SwitchMode(CameraMode const &camera_mode, Transform transform, Metada
 	// change, any effects should be transient, and if they're not transient
 	// enough, we'll revisit the question then.
 	camera_mode_ = camera_mode;
+	transform_ = transform;
 	if (first_time_) {
 		// On the first time, arrange for something sensible in the
 		// initial tables. Construct the tables for some default colour
@@ -194,9 +196,9 @@ void Alsc::SwitchMode(CameraMode const &camera_mode, Transform transform, Metada
 		// adaptive algorithm.
 		double cal_table_r[XY], cal_table_b[XY], cal_table_tmp[XY];
 		get_cal_table(4000, config_.calibrations_Cr, cal_table_tmp);
-		resample_cal_table(cal_table_tmp, camera_mode_, cal_table_r);
+		resample_cal_table(cal_table_tmp, camera_mode_, transform_, cal_table_r);
 		get_cal_table(4000, config_.calibrations_Cb, cal_table_tmp);
-		resample_cal_table(cal_table_tmp, camera_mode_, cal_table_b);
+		resample_cal_table(cal_table_tmp, camera_mode_, transform_, cal_table_b);
 		compensate_lambdas_for_cal(cal_table_r, lambda_r_,
 					   async_lambda_r_);
 		compensate_lambdas_for_cal(cal_table_b, lambda_b_,
@@ -379,7 +381,9 @@ void get_cal_table(double ct, std::vector<AlscCalibration> const &calibrations,
 }
 
 void resample_cal_table(double const cal_table_in[XY],
-			CameraMode const &camera_mode, double cal_table_out[XY])
+						CameraMode const &camera_mode,
+						Transform transform,
+						double cal_table_out[XY])
 {
 	// Precalculate and cache the x sampling locations and phases to save
 	// recomputing them on every row.
@@ -395,6 +399,8 @@ void resample_cal_table(double const cal_table_in[XY],
 		xf[i] = x - x_lo[i];
 		x_hi[i] = std::min(x_lo[i] + 1, X - 1);
 		x_lo[i] = std::max(x_lo[i], 0);
+		if (transform.contains(Transform::hflip()))
+			x_lo[i] = X - 1 - x_lo[i], x_hi[i] = X - 1 - x_hi[i];
 	}
 	// Now march over the output table generating the new values.
 	double scale_y = camera_mode.sensor_height /
@@ -407,6 +413,8 @@ void resample_cal_table(double const cal_table_in[XY],
 		double yf = y - y_lo;
 		int y_hi = std::min(y_lo + 1, Y - 1);
 		y_lo = std::max(y_lo, 0);
+		if (transform.contains(Transform::vflip()))
+			y_lo = Y - 1 - y_lo, y_hi = Y - 1 - y_hi;
 		double const *row_above = cal_table_in + X * y_lo;
 		double const *row_below = cal_table_in + X * y_hi;
 		for (int i = 0; i < X; i++) {
@@ -671,9 +679,9 @@ void Alsc::doAlsc()
 	// Fetch the new calibrations (if any) for this CT. Resample them in
 	// case the camera mode is not full-frame.
 	get_cal_table(ct_, config_.calibrations_Cr, cal_table_tmp);
-	resample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_r);
+	resample_cal_table(cal_table_tmp, async_camera_mode_, transform_, cal_table_r);
 	get_cal_table(ct_, config_.calibrations_Cb, cal_table_tmp);
-	resample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_b);
+	resample_cal_table(cal_table_tmp, async_camera_mode_, transform_, cal_table_b);
 	// You could print out the cal tables for this image here, if you're
 	// tuning the algorithm...
 	(void)print_cal_table;
diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.hpp b/src/ipa/raspberrypi/controller/rpi/alsc.hpp
index 9b54578..9001e8a 100644
--- a/src/ipa/raspberrypi/controller/rpi/alsc.hpp
+++ b/src/ipa/raspberrypi/controller/rpi/alsc.hpp
@@ -60,7 +60,8 @@ private:
 	// configuration is read-only, and available to both threads
 	AlscConfig config_;
 	bool first_time_;
-	std::atomic<CameraMode> camera_mode_;
+	CameraMode camera_mode_;
+	libcamera::Transform transform_;
 	std::thread async_thread_;
 	void asyncFunc(); // asynchronous thread function
 	std::mutex mutex_;
-- 
2.20.1



More information about the libcamera-devel mailing list