UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
delta_e.hpp
1
45#ifndef UFO_VISION_COLOR_DELTA_E_HPP
46#define UFO_VISION_COLOR_DELTA_E_HPP
47
48// UFO
49#include <ufo/utility/type_traits.hpp>
50#include <ufo/vision/color/concepts.hpp>
51#include <ufo/vision/color/convert.hpp>
52#include <ufo/vision/color/space.hpp>
53#include <ufo/vision/color/type_traits.hpp>
54
55// STL
56#include <cassert>
57#include <cmath>
58
59namespace ufo
60{
66enum class ColorDeltaE {
67 EUCLIDEAN,
68 // CIE76,
69 // CMC,
70 // CIE94,
71 // CIEDE2000
72 OK,
73};
74
85template <Color C>
86[[nodiscard]] constexpr float deltaEEuclideanSquared(C const& color, C const& sample)
87{
88 using F = typename color_traits<C>::template rebind<float, ColorFlags::None>;
89
90 auto const c = convert<F>(color);
91 auto const s = convert<F>(sample);
92
93 if constexpr (GrayColor<C>) {
94 float const dg = c.gray - s.gray;
95 return dg * dg;
96 } else if constexpr (RgbFamilyColor<C>) {
97 float const dr = c.red - s.red;
98 float const dg = c.green - s.green;
99 float const db = c.blue - s.blue;
100 return dr * dr + dg * dg + db * db;
101 } else if constexpr (LabColor<C>) {
102 float const dl = c.lightness - s.lightness;
103 float const da = c.a - s.a;
104 float const db = c.b - s.b;
105 return dl * dl + da * da + db * db;
106 } else if constexpr (LchColor<C>) {
107 float const dl = c.lightness - s.lightness;
108 float const dc = c.chroma - s.chroma;
109 float const dh = c.hue - s.hue;
110 return dl * dl + dc * dc + dh * dh;
111 } else {
112 static_assert(dependent_false_v<C>, "Unknown color model");
113 }
114}
115
123template <Color C>
124[[nodiscard]] constexpr float deltaEEuclidean(C const& color, C const& sample)
125{
126 return std::sqrt(deltaEEuclideanSquared(color, sample));
127}
128
137template <Color C>
138[[nodiscard]] constexpr float deltaEOkSquared(C const& color, C const& sample,
139 float const ab_scale = 2.0f)
140{
141 auto const c = convert<FineLab>(color);
142 auto const s = convert<FineLab>(sample);
143
144 float const dl = c.lightness - s.lightness;
145 float const da = ab_scale * (c.a - s.a);
146 float const db = ab_scale * (c.b - s.b);
147 return dl * dl + da * da + db * db;
148}
149
158template <Color C>
159[[nodiscard]] constexpr float deltaEOk(C const& color, C const& sample,
160 float const ab_scale = 2.0f)
161{
162 return std::sqrt(deltaEOkSquared(color, sample, ab_scale));
163}
164
174template <Color C>
175[[nodiscard]] constexpr float deltaESquared(C const& color, C const& sample,
176 ColorDeltaE method = ColorDeltaE::EUCLIDEAN,
177 ColorSpace space = ColorSpace::NATIVE)
178{
179 if (ColorDeltaE::OK == method || ColorSpace::Oklab2 == space) {
180 return deltaEOkSquared(color, sample);
181 }
182
183 switch (space) {
184 case ColorSpace::NATIVE: return deltaEEuclideanSquared(color, sample);
185 case ColorSpace::Rgb:
186 return deltaEEuclideanSquared(convert<FineRgb>(color), convert<FineRgb>(sample));
187 case ColorSpace::Oklab:
188 return deltaEEuclideanSquared(convert<FineLab>(color), convert<FineLab>(sample));
189 case ColorSpace::Oklch:
190 return deltaEEuclideanSquared(convert<FineLch>(color), convert<FineLch>(sample));
191 default: break;
192 }
193
194 assert(false && "Not implemented.");
195 return 0.0f;
196}
197
207template <Color C>
208[[nodiscard]] constexpr float deltaE(C const& color, C const& sample,
209 ColorDeltaE method = ColorDeltaE::EUCLIDEAN,
210 ColorSpace space = ColorSpace::NATIVE)
211{
212 return std::sqrt(deltaESquared(color, sample, method, space));
213}
214
218} // namespace ufo
219
220#endif // UFO_VISION_COLOR_DELTA_E_HPP
Grayscale colors (Gray<T, Flags>).
Definition concepts.hpp:133
Oklab perceptual colors (Lab<T, Flags>).
Definition concepts.hpp:151
OkLch cylindrical colors (Lch<T, Flags>).
Definition concepts.hpp:157
Rgb-family colors (gamma-encoded or linear: Rgb or Lrgb).
Definition concepts.hpp:169
constexpr float deltaE(C const &color, C const &sample, ColorDeltaE method=ColorDeltaE::EUCLIDEAN, ColorSpace space=ColorSpace::NATIVE)
Computes the distance between two colors using a specified method.
Definition delta_e.hpp:208
constexpr float deltaESquared(C const &color, C const &sample, ColorDeltaE method=ColorDeltaE::EUCLIDEAN, ColorSpace space=ColorSpace::NATIVE)
Computes the squared distance between two colors using a specified method.
Definition delta_e.hpp:175
constexpr float deltaEEuclidean(C const &color, C const &sample)
Computes the Euclidean distance between two colors.
Definition delta_e.hpp:124
ColorSpace
Selects the working color space for color operations.
Definition space.hpp:71
constexpr float deltaEOk(C const &color, C const &sample, float const ab_scale=2.0f)
Computes the Ok delta E distance between two colors.
Definition delta_e.hpp:159
constexpr float deltaEOkSquared(C const &color, C const &sample, float const ab_scale=2.0f)
Computes the squared Ok delta E distance between two colors.
Definition delta_e.hpp:138
constexpr float deltaEEuclideanSquared(C const &color, C const &sample)
Computes the squared Euclidean distance between two colors.
Definition delta_e.hpp:86
All vision-related classes and functions.
Definition cloud.hpp:49
Primary template - intentionally undefined.