1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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 */
|