图像对比度和亮度的公式为
其中,f(x)表示源图像像素,g(x)表示输出图像像素,参数a(a>0)(增益)和b (偏置)常常被用来控制图像的对比度和亮度。可以使用 Mat 的 convertTo 函数对帧图像进行对比度和亮度的调节。
frame.convertTo(adjustedFrame, -1, contrast, brightness);
注意这里的对比度增强并没有使得暗处更暗 。当对比度增强的时候,所有的像素都会变亮,但是本来就亮的像素点提升的幅度更大(斜率决定)。
完整代码:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
VideoCapture cap;
Mat frame;
bool isPlaying = true;
double fps;
int totalFrames;
int currentFrame = 0;
double brightness = 0.0;
double contrast = 1.0;
void onTrackbarProgress(int pos, void* userdata) {
cap.set(CAP_PROP_POS_FRAMES, pos);
currentFrame = pos;
}
void onTrackbarBright(int pos, void* userdata) {
brightness = pos - 50; // 亮度参数映射到[-50, 50], 大于0变亮,小于0变暗
}
void onTrackbarContrast(int pos, void* userdata) {
contrast = pos / 100.0;// 对比度参数映射到[0, 3],大于1对比增强,小于1对比减弱
}
int main() {
string path = "D://course//DigitalVideoProcess//labs//lab3//video//exp3.avi";
cap.open(path);
if (!cap.isOpened()) {
cout << "Error opening video file" << endl;
return -1;
}
/*视频播放窗口*/
namedWindow("Video Player", WINDOW_NORMAL);
resizeWindow("Video Player", 800, 600);
fps = cap.get(CAP_PROP_FPS);
totalFrames = cap.get(CAP_PROP_FRAME_COUNT);
// 视频进度滑动条
createTrackbar("Progress", "Video Player", ¤tFrame, totalFrames, onTrackbarProgress);
/*参数调节窗口*/
namedWindow("Adjust", WINDOW_NORMAL);
resizeWindow("Adjust", 400, 200);
// 亮度滑动条
int brightnessBar = 50;
createTrackbar("Brightness", "Adjust", &brightnessBar, 100, onTrackbarBright);
setTrackbarPos("Brightness", "Adjust", brightnessBar);
// 对比度滑动条
int contrastBar = 100;
createTrackbar("Contrast", "Adjust", &contrastBar, 300, onTrackbarContrast);
setTrackbarPos("Contrast", "Adjust", contrastBar);
while (true) {
if (isPlaying) {
cap >> frame;
if (frame.empty()) {
cout << "End of video" << endl;
break;
}
Mat adjustedFrame;
frame.convertTo(adjustedFrame, -1, contrast, brightness);
imshow("Video Player", adjustedFrame);
currentFrame = cap.get(CAP_PROP_POS_FRAMES);
setTrackbarPos("Progress", "Video Player", currentFrame);
int key = waitKey(1000 / fps);
if (key == ' ') { // 按空格键暂停或播放
isPlaying = !isPlaying;
}
}
else {
Mat adjustedFrame;
frame.convertTo(adjustedFrame, -1, contrast, brightness);
Mat pausedFrame = adjustedFrame.clone();
putText(pausedFrame, "PAUSED", Point(50, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
imshow("Video Player", pausedFrame);
int key = waitKey(0);
if (key == ' ') { // 按空格键暂停或播放
isPlaying = !isPlaying;
}
}
}
cap.release();
destroyAllWindows();
return 0;
}