开发环境:Ubuntu 18.04 LTS + ROS Melodic + ViSP 3.3.1
文章内容主要参考ViSP官方教学文档:https://visp-doc.inria.fr/doxygen/visp-daily/tutorial_mainpage.html

 本文主要介绍了如何使用ViSP来调整图像的明度和对比度,主要涉及四种内置的调整算法:线性调整,伽马修正,正方图均衡和Retinex算法。本文主要参考了imgproc中的 tutorial-brightness-adjustment.cpp 例程。首先还是下载和编译例程

svn export https://github.com/lagadic/visp.git/trunk/tutorial/imgproc
cd imgproc/brightness
mkdir build
cd build 
cmake .. -DCMAKE_BUILD_TYPE=Release -DVISP_DIR=$VISP_WS/visp-build
make 

 执行例程,查看效果

./tutorial-brightness-adjustment

左图是原图,右图是执行线性调整后的结果

在这里插入图片描述
  伽马修正的结果

在这里插入图片描述

直方图均衡后的结果
在这里插入图片描述
  Retinex调整后的结果

在这里插入图片描述

 我们来看一下程序的实现过程

#include <cstdlib>
#include <iostream>
#include <visp3/core/vpImage.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/io/vpImageIo.h>

#if defined(VISP_HAVE_MODULE_IMGPROC)
//! [Include]
#include <visp3/imgproc/vpImgproc.h>
//! [Include]
#endif

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]
  //!
  std::string input_filename = "Sample_low_brightness.png"; //设置默认输入图像的名称
  double alpha = 10.0, beta = 50.0;  // 设置线性调整的默认参数
  double gamma = 3.5;  //设置伽马修正的默认参数
  int scale = 240, scaleDiv = 3, level = 0, kernelSize = -1;  //设置Retinex算法的默认参数
  double dynamic = 3.0;  //设置Retinex算法的默认参数

  for (int i = 1; i < argc; i++) {
    if (std::string(argv[i]) == "--input" && i + 1 < argc) {
      input_filename = std::string(argv[i + 1]); //通过--input指令来设置输入图像的名称
    } else if (std::string(argv[i]) == "--alpha" && i + 1 < argc) {
      alpha = atof(argv[i + 1]);  //设置线性调整参数
    } else if (std::string(argv[i]) == "--beta" && i + 1 < argc) {
      beta = atof(argv[i + 1]);  //设置线性调整参数
    } else if (std::string(argv[i]) == "--gamma" && i + 1 < argc) {
      gamma = atof(argv[i + 1]); //设置伽马修正参数
    } else if (std::string(argv[i]) == "--scale" && i + 1 < argc) {
      scale = atoi(argv[i + 1]);  //设置Retinex算法参数
    } else if (std::string(argv[i]) == "--scaleDiv" && i + 1 < argc) {
      scaleDiv = atoi(argv[i + 1]);  //设置Retinex算法参数
    } else if (std::string(argv[i]) == "--level" && i + 1 < argc) {
      level = atoi(argv[i + 1]);  //设置Retinex算法参数
    } else if (std::string(argv[i]) == "--kernelSize" && i + 1 < argc) {
      kernelSize = atoi(argv[i + 1]);  //设置Retinex算法参数
    } else if (std::string(argv[i]) == "--dynamic" && i + 1 < argc) {
      dynamic = atof(argv[i + 1]);  //设置Retinex算法参数
    } else if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h") {
      std::cout << "Usage: " << argv[0]
                << " [--input <input image>]"
                   " [--alpha <alpha for vp::adjust()>] [--beta <beta for "
                   "vp::adjust()>]"
                   " [--gamma <gamma for vp::gammaCorrection()>]"
                   " [--scale <scale for vp::retinex()> [--scaleDiv for "
                   "vp::retinex()]"
                   " [--level <level for vp::retinex()> [--kernelSize "
                   "<kernelSize for vp::retinex()>]"
                   " [--dynamic <dynamic for vp::retinex()>] [--help]"
                << std::endl;
      return EXIT_SUCCESS;
    }
  }

  vpImage<vpRGBa> I_color;  //新建彩色图像容器,用于储存输入图像
  vpImageIo::read(I_color, input_filename);  //读取输入图像

  vpImage<vpRGBa> I_color_res(I_color.getHeight(), 2 * I_color.getWidth()); 
  //新建一个彩色图像容器,宽度为两个输入图像的宽度,用于储存输入图像和处理后的图像
  I_color_res.insert(I_color, vpImagePoint()); //把输入图像插入到图像容器中
#ifdef VISP_HAVE_X11
  vpDisplayX d(I_color_res);
#elif defined(VISP_HAVE_GDI)
  vpDisplayGDI d(I_color_res);
#elif defined(VISP_HAVE_OPENCV)
  vpDisplayOpenCV d(I_color_res);
#endif

  //! [Brightness contrast adjustment]
  vpImage<vpRGBa> I_color_adjust; //新建彩色图像容器,用于储存处理后的图像
  vp::adjust(I_color, I_color_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);

  //! [Gamma correction]
  vpImage<vpRGBa> I_color_gamma_correction;
  vp::gammaCorrection(I_color, I_color_gamma_correction, gamma); //使用伽马修正算法处理图像
  //! [Gamma correction]
  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);

  //! [Histogram equalization]
  vpImage<vpRGBa> I_color_equalize_histogram;
  vp::equalizeHistogram(I_color, I_color_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);

  //! [Retinex]
  vpImage<vpRGBa> I_color_retinex;
  vp::retinex(I_color, I_color_retinex, scale, scaleDiv, level, dynamic, kernelSize);
  //! [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
     << "_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);

  return EXIT_SUCCESS;
#else
  (void)argc;
  (void)argv;
  return 0;
#endif
}

如果大家对于深度学习与计算机视觉领域感兴趣,希望获得更多的知识分享与最新的论文解读,欢迎关注我的个人公众号“深视”。

在这里插入图片描述