45 #include <visp3/core/vpConfig.h>
46 #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);
344 #pragma omp parallel for
346 for (
int i = 0; i < size_; ++i) {
347 float red, green, blue;
350 unsigned int i_ = i * step;
357 max = std::max<float>(red, blue);
358 min = std::min<float>(green, blue);
361 max = std::max<float>(green, blue);
362 min = std::min<float>(red, blue);
367 if (!
vpMath::equal(max, 0.f, std::numeric_limits<float>::epsilon())) {
368 s = (255.f * (max - min)) / max;
374 if (
vpMath::equal(s, 0.f, std::numeric_limits<float>::epsilon())) {
378 float delta = max - min;
380 if (
vpMath::equal(red, max, std::numeric_limits<float>::epsilon())) {
381 h = (h_scale[0] * (green - blue)) / delta;
383 else if (
vpMath::equal(green, max, std::numeric_limits<float>::epsilon())) {
384 h = h_scale[1] + ((h_scale[0] * (blue - red)) / delta);
387 h = h_scale[2] + ((h_scale[0] * (red - green)) / delta);
395 hue[i] =
static_cast<unsigned char>(h);
396 saturation[i] =
static_cast<unsigned char>(s);
397 value[i] =
static_cast<unsigned char>(v);
417 vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4);
435 unsigned char *rgba,
unsigned int size,
bool h_full)
437 vpImageConvert::HSV2RGB(hue, saturation, value, rgba, size, 4, h_full);
456 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4);
476 unsigned char *value,
unsigned int size,
bool h_full)
478 vpImageConvert::RGB2HSV(rgba, hue, saturation, value, size, 4, h_full);
497 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3);
515 unsigned char *rgb,
unsigned int size,
bool h_full)
517 vpImageConvert::HSV2RGB(hue, saturation, value, rgb, size, 3, h_full);
535 vpImageConvert::RGB2HSV(rgb, hue, saturation, value, size, 3);
554 unsigned char *value,
unsigned int size,
bool h_full)
556 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)