在图像像素公式g(x)=a*f(x)+b其中:
- 参数f(x)表示源图像像素。
- 参数g(x) 表示输出图像像素。
- 参数a(需要满足a>0)被称为增益(gain),常常被用来控制图像的对比度。
- 参数b通常被称为偏置(bias),常常被用来控制图像的亮度。
为了访问图像的每一个像素,我们使用这样的语法: image.at<Vec3b>(y,x)[c]
其中,y是像素所在的行, x是像素所在的列, c是R、G、B(对应0、1、2)其中之一。
因为我们的运算结果可能超出像素取值范围(溢出),还可能是非整数(如果是浮点数的话),所以我们要用saturate_cast对结果进行转换,以确保它为有效值。
这里的a也就是对比度,一般为了观察的效果,取值为0.0到3.0的浮点值,但是我们的轨迹条一般取值都会整数,所以在这里我们可以,将其代表对比度值的nContrastValue参数设为0到300之间的整型,在最后的式子中乘以一个0.01,这样就可以完成轨迹条中300个不同取值的变化。所以在式子中,我们会看到saturate_cast<uchar>( (g_nContrastValue*0.01)*(image.at<Vec3b>(y,x)[c] ) + g_nBrightValue )中的g_nContrastValue*0.01。
程序示例如下:
1 #include <opencv2/core/core.hpp>
2 #include<opencv2/highgui/highgui.hpp>
3 #include"opencv2/imgproc/imgproc.hpp"
4 #include <iostream>
5
6 using namespace cv; 7
8
9 static void ContrastAndBright(int, void *); 10
11 int g_nContrastValue; //对比度值
12 int g_nBrightValue; //亮度值
13 Mat g_srcImage, g_dstImage; 14 //-----------------------------------【main( )函数】-------------------------------------------- 15 // 描述:控制台应用程序的入口函数,我们的程序从这里开始 16 //-----------------------------------------------------------------------------------------------
17 int main() 18 { 19 //改变控制台前景色和背景色
20 system("color5F"); 21
22 //读入用户提供的图像
23 g_srcImage = imread("8.jpg"); 24 if (!g_srcImage.data) { printf("读取图片失败!\n"); return false; } 25 g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type()); 26
27 //设定对比度和亮度的初值
28 g_nContrastValue = 80; 29 g_nBrightValue = 80; 30
31 //创建窗口
32 namedWindow("结果", 1); 33
34 //创建轨迹条
35 createTrackbar("对比度:", "结果", &g_nContrastValue, 300, ContrastAndBright); 36 createTrackbar("亮 度:", "结果", &g_nBrightValue, 200, ContrastAndBright); 37
38 //调用回调函数
39 ContrastAndBright(g_nContrastValue, 0); 40 ContrastAndBright(g_nBrightValue, 0); 41
42 //按下“q”键时,程序退出
43 while (char(waitKey(1)) != 'q') {} 44 return 0; 45 } 46
47
48 //-----------------------------【ContrastAndBright( )函数】------------------------------------ 49 // 描述:改变图像对比度和亮度值的回调函数 50 //-----------------------------------------------------------------------------------------------
51 static void ContrastAndBright(int, void *) 52 { 53
54 //创建窗口
55 namedWindow("原图", 1); 56
57 //三个for循环,执行运算 g_dstImage(i,j) =a*g_srcImage(i,j) + b
58 for (int y = 0; y < g_srcImage.rows; y++) 59 { 60 for (int x = 0; x < g_srcImage.cols; x++) 61 { 62 for (int c = 0; c < 3; c++) 63 { 64 g_dstImage.at<Vec3b>(y, x)[c] = saturate_cast<uchar>((g_nContrastValue*0.01)*(g_srcImage.at<Vec3b>(y, x)[c]) + g_nBrightValue); 65 } 66 } 67 } 68
69 //显示图像
70 imshow("原图", g_srcImage); 71 imshow("结果", g_dstImage); 72 }
运行结果: