mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-12 23:09:45 +03:00
libipa: Add grey world AWB algorithm
Add the grey world algorithm that is currently used in rkisp1 to libipa. No changes in functionality were made. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
parent
d19ae2a228
commit
7ea83d5f7b
3 changed files with 151 additions and 0 deletions
114
src/ipa/libipa/awb_grey.cpp
Normal file
114
src/ipa/libipa/awb_grey.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2024 Ideas on Board Oy
|
||||
*
|
||||
* Base class for grey world AWB algorithm
|
||||
*/
|
||||
|
||||
#include "awb_grey.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <libcamera/base/log.h>
|
||||
#include <libcamera/control_ids.h>
|
||||
|
||||
#include "colours.h"
|
||||
|
||||
using namespace libcamera::controls;
|
||||
|
||||
/**
|
||||
* \file awb_grey.h
|
||||
* \brief Implementation of a grey world AWB algorithm
|
||||
*/
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
LOG_DECLARE_CATEGORY(Awb)
|
||||
namespace ipa {
|
||||
|
||||
/**
|
||||
* \class AwbGrey
|
||||
* \brief A Grey world auto white balance algorithm
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Initialize the algorithm with the given tuning data
|
||||
* \param[in] tuningData The tuning data for the algorithm
|
||||
*
|
||||
* Load the colour temperature curve from the tuning data. If there is no tuning
|
||||
* data available, continue with a warning. Manual colour temperature will not
|
||||
* work in that case.
|
||||
*
|
||||
* \return 0 on success, a negative error code otherwise
|
||||
*/
|
||||
int AwbGrey::init(const YamlObject &tuningData)
|
||||
{
|
||||
Interpolator<Vector<double, 2>> gains;
|
||||
int ret = gains.readYaml(tuningData["colourGains"], "ct", "gains");
|
||||
if (ret < 0)
|
||||
LOG(Awb, Warning)
|
||||
<< "Failed to parse 'colourGains' "
|
||||
<< "parameter from tuning file; "
|
||||
<< "manual colour temperature will not work properly";
|
||||
else
|
||||
colourGainCurve_ = gains;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate awb data from the given statistics
|
||||
* \param[in] stats The statistics to use for the calculation
|
||||
* \param[in] lux The lux value of the scene
|
||||
*
|
||||
* Estimates the colour temperature based on the colours::estimateCCT function.
|
||||
* The gains are calculated purely based on the RGB means provided by the \a
|
||||
* stats. The colour temperature is not taken into account when calculating the
|
||||
* gains.
|
||||
*
|
||||
* The \a lux parameter is not used in this algorithm.
|
||||
*
|
||||
* \return The awb result
|
||||
*/
|
||||
AwbResult AwbGrey::calculateAwb(const AwbStats &stats, [[maybe_unused]] int lux)
|
||||
{
|
||||
AwbResult result;
|
||||
auto means = stats.getRGBMeans();
|
||||
result.colourTemperature = estimateCCT(means);
|
||||
|
||||
/*
|
||||
* Estimate the red and blue gains to apply in a grey world. The green
|
||||
* gain is hardcoded to 1.0. Avoid divisions by zero by clamping the
|
||||
* divisor to a minimum value of 1.0.
|
||||
*/
|
||||
result.gains.r() = means.g() / std::max(means.r(), 1.0);
|
||||
result.gains.g() = 1.0;
|
||||
result.gains.b() = means.g() / std::max(means.b(), 1.0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Compute white balance gains from a colour temperature
|
||||
* \param[in] colourTemperature The colour temperature in Kelvin
|
||||
*
|
||||
* Compute the white balance gains from a \a colourTemperature. This function
|
||||
* does not take any statistics into account. It simply interpolates the colour
|
||||
* gains configured in the colour temperature curve.
|
||||
*
|
||||
* \return The colour gains if a colour temperature curve is available,
|
||||
* [1, 1, 1] otherwise.
|
||||
*/
|
||||
RGB<double> AwbGrey::gainsFromColourTemperature(double colourTemperature)
|
||||
{
|
||||
if (!colourGainCurve_) {
|
||||
LOG(Awb, Error) << "No gains defined";
|
||||
return RGB<double>({ 1.0, 1.0, 1.0 });
|
||||
}
|
||||
|
||||
auto gains = colourGainCurve_->getInterpolated(colourTemperature);
|
||||
return { { gains[0], 1.0, gains[1] } };
|
||||
}
|
||||
|
||||
} /* namespace ipa */
|
||||
|
||||
} /* namespace libcamera */
|
35
src/ipa/libipa/awb_grey.h
Normal file
35
src/ipa/libipa/awb_grey.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2024 Ideas on Board Oy
|
||||
*
|
||||
* AWB grey world algorithm
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "libcamera/internal/vector.h"
|
||||
#include "libcamera/internal/yaml_parser.h"
|
||||
|
||||
#include "awb.h"
|
||||
#include "interpolator.h"
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
namespace ipa {
|
||||
|
||||
class AwbGrey : public AwbAlgorithm
|
||||
{
|
||||
public:
|
||||
AwbGrey() = default;
|
||||
|
||||
int init(const YamlObject &tuningData) override;
|
||||
AwbResult calculateAwb(const AwbStats &stats, int lux) override;
|
||||
RGB<double> gainsFromColourTemperature(double colourTemperature) override;
|
||||
|
||||
private:
|
||||
std::optional<Interpolator<Vector<double, 2>>> colourGainCurve_;
|
||||
};
|
||||
|
||||
} /* namespace ipa */
|
||||
|
||||
} /* namespace libcamera */
|
|
@ -3,6 +3,7 @@
|
|||
libipa_headers = files([
|
||||
'agc_mean_luminance.h',
|
||||
'algorithm.h',
|
||||
'awb_grey.h',
|
||||
'awb.h',
|
||||
'camera_sensor_helper.h',
|
||||
'colours.h',
|
||||
|
@ -20,6 +21,7 @@ libipa_headers = files([
|
|||
libipa_sources = files([
|
||||
'agc_mean_luminance.cpp',
|
||||
'algorithm.cpp',
|
||||
'awb_grey.cpp',
|
||||
'awb.cpp',
|
||||
'camera_sensor_helper.cpp',
|
||||
'colours.cpp',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue