43#include <visp3/core/vpConfig.h>
44#include <visp3/core/vpImageConvert.h>
58 void vpImageConvert::HSV2RGB(
const double *hue_,
const double *saturation_,
const double *value_,
unsigned char *rgb,
59 unsigned int size,
unsigned int step)
61 int size_ =
static_cast<int>(size);
63#pragma omp parallel for
65 for (
int i = 0;
i < size_; ++
i) {
66 double hue = hue_[
i], saturation = saturation_[
i], value = value_[
i];
68 if (
vpMath::equal(saturation, 0.0, std::numeric_limits<double>::epsilon())) {
74 double s = saturation;
77 if (
vpMath::equal(h, 6.0, std::numeric_limits<double>::epsilon())) {
81 double f =
h -
static_cast<int>(
h);
82 double p =
v * (1.0 -
s);
83 double q =
v * (1.0 - (
s * f));
84 double t =
v * (1.0 - (
s * (1.0 - f)));
89 switch (
static_cast<int>(h)) {
128 unsigned int i_step =
static_cast<unsigned int>(
i) * step;
129 rgb[i_step] =
static_cast<unsigned char>(
vpMath::round(hue * 255.0));
130 rgb[++i_step] =
static_cast<unsigned char>(
vpMath::round(saturation * 255.0));
131 rgb[++i_step] =
static_cast<unsigned char>(
vpMath::round(value * 255.0));
133 if (i_step == val_3) {
152void vpImageConvert::HSV2RGB(
const unsigned char *hue_,
const unsigned char *saturation_,
const unsigned char *value_,
153 unsigned char *rgb,
unsigned int size,
unsigned int step,
bool h_full)
165 int size_ =
static_cast<int>(size);
167#pragma omp parallel for
169 for (
int i = 0;
i < size_; ++
i) {
170 float hue = hue_[
i] / h_max;
171 float saturation = saturation_[
i] / 255.f;
172 float value = value_[
i] / 255.f;
174 if (
vpMath::equal(saturation, 0.f, std::numeric_limits<float>::epsilon())) {
180 float s = saturation;
183 if (
vpMath::equal(h, 6.f, std::numeric_limits<float>::epsilon())) {
186 float f =
h -
static_cast<float>(
static_cast<int>(
h));
187 float p =
v * (1.0f -
s);
188 float q =
v * (1.0f - (
s * f));
189 float t =
v * (1.0f - (
s * (1.0f - f)));
191 switch (
static_cast<int>(h)) {
230 unsigned int i_step =
static_cast<unsigned int>(
i) * step;
231 rgb[i_step] =
static_cast<unsigned char>(hue * 255.f);
232 rgb[++i_step] =
static_cast<unsigned char>(saturation * 255.0f);
233 rgb[++i_step] =
static_cast<unsigned char>(value * 255.0f);
234 if (i_step == val_3) {
254void vpImageConvert::RGB2HSV(
const unsigned char *rgb,
double *hue,
double *saturation,
double *value,
255 unsigned int size,
unsigned int step)
257 int size_ =
static_cast<int>(size);
258 int step_ =
static_cast<int>(
step);
260#pragma omp parallel for
262 for (
int i = 0;
i < size_; ++
i) {
263 double red, green, blue;
268 red = rgb[i_] / 255.0;
270 green = rgb[i_] / 255.0;
272 blue = rgb[i_] / 255.0;
275 max = std::max<double>(red, blue);
276 min = std::min<double>(green, blue);
279 max = std::max<double>(green, blue);
280 min = std::min<double>(red, blue);
285 if (!
vpMath::equal(max, 0.0, std::numeric_limits<double>::epsilon())) {
286 s = (max - min) / max;
292 if (
vpMath::equal(s, 0.0, std::numeric_limits<double>::epsilon())) {
296 double delta = max - min;
298 if (
vpMath::equal(red, max, std::numeric_limits<double>::epsilon())) {
299 h = (green - blue) / delta;
301 else if (
vpMath::equal(green, max, std::numeric_limits<double>::epsilon())) {
302 h = 2.0 + ((blue - red) / delta);
305 h = 4.0 + ((red - green) / delta);
337void vpImageConvert::RGB2HSV(
const unsigned char *rgb,
unsigned char *hue,
unsigned char *saturation,
unsigned char *value,
338 unsigned int size,
unsigned int step,
bool h_full)
340 int size_ =
static_cast<int>(size);
341 std::vector<float> h_scale(4);
342 const unsigned int index_0 = 0;
343 const unsigned int index_1 = 1;
344 const unsigned int index_2 = 2;
345 const unsigned int index_3 = 3;
347 h_scale[index_0] = 42.5f;
348 h_scale[index_1] = 85.f;
349 h_scale[index_2] = 170.f;
350 h_scale[index_3] = 255.f;
353 h_scale[index_0] = 30.f;
354 h_scale[index_1] = 60.f;
355 h_scale[index_2] = 120.f;
356 h_scale[index_3] = 180.f;
359#pragma omp parallel for
361 for (
int i = 0;
i < size_; ++
i) {
362 float red, green, blue;
365 unsigned int i_ =
static_cast<unsigned int>(
i) * step;
372 max = std::max<float>(red, blue);
373 min = std::min<float>(green, blue);
376 max = std::max<float>(green, blue);
377 min = std::min<float>(red, blue);
382 if (!
vpMath::equal(max, 0.f, std::numeric_limits<float>::epsilon())) {
383 s = (255.f * (max - min)) / max;
389 if (
vpMath::equal(s, 0.f, std::numeric_limits<float>::epsilon())) {
393 float delta = max - min;
395 if (
vpMath::equal(red, max, std::numeric_limits<float>::epsilon())) {
396 h = (h_scale[index_0] * (green - blue)) / delta;
398 else if (
vpMath::equal(green, max, std::numeric_limits<float>::epsilon())) {
399 h = h_scale[index_1] + ((h_scale[index_0] * (blue - red)) / delta);
402 h = h_scale[index_2] + ((h_scale[index_0] * (red - green)) / delta);
406 h += h_scale[index_3];
410 hue[
i] =
static_cast<unsigned char>(
h);
411 saturation[
i] =
static_cast<unsigned char>(
s);
412 value[
i] =
static_cast<unsigned char>(
v);
432 const unsigned int val_4 = 4;
433 vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, val_4);
451 unsigned char *rgba,
unsigned int size,
bool h_full)
453 const unsigned int val_4 = 4;
454 vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, val_4, h_full);
475 const unsigned int val_4 = 4;
476 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, val_4);
497 unsigned char *value,
unsigned int size,
bool h_full)
499 const unsigned int val_4 = 4;
500 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, val_4, h_full);
519 const unsigned int val_3 = 3;
520 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, val_3);
538 unsigned char *rgb,
unsigned int size,
bool h_full)
540 const unsigned int val_3 = 3;
541 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, val_3, h_full);
559 const unsigned int val_3 = 3;
560 vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, val_3);
579 unsigned char *value,
unsigned int size,
bool h_full)
581 const unsigned int val_3 = 3;
582 vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, val_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)