44 #include <visp3/core/vpConfig.h>
45 #include <visp3/core/vpImageConvert.h>
59 void vpImageConvert::HSV2RGB(
const double *hue_,
const double *saturation_,
const double *value_,
unsigned char *rgb,
60 unsigned int size,
unsigned int step)
62 int size_ =
static_cast<int>(size);
64 #pragma omp parallel for
66 for (
int i = 0; i < size_; ++i) {
67 double hue = hue_[i], saturation = saturation_[i], value = value_[i];
69 if (
vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
75 double s = saturation;
78 if (
vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
82 double f = h -
static_cast<int>(h);
83 double p = v * (1.0 - s);
84 double q = v * (1.0 - (s * f));
85 double t = v * (1.0 - (s * (1.0 - f)));
87 switch (
static_cast<int>(h)) {
126 int i_step = i * step;
127 rgb[i_step] =
static_cast<unsigned char>(
vpMath::round(hue * 255.0));
128 rgb[++i_step] =
static_cast<unsigned char>(
vpMath::round(saturation * 255.0));
129 rgb[++i_step] =
static_cast<unsigned char>(
vpMath::round(value * 255.0));
130 if ((++i_step) == 3) {
148 void vpImageConvert::HSV2RGB(
const unsigned char *hue_,
const unsigned char *saturation_,
const unsigned char *value_,
149 unsigned char *rgb,
unsigned int size,
unsigned int step,
bool h_full)
158 int size_ =
static_cast<int>(size);
160 #pragma omp parallel for
162 for (
int i = 0; i < size_; ++i) {
163 float hue = hue_[i] / h_max;
164 float saturation = saturation_[i] / 255.f;
165 float value = value_[i] / 255.f;
167 if (
vpMath::equal(saturation, 0.f, std::numeric_limits<float>::epsilon())) {
173 float s = saturation;
176 if (
vpMath::equal(h, 6.f, std::numeric_limits<float>::epsilon())) {
179 float f = h -
static_cast<int>(h);
180 float p = v * (1.0f - s);
181 float q = v * (1.0f - (s * f));
182 float t = v * (1.0f - (s * (1.0f - f)));
184 switch (
static_cast<int>(h)) {
223 int i_step = i * step;
224 rgb[i_step] =
static_cast<unsigned char>(hue * 255.f);
225 rgb[++i_step] =
static_cast<unsigned char>(saturation * 255.0f);
226 rgb[++i_step] =
static_cast<unsigned char>(value * 255.0f);
227 if ((++i_step) == 3) {
246 void vpImageConvert::RGB2HSV(
const unsigned char *rgb,
double *hue,
double *saturation,
double *value,
247 unsigned int size,
unsigned int step)
249 int size_ =
static_cast<int>(size);
251 #pragma omp parallel for
253 for (
int i = 0; i < size_; ++i) {
254 double red, green, blue;
259 red = rgb[i_] / 255.0;
260 green = rgb[++i_] / 255.0;
261 blue = rgb[++i_] / 255.0;
264 max = std::max<double>(red, blue);
265 min = std::min<double>(green, blue);
268 max = std::max<double>(green, blue);
269 min = std::min<double>(red, blue);
274 if (!
vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
275 s = (max - min) / max;
281 if (
vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
285 double delta = max - min;
287 if (
vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
288 h = (green - blue) / delta;
290 else if (
vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
291 h = 2 + ((blue - red) / delta);
294 h = 4 + ((red - green) / delta);
326 void vpImageConvert::RGB2HSV(
const unsigned char *rgb,
unsigned char *hue,
unsigned char *saturation,
unsigned char *value,
327 unsigned int size,
unsigned int step,
bool h_full)
329 int size_ =
static_cast<int>(size);
330 std::vector<float> h_scale(4);
331 const unsigned int index_0 = 0;
332 const unsigned int index_1 = 1;
333 const unsigned int index_2 = 2;
334 const unsigned int index_3 = 3;
336 h_scale[index_0] = 42.5f;
337 h_scale[index_1] = 85.f;
338 h_scale[index_2] = 170.f;
339 h_scale[index_3] = 255.f;
342 h_scale[index_0] = 30.f;
343 h_scale[index_1] = 60.f;
344 h_scale[index_2] = 120.f;
345 h_scale[index_3] = 180.f;
348 #pragma omp parallel for
350 for (
int i = 0; i < size_; ++i) {
351 float red, green, blue;
354 unsigned int i_ = i * step;
361 max = std::max<float>(red, blue);
362 min = std::min<float>(green, blue);
365 max = std::max<float>(green, blue);
366 min = std::min<float>(red, blue);
371 if (!
vpMath::equal(max, 0.f, std::numeric_limits<float>::epsilon())) {
372 s = (255.f * (max - min)) / max;
378 if (
vpMath::equal(s, 0.f, std::numeric_limits<float>::epsilon())) {
382 float delta = max - min;
384 if (
vpMath::equal(red, max, std::numeric_limits<float>::epsilon())) {
385 h = (h_scale[index_0] * (green - blue)) / delta;
387 else if (
vpMath::equal(green, max, std::numeric_limits<float>::epsilon())) {
388 h = h_scale[index_1] + ((h_scale[index_0] * (blue - red)) / delta);
391 h = h_scale[index_2] + ((h_scale[index_0] * (red - green)) / delta);
395 h += h_scale[index_3];
399 hue[i] =
static_cast<unsigned char>(h);
400 saturation[i] =
static_cast<unsigned char>(s);
401 value[i] =
static_cast<unsigned char>(v);
421 vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
439 unsigned char *rgba,
unsigned int size,
bool h_full)
441 vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4, h_full);
460 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
480 unsigned char *value,
unsigned int size,
bool h_full)
482 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4, h_full);
501 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
519 unsigned char *rgb,
unsigned int size,
bool h_full)
521 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3, h_full);
539 vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
558 unsigned char *value,
unsigned int size,
bool h_full)
560 vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3, h_full);
static void HSVToRGBa(const double *hue, const double *saturation, const double *value, unsigned char *rgba, unsigned int size)
static void RGBToHSV(const unsigned char *rgb, double *hue, double *saturation, double *value, unsigned int size)
static void RGBaToHSV(const unsigned char *rgba, double *hue, double *saturation, double *value, unsigned int size)
static void HSVToRGB(const double *hue, const double *saturation, const double *value, unsigned char *rgb, unsigned int size)
static bool equal(double x, double y, double threshold=0.001)
static int round(double x)