[PATCH v2 1/1] libcamera: software_isp: Add saturation control

Milan Zamazal mzamazal at redhat.com
Mon May 12 19:04:52 CEST 2025


Bryan O'Donoghue <bryan.odonoghue at linaro.org> writes:

> On 30/04/2025 12:20, Milan Zamazal wrote:
>> Saturation control is added on top of the colour correction matrix.  A
>> way of saturation adjustment that can be fully integrated into the
>
>> colour correction matrix is used.  The control is available only if Ccm
>> algorithm is enabled.
>> The control uses 0.0-2.0 value range, with 1.0 being unmodified
>> saturation, 0.0 full desaturation and 2.0 quite saturated.
>> The saturation is adjusted by converting to Y'CbCr colour space,
>> applying the saturation value on the colour axes, and converting back to
>> RGB.  ITU-R BT.601 conversion is used to convert between the colour
>> spaces, for no particular reason.
>> The colour correction matrix is applied before gamma and the given
>> matrix is suitable for such a case.  Alternatively, the transformation
>> used in libcamera rpi ccm.cpp could be used.
>> Signed-off-by: Milan Zamazal <mzamazal at redhat.com>
>> ---
>>   src/ipa/simple/algorithms/ccm.cpp | 60 +++++++++++++++++++++++++++++--
>>   src/ipa/simple/algorithms/ccm.h   | 11 ++++++
>>   src/ipa/simple/ipa_context.h      |  4 +++
>>   3 files changed, 72 insertions(+), 3 deletions(-)
>> diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp
>> index d5ba928d..021aefc9 100644
>> --- a/src/ipa/simple/algorithms/ccm.cpp
>> +++ b/src/ipa/simple/algorithms/ccm.cpp
>> @@ -3,7 +3,7 @@
>>    * Copyright (C) 2024, Ideas On Board
>>    * Copyright (C) 2024-2025, Red Hat Inc.
>>    *
>> - * Color correction matrix
>> + * Color correction matrix + saturation
>>    */
>>   #include "ccm.h"
>> @@ -13,6 +13,8 @@
>>   #include <libcamera/control_ids.h>
>> +#include "libcamera/internal/matrix.h"
>> +
>>   namespace {
>>   constexpr unsigned int kTemperatureThreshold = 100;
>> @@ -35,28 +37,77 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData
>>   	}
>>   	context.ccmEnabled = true;
>> +	context.ctrlMap[&controls::Saturation] = ControlInfo(0.0f, 2.0f, 1.0f);
>> +
>> +	return 0;
>> +}
>> +
>> +int Ccm::configure(IPAContext &context,
>> +		   [[maybe_unused]] const IPAConfigInfo &configInfo)
>> +{
>> +	context.activeState.knobs.saturation = std::optional<double>();
>>   	return 0;
>>   }
>> +void Ccm::queueRequest(typename Module::Context &context,
>> +		       [[maybe_unused]] const uint32_t frame,
>> +		       [[maybe_unused]] typename Module::FrameContext &frameContext,
>> +		       const ControlList &controls)
>> +{
>> +	const auto &saturation = controls.get(controls::Saturation);
>> +	if (saturation.has_value()) {
>> +		context.activeState.knobs.saturation = saturation;
>> +		LOG(IPASoftCcm, Debug) << "Setting saturation to " << saturation.value();
>> +	}
>> +}
>> +
>> +void Ccm::updateSaturation(Matrix<float, 3, 3> &ccm, float saturation)
>> +{
>> +	/* https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion */
>> +	const Matrix<float, 3, 3> rgb2ycbcr{
>> +		{ 0.256788235294, 0.504129411765, 0.0979058823529,
>> +		  -0.148223529412, -0.290992156863, 0.439215686275,
>> +		  0.439215686275, -0.367788235294, -0.0714274509804 }
>> +	};
>> +	const Matrix<float, 3, 3> ycbcr2rgb{
>> +		{ 1.16438356164, 0, 1.59602678571,
>> +		  1.16438356164, -0.391762290094, -0.812967647235,
>> +		  1.16438356164, 2.01723214285, 0 }
>> +	};
>> +	const Matrix<float, 3, 3> saturationMatrix{
>> +		{ 1, 0, 0,
>> +		  0, saturation, 0,
>> +		  0, 0, saturation }
>> +	};
>> +	ccm = ycbcr2rgb * saturationMatrix * rgb2ycbcr * ccm;
>> +}
>
>> +I applied this to the GPUISP branch but it occurs to me I don't really 
> know how to test it.

If CCM is already working, you can run it with camshark and play with
the saturation control there: 0.0 = fully desaturated, 1.0 = normal
saturation, 2.0 = quite saturated.

> https://gitlab.freedesktop.org/camera/libcamera-softisp/-/tree/origin-master+whole-frame-swtats-v2-gpuisp-v1?ref_type=heads
>
> ---
> bod



More information about the libcamera-devel mailing list