开发环境: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
}
如果大家对于深度学习与计算机视觉领域感兴趣,希望获得更多的知识分享与最新的论文解读,欢迎关注我的个人公众号“深视”。
评论(0)
您还未登录,请登录后发表或查看评论