opencv调整图像亮度与对比度

时间:2022-03-02 08:41:54

理论基础

图像变换中一般有如下两种操作

1,像素变换 对应 点操作

2,,邻域操作 对应 区域 

图像亮度与对比度的调整操作属于点操作,点操作的特点:

1,根据输入像素值来计算相应的输出像素值

亮度与对比度调整的数学模型

g(i,j)=a*f(i,j)+b

f(i,j)表示源图像,g(i,j)表示输出图像像素

参数 a (a >0) 被称为增益,用来控制图像的对比度

参数b 被称为偏置,用来控制图像的亮度

i,j表示像素位于第i行和第j列,编写程序时,不管是三通道还是单通道

需要遍历整个图像对每个像素值应用上面的数学公式。


应用的知识点

1,Mat new_image=Mat::zeros(image.size(),image.type())创建一张跟原图大小和类型一致的空白图像,像素值初始化为0

2,saturate_cast<uchar>(value) 防止像素值越界,确保像素值的范围在0-255之间

3,Mat.at<Vec3b>(y,x)[index]=value 给每个像素点通道赋值

效果图

1,原始图像

opencv调整图像亮度与对比度

亮度和对比度变换后的图像

opencv调整图像亮度与对比度

代码实现

#include <opencv2\opencv.hpp>
#include <iostream>

using namespace cv;
int main(int argc, char** argv)
{
Mat src, dst;
src = imread("test.jpg");
if (!src.data)
{
printf("图片加载错误");
return -1;
}

char input_win[] = "输入图像";
//cvtColor(src,src,CV_BGR2GRAY);
namedWindow(input_win,CV_WINDOW_AUTOSIZE);
imshow(input_win,src);

int height = src.rows;
int width = src.cols;
dst = Mat::zeros(src.size(),src.type());
float alpha = 1.8;
float beta = 20;

//Mat m1;
//src.convertTo(m1,CV_32F);
for (int row = 0; row < height;row++)
{
for (int col = 0; col < width;col++)
{
if (src.channels()==3)
{
float b = src.at<Vec3b>(row, col)[0];//blue
float g = src.at<Vec3b>(row, col)[1];//green
float r = src.at<Vec3b>(row, col)[2];//red

//output
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha+beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g*alpha+beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r*alpha + beta);
}
else if (src.channels()==1)
{
float gray = src.at<uchar>(row,col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(gray*alpha+beta);
}
}
}

char output_title[] = "调整图像亮度和对比度后的图像";
imshow(output_title,dst);
waitKey(0);
return 0;
}