M5Unit-COLOR 0.1.1 git rev:9de2836
Loading...
Searching...
No Matches
unit_color_utility.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_HPP
11#define M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_HPP
12
14#include <cmath>
15#include <tuple>
16#include <cassert>
17
18namespace m5 {
19namespace unit {
20namespace tcs3472x {
21
24constexpr float GA{1.0f};
25// constexpr float GA{1.08f}; // Placing the parts behind clear glass requires using GA = 1.08
26constexpr float DF{310.f};
27constexpr float DGF{GA * DF};
28constexpr float R_Coef{0.136f};
29constexpr float G_Coef{1.0f};
30constexpr float B_Coef{-0.444f};
31constexpr float CT_Coef{3810.f};
32constexpr float CT_Offset{1391.f};
34
37constexpr float AT_NORMAL_FACTOR = 2.4f;
38constexpr float AT_NORMAL_MIN = AT_NORMAL_FACTOR; // 2.4ms
39constexpr float AT_NORMAL_MAX = 256 * AT_NORMAL_FACTOR; // 614.4ms
40//
41constexpr float WT_NORMAL_FACTOR = AT_NORMAL_FACTOR;
42constexpr float WT_NORMAL_MIN = WT_NORMAL_FACTOR; // 2.4ms
43constexpr float WT_NORMAL_MAX = 256 * WT_NORMAL_FACTOR; // 614.4ms
44constexpr float WT_LONG_FACTOR = 2.4f * 12.f;
45constexpr float WT_LONG_MIN = WT_LONG_FACTOR; // 28.8ms
46constexpr float WT_LONG_MAX = 256 * WT_LONG_FACTOR; // 7372.8ms
48
62 Calibration(const uint16_t br, const uint16_t wr, const uint16_t bg, const uint16_t wg, const uint16_t bb,
63 const uint16_t wb)
64 : blackR{br}, whiteR{wr}, blackG{bg}, whiteG{wg}, blackB{bb}, whiteB{wb}
65 {
66 assert(wr > br && "White must be greater than black");
67 assert(wg > bg && "White must be greater than black");
68 assert(wb > bb && "White must be greater than black");
69 }
70
71 uint16_t blackR{};
72 uint16_t whiteR{};
73 uint16_t blackG{};
74 uint16_t whiteG{};
75 uint16_t blackB{};
76 uint16_t whiteB{};
77
79 inline uint8_t R8(const Data& d) const
80 {
81 return linear(d.RnoIR16(), blackR, whiteR);
82 }
84 inline uint8_t G8(const Data& d) const
85 {
86 return linear(d.GnoIR16(), blackG, whiteG);
87 }
89 inline uint8_t B8(const Data& d) const
90 {
91 return linear(d.BnoIR16(), blackB, whiteB);
92 }
93
95 inline static uint8_t linear(const uint16_t raw, const uint16_t low, const uint16_t high)
96 {
97 if (raw <= low) {
98 return 0U;
99 }
100 if (raw >= high) {
101 return 255U;
102 }
103 return static_cast<uint8_t>(
104 std::round((static_cast<float>(raw) - static_cast<float>(low)) / (static_cast<float>(high - low)) * 255.f));
105 }
106};
107
109inline float atime_to_ms(const uint8_t a)
110{
111 return 2.4f * (256 - a);
112}
113
115inline float wtime_to_ms(const uint8_t w, const bool wlong)
116{
117 return atime_to_ms(w) * (wlong ? 12 : 1);
118}
119
121inline uint8_t ms_to_atime(const float ms)
122{
123 int tmp = 256 - std::round(ms / 2.4f);
124 return static_cast<uint8_t>(std::max(std::min(tmp, 0xFF), 0x00));
125}
126
128std::tuple<uint8_t, bool> ms_to_wtime(const float ms);
129
144float calculateLux(const uint16_t rawR, const uint16_t rawG, const uint16_t rawB, const uint16_t rawC,
145 const float atime_ms, const Gain gc, const float dgf = DGF, const float coefR = R_Coef,
146 const float coefG = G_Coef, const float coefB = B_Coef);
147
158float calculateColorTemperature(const uint16_t rawR, const uint16_t rawG, const uint16_t rawB, const uint16_t rawC,
159 const float coefCT = CT_Coef, const float offsetCT = CT_Offset);
160
167uint16_t calculateSaturation(const uint8_t atime);
168
175inline uint16_t calculateSaturation(const float atime_ms)
176{
177 return calculateSaturation(ms_to_atime(atime_ms));
178}
179
194float calculateCRATIO(const uint16_t rawR, const uint16_t rawG, const uint16_t rawB, const uint16_t rawC);
195
203float calculateCPL(const float atime_ms, const Gain gc, const float dgf = DGF);
204
212inline float calculateMaxLux(const float atime_ms, const Gain gc, const float dgf = DGF)
213{
214 return 65535.0f / (3.0f * calculateCPL(atime_ms, gc, dgf));
215}
216
218template <typename T, T... Ints>
219struct integer_sequence {
220 typedef T value_type;
221 static constexpr std::size_t size()
222 {
223 return sizeof...(Ints);
224 }
225};
226
227// Porting C++14 features to C++11
228// clang-format off
229template <size_t... Ints>
230using index_sequence = integer_sequence<size_t, Ints...>;
231
232template <typename T, size_t N, T... Is>
233struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Is...> {};
234
235template <typename T, T... Is>
236struct make_integer_sequence<T, 0, Is...> : integer_sequence<T, Is...> {};
237
238template <size_t N>
239using make_index_sequence = make_integer_sequence<size_t, N>;
240// clang-format on
241
242// constexpr version of std::pow is GCC4.6.1 or higher
243#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 6 || (__GNUC_MINOR__ == 6 && __GNUC_PATCHLEVEL__ > 0)))
244#define M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_CAN_CONSTEXPR_MAKE_GAMMA_TABLE
245#define M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_CONSTEXPR constexpr
246#else
247#define M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_CONSTEXPR
248#endif
249
250M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_CONSTEXPR uint8_t calculate_gamma(const float x, const float gamma)
251{
252 return static_cast<uint8_t>(std::pow(x, gamma) * 255);
253}
254
255template <size_t... Indices>
256M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_CONSTEXPR std::array<uint8_t, sizeof...(Indices)> make_gamma_table_impl(
257 const float gamma, index_sequence<Indices...>)
258{
259 return {calculate_gamma(static_cast<float>(Indices) / 255.0f, gamma)...};
260}
262
270template <size_t Size = 256>
271M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_CONSTEXPR std::array<uint8_t, Size> make_gamma_table(const float gamma = 2.2f)
272{
273 return make_gamma_table_impl(gamma, make_index_sequence<Size>{});
274}
275
276} // namespace tcs3472x
277} // namespace unit
278} // namespace m5
279#endif
Top level namespace of M5Stack.
For TCS3472x.
Unit-related namespace.
Raw value to determine black and white.
Definition unit_color_utility.hpp:53
uint16_t blackG
Black reference value for green.
Definition unit_color_utility.hpp:73
uint8_t G8(const Data &d) const
Get the green value with calibration.
Definition unit_color_utility.hpp:84
static uint8_t linear(const uint16_t raw, const uint16_t low, const uint16_t high)
Linear interpolation in a specified range.
Definition unit_color_utility.hpp:95
uint16_t whiteB
White reference value for blue.
Definition unit_color_utility.hpp:76
uint8_t B8(const Data &d) const
Get the blue value with calibration.
Definition unit_color_utility.hpp:89
uint16_t blackR
Black reference value for red.
Definition unit_color_utility.hpp:71
Calibration(const uint16_t br, const uint16_t wr, const uint16_t bg, const uint16_t wg, const uint16_t bb, const uint16_t wb)
Definition unit_color_utility.hpp:62
uint16_t blackB
Black reference value for blue.
Definition unit_color_utility.hpp:75
uint8_t R8(const Data &d) const
Get the red value with calibration.
Definition unit_color_utility.hpp:79
uint16_t whiteR
White reference value for red.
Definition unit_color_utility.hpp:72
uint16_t whiteG
White reference value for green.
Definition unit_color_utility.hpp:74
Measurement data group.
Definition unit_TCS3472x.hpp:64
uint16_t RnoIR16() const
Gets the raw red value without IR component.
Definition unit_TCS3472x.hpp:90
uint16_t BnoIR16() const
Gets the raw blue value without IR component.
Definition unit_TCS3472x.hpp:100
uint16_t GnoIR16() const
Gets the raw green value without IR component.
Definition unit_TCS3472x.hpp:95
TCS3472x Unit for M5UnitUnified.
Gain
RGBC Gain Control.
Definition unit_TCS3472x.hpp:53
uint16_t calculateSaturation(const uint8_t raw)
Calculate Saturation.
Definition unit_color_utility.cpp:71
float calculateCPL(const float atime_ms, const Gain gc, const float dgf)
Calculate Counts per Lux (CPL)
Definition unit_color_utility.cpp:90
uint8_t ms_to_atime(const float ms)
ms to ATIME
Definition unit_color_utility.hpp:121
float atime_to_ms(const uint8_t a)
ATIME to ms.
Definition unit_color_utility.hpp:109
M5_UNIT_COLOR_UTILITY_UNIT_COLOR_UTILITY_CONSTEXPR std::array< uint8_t, Size > make_gamma_table(const float gamma=2.2f)
Make gamma table.
Definition unit_color_utility.hpp:271
float wtime_to_ms(const uint8_t w, const bool wlong)
WTIME and WLONG to ms.
Definition unit_color_utility.hpp:115
float calculateMaxLux(const float atime_ms, const Gain gc, const float dgf=DGF)
Calculate maximum Lux.
Definition unit_color_utility.hpp:212