亮度和对比度调节

前言

本文主要介

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <time.h>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

static void on_ContrastAndBright(int, void*);
static void ShowHelpText();

int g_nContrastValue;
int g_nBrightValue;
Mat g_srcImage, g_dstImage;

int main(){
g_srcImage = imread("1.jpg");
if(!g_srcImage.data){
printf("Failed\n");
return -1;
}
g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());

g_nContrastValue = 80;
g_nBrightValue = 80;

namedWindow("Output",WINDOW_AUTOSIZE);

createTrackbar("Contrast:","Output",&g_nContrastValue,300,on_ContrastAndBright);
createTrackbar("Bright:","Output",&g_nBrightValue,200,on_ContrastAndBright);

on_ContrastAndBright(g_nContrastValue,0);
on_ContrastAndBright(g_nBrightValue,0);

while(char(waitKey(1)) != 'q') {}
return 0;
}
static void on_ContrastAndBright(int, void*){
namedWindow("Input",WINDOW_AUTOSIZE);
for(int y = 0; y < g_srcImage.rows; y++)
{
for(int x = 0; x < g_srcImage.cols; x++){
for(int c = 0; c < 3; c++){
g_dstImage.at<Vec3b>(y,x)[c] = saturate_cast<uchar>
((g_nContrastValue*0.01) * (g_srcImage.at<Vec3b>(y,x)[c]) + g_nBrightValue);
}
}
}
imshow("Input",g_srcImage);
imshow("Output",g_dstImage);
}

原图:

测试图;

感觉图片上的时间硬是调早了两个小时……

1.Mat::zeros()和Mat::ones()

Mat::zeros()相当于创建了一张全黑的图,图像矩阵上每个像素点的每个通道全设置为0。
Mat::ones()则是将图像矩阵上每个像素点的第一个通道设置为1,其余通道设置为0。

2.saturate_cast防止数据溢出

原理如下:

1
2
if(data<0) data=0;
else if(data>255) data=255;

3.Mat类中的at函数

在测试代码中,函数实现亮度和对比度的调节是通过Mat类中的at函数遍历各个像素点并修改来实现的,但这不是最有效率的做法,在测试图像素为4000✖1900左右,在调节亮度和对比度时就会变得非常卡了。还有一种指针的做法和一种迭代器的做法,可以参考我之前的博客。