#include "opencv2/core/utility.hpp" // 包含OpenCV核心工具库的头文件
#include "opencv2/imgproc.hpp" // 包含OpenCV图像处理的头文件
#include "opencv2/imgcodecs.hpp" // 包含OpenCV图像编码解码的头文件
#include "opencv2/highgui.hpp" // 包含OpenCV高层GUI(图形用户界面)的头文件
#include <iostream> // 包含标准输入输出流的头文件
// 使用命名空间cv和std,避免每次调用OpenCV和标准库函数时都需要前缀
using namespace cv;
using namespace std;
// 全局变量,分别用于存储亮度和对比度的值
int _brightness = 100;
int _contrast = 100;
Mat image; // 全局变量,用于存储图像矩阵
/* 亮度/对比度调整回调函数 */
static void updateBrightnessContrast( int /*arg*/, void* )
{
int histSize = 64; // 定义直方图的大小
int brightness = _brightness - 100; // 计算新的亮度值
int contrast = _contrast - 100; // 计算新的对比度值
/*
* 使用Werner D. Streidt的算法来调整亮度和对比度
* (参见http://visca.com/ffactory/archives/5-99/msg00021.html)
*/
double a, b;
if( contrast > 0 )
{
double delta = 127.*contrast/100; // 计算对比度增量
a = 255./(255. - delta*2); // 根据对比度增量计算系数a
b = a*(brightness - delta); // 根据对比度增量和亮度计算系数b
}
else
{
double delta = -128.*contrast/100; // 计算对比度减量
a = (256.-delta*2)/255.; // 根据对比度减量计算系数a
b = a*brightness + delta; // 根据对比度减量和亮度计算系数b
}
Mat dst, hist; // 定义目标图像和直方图矩阵
image.convertTo(dst, CV_8U, a, b); // 应用亮度和对比度的调整并转换图像格式
imshow("image", dst); // 显示调整后的图像
// 计算调整后图像的直方图
calcHist(&dst, 1, 0, Mat(), hist, 1, &histSize, 0);
Mat histImage = Mat::ones(200, 320, CV_8U)*255; // 创建直方图的图像
// 对直方图进行归一化操作
normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, CV_32F);
histImage = Scalar::all(255); // 设置直方图图像的背景为白色
int binW = cvRound((double)histImage.cols/histSize); // 计算每个bin的宽度
// 绘制直方图
for( int i = 0; i < histSize; i++ )
rectangle( histImage, Point(i*binW, histImage.rows),
Point((i+1)*binW, histImage.rows - cvRound(hist.at<float>(i))),
Scalar::all(0), -1, 8, 0 );
imshow("histogram", histImage); // 显示直方图
}
// keys字符串定义了程序可以接受的命令行参数
const char* keys =
{
"{help h||}{@image|baboon.jpg|input image file}"
};
// 程序主函数
int main( int argc, const char** argv )
{
CommandLineParser parser(argc, argv, keys); // 创建命令行参数解析器
parser.about("\nThis program demonstrates the use of calcHist() -- histogram creation.\n");
if (parser.has("help")) // 如果提供了帮助标志,则打印帮助信息
{
parser.printMessage();
return 0;
}
string inputImage = parser.get<string>(0); // 获取输入的图像文件
// 读取源图像,使用高级GUI
image = imread(samples::findFile(inputImage), IMREAD_GRAYSCALE); // 以灰度模式读取图像
if(image.empty()) // 如果读取图像失败,则打印错误信息并退出
{
std::cerr << "Cannot read image file: " << inputImage << std::endl;
return -1;
}
// 创建显示窗口
namedWindow("image", 0);
namedWindow("histogram", 0);
// 创建轨迹条以调整亮度和对比度,并设置回调函数
createTrackbar("brightness", "image", &_brightness, 200, updateBrightnessContrast);
createTrackbar("contrast", "image", &_contrast, 200, updateBrightnessContrast);
// 使用默认值更新亮度和对比度
updateBrightnessContrast(0, 0);
waitKey(); // 等待用户按键
return 0; // 程序正常退出
}
这段代码是使用C++和OpenCV库编写的图像处理程序,其主要功能是调整图像的亮度和对比度,并在GUI窗口中实时显示调整后的图像以及其直方图。用户可以通过界面上的滑动条来动态地调整亮度和对比度参数从而观察到图像即时的变化效果。程序首先读取并显示一个灰度图像,然后响应用户的交互输入来更新图像显示和直方图。
image.convertTo(dst, CV_8U, a, b);
calcHist(&dst, 1, 0, Mat(), hist, 1, &histSize, 0);
normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, CV_32F);