diff --git a/tutorial/imgproc/brightness/tutorial-brightness-adjustment.cpp b/tutorial/imgproc/brightness/tutorial-brightness-adjustment.cpp index f9e63c37c6..9d753a52c8 100644 --- a/tutorial/imgproc/brightness/tutorial-brightness-adjustment.cpp +++ b/tutorial/imgproc/brightness/tutorial-brightness-adjustment.cpp @@ -4,9 +4,7 @@ #include #include #include -#include -#include -#include +#include #include #if defined(VISP_HAVE_MODULE_IMGPROC) @@ -15,14 +13,49 @@ //! [Include] #endif +#if ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L))) +#include +#endif + +namespace +{ +#ifdef ENABLE_VISP_NAMESPACE +using namespace VISP_NAMESPACE_NAME; +#endif + +void display(vpImage &I_display, vpImage &I_color_res, const vpImage &I_color_adjust, + vpImage &I_gray_res, vpImage &I_gray_adjust, vpImage &I_gray_display, + const std::string &title, const std::string &filename_color, const std::string &filename_gray, + const std::string &title_2 = "") +{ + I_color_res.insert(I_color_adjust, vpImagePoint(0, I_color_adjust.getWidth())); + I_display.insert(I_color_adjust, vpImagePoint(0, I_color_adjust.getWidth())); + + I_gray_res.insert(I_gray_adjust, vpImagePoint(0, I_gray_adjust.getWidth())); + vpImageConvert::convert(I_gray_adjust, I_gray_display); + I_display.insert(I_gray_display, vpImagePoint(I_color_adjust.getHeight(), I_color_adjust.getWidth())); + + vpImageIo::write(I_color_res, filename_color); + vpImageIo::write(I_gray_res, filename_gray); + + vpDisplay::display(I_display); + vpDisplay::displayText(I_display, 20, 20, title, vpColor::red); + if (!title_2.empty()) { + vpDisplay::displayText(I_display, 40, static_cast(I_color_adjust.getWidth()*0.85), + title_2, vpColor::green); + } + vpDisplay::flush(I_display); + vpDisplay::getClick(I_display); +} +} + int main(int argc, const char **argv) { -//! [Macro defined] -#if defined(VISP_HAVE_MODULE_IMGPROC) && \ - (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV)) && \ - (defined(VISP_HAVE_PNG) || defined(VISP_HAVE_OPENCV)) //! [Macro defined] - //! +#if defined(VISP_HAVE_MODULE_IMGPROC) && defined(VISP_HAVE_DISPLAY) && \ + (defined(VISP_HAVE_PNG) || defined(VISP_HAVE_OPENCV) || defined(VISP_HAVE_STBIMAGE) || defined(VISP_HAVE_SIMDLIB)) && \ + ((__cplusplus >= 201103L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L))) + //! [Macro defined] #ifdef ENABLE_VISP_NAMESPACE using namespace VISP_NAMESPACE_NAME; #endif @@ -34,19 +67,24 @@ int main(int argc, const char **argv) VISP_NAMESPACE_NAME::vpGammaColorHandling colorHandling = VISP_NAMESPACE_NAME::GAMMA_HSV; int scale = 240, scaleDiv = 3, level = 0, kernelSize = -1; double dynamic = 3.0; + int scale_display = 2; for (int i = 1; i < argc; i++) { if (std::string(argv[i]) == "--input" && i + 1 < argc) { - input_filename = std::string(argv[i + 1]); + ++i; + input_filename = std::string(argv[i]); } else if (std::string(argv[i]) == "--alpha" && i + 1 < argc) { - alpha = atof(argv[i + 1]); + ++i; + alpha = atof(argv[i]); } else if (std::string(argv[i]) == "--beta" && i + 1 < argc) { - beta = atof(argv[i + 1]); + ++i; + beta = atof(argv[i]); } else if (std::string(argv[i]) == "--gamma" && i + 1 < argc) { - gamma = atof(argv[i + 1]); + ++i; + gamma = atof(argv[i]); } else if ((std::string(argv[i]) == "--gamma-color-handling") && ((i + 1) < argc)) { ++i; @@ -57,19 +95,28 @@ int main(int argc, const char **argv) method = VISP_NAMESPACE_NAME::vpGammaMethodFromString(argv[i]); } else if (std::string(argv[i]) == "--scale" && i + 1 < argc) { - scale = atoi(argv[i + 1]); + ++i; + scale = atoi(argv[i]); } else if (std::string(argv[i]) == "--scaleDiv" && i + 1 < argc) { - scaleDiv = atoi(argv[i + 1]); + ++i; + scaleDiv = atoi(argv[i]); } else if (std::string(argv[i]) == "--level" && i + 1 < argc) { - level = atoi(argv[i + 1]); + ++i; + level = atoi(argv[i]); } else if (std::string(argv[i]) == "--kernelSize" && i + 1 < argc) { - kernelSize = atoi(argv[i + 1]); + ++i; + kernelSize = atoi(argv[i]); } else if (std::string(argv[i]) == "--dynamic" && i + 1 < argc) { - dynamic = atof(argv[i + 1]); + ++i; + dynamic = atof(argv[i]); + } + else if (std::string(argv[i]) == "--scale-display" && i + 1 < argc) { + ++i; + scale_display = atoi(argv[i]); } else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") { std::cout << "Usage: " << argv[0] @@ -83,7 +130,9 @@ int main(int argc, const char **argv) "VISP_NAMESPACE_NAME::retinex()]" " [--level [--kernelSize " "]" - " [--dynamic ] [--help]" + " [--dynamic ] " + " [--scale-display ] " + " [--help]" << std::endl; return EXIT_SUCCESS; } @@ -93,35 +142,36 @@ int main(int argc, const char **argv) vpImageIo::read(I_color, input_filename); vpImage I_gray; vpImageConvert::convert(I_color, I_gray); + vpImage I_gray_display; + vpImageConvert::convert(I_gray, I_gray_display); + // Side-by-side images vpImage I_color_res(I_color.getHeight(), 2 * I_color.getWidth()); I_color_res.insert(I_color, vpImagePoint()); vpImage I_gray_res(I_gray.getHeight(), 2 * I_gray.getWidth()); I_gray_res.insert(I_gray, vpImagePoint()); -#ifdef VISP_HAVE_X11 - vpDisplayX d_gray(I_gray_res); - vpDisplayX d(I_color_res); -#elif defined(VISP_HAVE_GDI) - vpDisplayGDI d_gray(I_gray_res); - vpDisplayGDI d(I_color_res); -#elif defined(HAVE_OPENCV_HIGHGUI) - vpDisplayOpenCV d_gray(I_gray_res); - vpDisplayOpenCV d(I_color_res); -#endif + + // Side-by-side display for color (top) and gray (bottom) images + vpImage I_display(2 * I_color.getHeight(), 2 * I_color.getWidth()); + I_display.insert(I_color, vpImagePoint()); + I_display.insert(I_gray_display, vpImagePoint(I_color.getHeight(), 0)); + std::shared_ptr d = vpDisplayFactory::createDisplay(); + d->setDownScalingFactor(static_cast(scale_display)); + d->init(I_display, 10, 10, "Brightness adjustment results"); //! [Brightness contrast adjustment] vpImage I_color_adjust; VISP_NAMESPACE_NAME::adjust(I_color, I_color_adjust, alpha, beta); + vpImage I_gray_adjust; + VISP_NAMESPACE_NAME::adjust(I_gray, I_gray_adjust, alpha, beta); //! [Brightness contrast adjustment] - I_color_res.insert(I_color_adjust, vpImagePoint(0, I_color.getWidth())); - std::stringstream ss; - ss << "Sample_low_brightness_alpha=" << alpha << "_beta=" << beta << ".png"; - vpImageIo::write(I_color_res, ss.str()); - vpDisplay::display(I_color_res); - vpDisplay::displayText(I_color_res, 20, 20, "Brightness and contrast adjustment. Click to continue.", vpColor::red); - vpDisplay::flush(I_color_res); - vpDisplay::getClick(I_color_res); + std::stringstream ss_color; + ss_color << "Sample_low_brightness_adjust_alpha=" << alpha << "_beta=" << beta << ".png"; + std::stringstream ss_gray; + ss_gray << "Sample_low_brightness_adjust_alpha=" << alpha << "_beta=" << beta << "_gray.png"; + display(I_display, I_color_res, I_color_adjust, I_gray_res, I_gray_adjust, I_gray_display, + "Brightness and contrast adjustment. Click to continue.", ss_color.str(), ss_gray.str()); //! [Gamma correction] if (method != VISP_NAMESPACE_NAME::GAMMA_MANUAL) { @@ -133,60 +183,78 @@ int main(int argc, const char **argv) // If the user wants to set a constant user-defined gamma factor, the method must be set to manual. method = VISP_NAMESPACE_NAME::GAMMA_MANUAL; } - vpImage I_gray_gamma_correction; - VISP_NAMESPACE_NAME::gammaCorrection(I_gray, I_gray_gamma_correction, static_cast(gamma), method); vpImage I_color_gamma_correction; VISP_NAMESPACE_NAME::gammaCorrection(I_color, I_color_gamma_correction, static_cast(gamma), colorHandling, method); + vpImage I_gray_gamma_correction; + VISP_NAMESPACE_NAME::gammaCorrection(I_gray, I_gray_gamma_correction, static_cast(gamma), method); //! [Gamma correction] - I_gray_res.insert(I_gray_gamma_correction, vpImagePoint(0, I_gray.getWidth())); - ss.str(""); - ss << "Sample_low_brightness_gray.png"; - vpImageIo::write(I_gray_res, ss.str()); - - vpDisplay::display(I_gray_res); - vpDisplay::displayText(I_gray_res, 20, 20, "Gamma correction on gray image. Click to continue.", vpColor::red); - vpDisplay::flush(I_gray_res); - vpDisplay::getClick(I_gray_res); - - I_color_res.insert(I_color_gamma_correction, vpImagePoint(0, I_color.getWidth())); - ss.str(""); - ss << "Sample_low_brightness_gamma=" << gamma << ".png"; - vpImageIo::write(I_color_res, ss.str()); - - vpDisplay::display(I_color_res); - vpDisplay::displayText(I_color_res, 20, 20, "Gamma correction. Click to continue.", vpColor::red); - vpDisplay::flush(I_color_res); - vpDisplay::getClick(I_color_res); + + ss_color.str(""); + ss_color << "Sample_low_brightness_gamma=" << gamma << ".png"; + ss_gray.str(""); + ss_gray << "Sample_low_brightness_gamma=" << gamma << "_gray.png"; + display(I_display, I_color_res, I_color_gamma_correction, I_gray_res, I_gray_gamma_correction, I_gray_display, + "Gamma correction. Click to continue.", ss_color.str(), ss_gray.str()); + + // Display results for the different Gamma correction method + for (int gamma_idx = 0; gamma_idx < VISP_NAMESPACE_NAME::GAMMA_METHOD_COUNT; ++gamma_idx) { + gamma = -1.; + VISP_NAMESPACE_NAME::vpGammaMethod gamma_method = static_cast(gamma_idx); + if (gamma_method == VISP_NAMESPACE_NAME::GAMMA_MANUAL) { + continue; + } + + vpImage I_color_gamma_correction; + VISP_NAMESPACE_NAME::gammaCorrection(I_color, I_color_gamma_correction, static_cast(gamma), colorHandling, + gamma_method); + vpImage I_gray_gamma_correction; + VISP_NAMESPACE_NAME::gammaCorrection(I_gray, I_gray_gamma_correction, static_cast(gamma), gamma_method); + + const std::string gamma_name = VISP_NAMESPACE_NAME::vpGammaMethodToString(gamma_method); + ss_color.str(""); + ss_color << "Sample_low_brightness_" << gamma_name << ".png"; + ss_gray.str(""); + ss_gray << "Sample_low_brightness_" << gamma_name << "_gray.png"; + display(I_display, I_color_res, I_color_gamma_correction, I_gray_res, I_gray_gamma_correction, I_gray_display, + "Gamma correction. Click to continue.", ss_color.str(), ss_gray.str(), gamma_name); + } //! [Histogram equalization] vpImage I_color_equalize_histogram; VISP_NAMESPACE_NAME::equalizeHistogram(I_color, I_color_equalize_histogram); + vpImage I_gray_equalize_histogram; + VISP_NAMESPACE_NAME::equalizeHistogram(I_gray, I_gray_equalize_histogram); //! [Histogram equalization] - I_color_res.insert(I_color_equalize_histogram, vpImagePoint(0, I_color.getWidth())); - ss.str(""); - ss << "Sample_low_brightness_eqHist.png"; - vpImageIo::write(I_color_res, ss.str()); - vpDisplay::display(I_color_res); - vpDisplay::displayText(I_color_res, 20, 20, "Histogram equalization. Click to continue.", vpColor::red); - vpDisplay::flush(I_color_res); - vpDisplay::getClick(I_color_res); + ss_color.str(""); + ss_color << "Sample_low_brightness_eqHist.png"; + ss_gray.str(""); + ss_gray << "Sample_low_brightness_eqHist_gray.png"; + display(I_display, I_color_res, I_color_equalize_histogram, I_gray_res, I_gray_equalize_histogram, I_gray_display, + "Histogram equalization. Click to continue.", ss_color.str(), ss_gray.str()); //! [Retinex] vpImage I_color_retinex; VISP_NAMESPACE_NAME::retinex(I_color, I_color_retinex, scale, scaleDiv, level, dynamic, kernelSize); + // Retinex uses color image as input + // Convert gray image into RGBa format for quick test + vpImage I_gray_color; + vpImageConvert::convert(I_gray, I_gray_color); + vpImage I_gray_color_retinex; + VISP_NAMESPACE_NAME::retinex(I_gray_color, I_gray_color_retinex, scale, scaleDiv, level, dynamic, kernelSize); + // Convert back to gray + vpImage I_gray_retinex; + vpImageConvert::convert(I_gray_color_retinex, I_gray_retinex); //! [Retinex] - I_color_res.insert(I_color_retinex, vpImagePoint(0, I_color.getWidth())); - ss.str(""); - ss << "Sample_low_brightness_scale=" << scale << "_scaleDiv=" << scaleDiv << "_level=" << level + ss_color.str(""); + ss_color << "Sample_low_brightness_Retinex_scale=" << scale << "_scaleDiv=" << scaleDiv << "_level=" << level << "_dynamic=" << dynamic << "_kernelSize=" << kernelSize << ".png"; - vpImageIo::write(I_color_res, ss.str()); - - vpDisplay::display(I_color_res); - vpDisplay::displayText(I_color_res, 20, 20, "Retinex. Click to quit.", vpColor::red); - vpDisplay::flush(I_color_res); - vpDisplay::getClick(I_color_res); + ss_gray.str(""); + ss_gray << "Sample_low_brightness_Retinex_scale=" << scale << "_scaleDiv=" << scaleDiv << "_level=" << level + << "_dynamic=" << dynamic << "_kernelSize=" << kernelSize << "_gray.png"; + display(I_display, I_color_res, I_color_retinex, I_gray_res, I_gray_retinex, I_gray_display, + "Retinex. Click to quit.", ss_color.str(), ss_gray.str()); #else (void)argc; (void)argv;