#include <iostream>
#include <limits>
#include <visp3/core/vpImage.h>
#include <visp3/core/vpImageConvert.h>
#include <visp3/core/vpRGBa.h>
#include <visp3/core/vpHSV.h>
#include "hsvUtils.h"
#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
#ifdef ENABLE_VISP_NAMESPACE
#endif
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template<typename Type, bool useFullScale >
bool test_rgb(
const vpRGBa &rgb_computed,
const vpRGBa &rgb_truth,
{
if ((rgb_computed.
R != rgb_truth.
R) ||
(rgb_computed.
G != rgb_truth.
G) ||
(rgb_computed.
B != rgb_truth.
B)) {
std::cout << static_cast<int>(hsv_truth.
H) <<
","
<<
static_cast<int>(hsv_truth.
S) <<
","
<<
static_cast<int>(hsv_truth.
V) <<
"): Expected RGB value: ("
<<
static_cast<int>(rgb_truth.
R) <<
","
<<
static_cast<int>(rgb_truth.
G) <<
","
<<
static_cast<int>(rgb_truth.
B) <<
") converted value: ("
<<
static_cast<int>(rgb_computed.
R) <<
","
<<
static_cast<int>(rgb_computed.
G) <<
","
<<
static_cast<int>(rgb_computed.
B) <<
")" << std::endl;
return false;
}
return true;
}
#endif
int main()
{
bool isSuccess = true;
std::vector< vpColVector> rgb_truth;
double h_max;
bool h_full;
size_t size = rgb_truth.size();
for (size_t test = 0; test < 2; ++test) {
if (test == 0) {
h_max = 255;
h_full = true;
}
else {
h_full = false;
}
std::vector< vpColVector > hsv_truth;
hsv_truth.emplace_back(std::vector<double>({ 0., 0., 0. }));
hsv_truth.emplace_back(std::vector<double>({ 0., 0., 255. }));
hsv_truth.emplace_back(std::vector<double>({ 0., 255., 255. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 120. / 360., 255., 255. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 240. / 360., 255., 255. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 60. / 360., 255., 255. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 180. / 360., 255., 255. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 300. / 360., 255., 255. }));
hsv_truth.emplace_back(std::vector<double>({ 0., 0., 128. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 60. / 360., 255., 128. }));
hsv_truth.emplace_back(std::vector<double>({ 0., 255., 128. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 120. / 360., 255., 128. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 180. / 360., 255., 128. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 240. / 360., 255., 128. }));
hsv_truth.emplace_back(std::vector<double>({ h_max * 300. / 360., 255., 128. }));
std::cout << std::endl << "----- Test hsv (unsigned char) -> rgba conversion with h full scale: " << (h_full ? "yes" : "no") << " -----" << std::endl;
for (unsigned int id = 0; id < size; ++id) {
vpRGBa rgba_truth(rgb_truth[
id]);
if (h_full) {
std::cout << "Running the test for H = " << hsv_truth[id][0] << " ..." << std::endl;
vpHSV<unsigned char, true> hsv(
static_cast<unsigned char>(hsv_truth[
id][0]),
static_cast<unsigned char>(hsv_truth[
id][1]),
static_cast<unsigned char>(hsv_truth[
id][2]));
isSuccess = isSuccess && test_rgb(rgba, rgba_truth, hsv);
}
}
else {
std::cout << "Running the test for H = " << hsv_truth[id][0] << " ..." << std::endl;
vpHSV<unsigned char, false> hsv(
static_cast<unsigned char>(hsv_truth[
id][0]),
static_cast<unsigned char>(hsv_truth[
id][1]),
static_cast<unsigned char>(hsv_truth[
id][2]));
isSuccess = isSuccess && test_rgb(rgba, rgba_truth, hsv);
}
}
}
if (h_full) {
std::cout << std::endl << "----- Test hsv (double) -> rgba conversion -----" << std::endl;
for (unsigned int id = 0; id < size; ++id) {
vpRGBa rgba_truth(rgb_truth[
id]);
std::cout << "Running the test for HSV = " << hsv_truth[id][0] << " ; " << hsv_truth[id][1] << "; " << hsv_truth[id][2] << " ..." << std::endl;
for (unsigned char c = 0; c < vpHSV<double>::nbChannels; ++c) {
hsv_vec[c] = hsv_vec[c] / 255.;
}
isSuccess = isSuccess && test_rgb(rgba, rgba_truth, hsv);
}
}
}
std::cout << std::endl << "----- Testing vpImageConvert::convert(vpImage<vpHSV>, vpImage<vpRGBa>) conversions -----" << std::endl;
bool localSuccess = vpHSVTests::areAlmostEqual(Irgb, "Irgb", Irgb_truth, "Irgb_truth");
if (!localSuccess) {
std::cerr << "vpImageConvert(hsv<uchar, false>, rgba) failed!" << std::endl;
}
isSuccess = isSuccess && localSuccess;
localSuccess = vpHSVTests::areAlmostEqual(Irgb, "Irgb", Irgb_truth, "Irgb_truth");
if (!localSuccess) {
std::cerr << "vpImageConvert(hsv<uchar, true>, rgba) failed!" << std::endl;
}
isSuccess = isSuccess && localSuccess;
localSuccess = vpHSVTests::areAlmostEqual(Irgb, "Irgb", Irgb_truth, "Irgb_truth");
if (!localSuccess) {
std::cerr << "vpImageConvert(hsv<double>, rgba) failed!" << std::endl;
}
isSuccess = isSuccess && localSuccess;
if (isSuccess) {
std::cout << "All tests were successful !" << std::endl;
return EXIT_SUCCESS;
}
std::cerr << "ERROR: Something went wrong !" << std::endl;
return EXIT_FAILURE;
}
#else
int main()
{
std::cout << "vpHSV class is not available, please use CXX 11 standard" << std::endl;
return EXIT_SUCCESS;
}
#endif
Implementation of column vector and the associated operations.
Class implementing the HSV pixel format.
static constexpr unsigned char maxHueUsingLimitedRange
Maximum value of the Hue channel when using unsigned char and the limited range.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Definition of the vpImage class member functions.
static int round(double x)
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.