【VC++、OpenCV3.4】图像亮度和对比度调整
1、图像变换可以看做像素变换(点操作)和区域上的邻域操作。
调整图像亮度和对比度属于像素变换-点操作。
其中alpha是增益变量,另外OpenCV是基于RGB的图像操作,0-255,所以a应该是正数。
注意:提高亮度和提高对比度是不一样的。亮度是关注像素值,对比度关注像素差值。
2、重要的API
Mat new_image=Mat::zeros(image..size(),image.type());创建一张和原图大小一致的空白图像,像素值初始化为0。
saturate_cast<uchar>(value)确保值的大小范围在0-255;
Mat.at<Vec3b>(x,y)[index]=value;给每个像素点的通道赋值。
Mat对象默认是Vec3b的数据形式,如果要使用Vec3f等形式需要用函数convertTo(out,CV_32F)来转换。数据类型不对会报错
3、亮度的改变也可以直接用multiply
用法:
CV_EXPORTS_W void multiply(InputArray src1, InputArray src2,
OutputArray dst, double scale = 1, int dtype = -1);
代码:
#include<opencv2/opencv.hpp>
#include<iostream>
#include<string>
using namespace cv;
//调整亮度和对比度
int main(int argc, char**argv) {
Mat src, dst;
src = imread("C:\\Users\\admin\\Desktop\\demo.jpg", IMREAD_COLOR);
if (!src.data)
{
printf("Could not load the picture...");
return -1;
}
char Input_title[] = "Source pic";
namedWindow(Input_title, CV_WINDOW_AUTOSIZE);
imshow(Input_title, src);
int width = src.cols;
int height = src.rows;
double alpha = 1.2;
double beta = 10.0;
dst = Mat::zeros(src.size(), src.type());
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) {
//直接使用Vec3f有报错。在使用之前需要转换
float b = m1.at<Vec3f>(row, col)[0];
float g = m1.at<Vec3f>(row, col)[1];
float r = m1.at<Vec3f>(row, col)[2];
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha + beta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(b*alpha + beta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(b*alpha + beta);
}
else if(src.channels()==1)
{
float v = src.at<uchar>(row, col);
dst.at<uchar>(row, col) = saturate_cast<uchar>(v*alpha + beta);
}
}
}
String Out_pic = "Output window";
namedWindow(Out_pic, CV_WINDOW_AUTOSIZE);
imshow(Out_pic, dst);
waitKey(0);
return 0;
}
效果图: