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)));
90 switch (
static_cast<int>(h)) {
129 int i_step = i * step;
130 rgb[i_step] =
static_cast<unsigned char>(
vpMath::round(hue * 255.0));
131 rgb[++i_step] =
static_cast<unsigned char>(
vpMath::round(saturation * 255.0));
132 rgb[++i_step] =
static_cast<unsigned char>(
vpMath::round(value * 255.0));
134 if (i_step == val_3) {
153 void vpImageConvert::HSV2RGB(
const unsigned char *hue_,
const unsigned char *saturation_,
const unsigned char *value_,
154 unsigned char *rgb,
unsigned int size,
unsigned int step,
bool h_full)
166 int size_ =
static_cast<int>(size);
168 #pragma omp parallel for
170 for (
int i = 0; i < size_; ++i) {
171 float hue = hue_[i] / h_max;
172 float saturation = saturation_[i] / 255.f;
173 float value = value_[i] / 255.f;
175 if (
vpMath::equal(saturation, 0.f, std::numeric_limits<float>::epsilon())) {
181 float s = saturation;
184 if (
vpMath::equal(h, 6.f, std::numeric_limits<float>::epsilon())) {
187 float f = h -
static_cast<int>(h);
188 float p = v * (1.0f - s);
189 float q = v * (1.0f - (s * f));
190 float t = v * (1.0f - (s * (1.0f - f)));
192 switch (
static_cast<int>(h)) {
231 int i_step = i * step;
232 rgb[i_step] =
static_cast<unsigned char>(hue * 255.f);
233 rgb[++i_step] =
static_cast<unsigned char>(saturation * 255.0f);
234 rgb[++i_step] =
static_cast<unsigned char>(value * 255.0f);
235 if (i_step == val_3) {
255 void vpImageConvert::RGB2HSV(
const unsigned char *rgb,
double *hue,
double *saturation,
double *value,
256 unsigned int size,
unsigned int step)
258 int size_ =
static_cast<int>(size);
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);
337 void 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_ = 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);
473 const unsigned int val_4 = 4;
474 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, val_4);
494 unsigned char *value,
unsigned int size,
bool h_full)
496 const unsigned int val_4 = 4;
497 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, val_4, h_full);
516 const unsigned int val_3 = 3;
517 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, val_3);
535 unsigned char *rgb,
unsigned int size,
bool h_full)
537 const unsigned int val_3 = 3;
538 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, val_3, h_full);
556 const unsigned int val_3 = 3;
557 vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, val_3);
576 unsigned char *value,
unsigned int size,
bool h_full)
578 const unsigned int val_3 = 3;
579 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)