OpenCv图像处理之亮度与对比度的调整
对比度
差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。但对比率遭受和亮度相同的困境,现今尚无一套有效又公正的标准来衡量对比率,所以最好的辨识方式还是依靠使用者眼睛。 –百度百科
简单来说对比度就是像素值大小的差异。
亮度
亮度是指画面的明亮程度,单位是坎德拉每平米(cd/m2)或称nits,也就是每平方公尺分之烛光。当前提高显示屏亮度的方法有两种,一种是提高LCD面板的光通过率;另一种就是增加背景灯光的亮度。–百度百科
使用cv::saturate_cast<>()进行线性变换
我们一般对图像的亮度和对比度处理的时候,采用大多是线性变换,线性变换的公式是g(i,j) = alpha *f(i,j)+beta
,其中g(i,j)
表示变换(调整)后的像素值,f(i,j)
表示原像素值,alpha
用来调整对比度,它对像素的影响力度大,beta
用来调整亮度。
下面来看一个示例
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
using namespace std;
using namespace cv;
void resize_img(Mat &mat, int width, int height, int interpolation);
int main() {
Mat img, clone_img;
img = imread("D:/cat.jpg", 3);
if (img.empty()) {
cout << "open the image file failed" << endl;
return -1;
}
clone_img = img.clone();
double scale = 0.5;
int width = int(img.cols * scale);
int height = int(img.rows * scale);
int interpolation = INTER_AREA;
double alpha = 1.2;//设置为负数,降低对比度
double beta = 30;//设置为负数,降低亮度
resize_img(clone_img, width, height, interpolation);
Mat object_img = Mat::zeros(Size(clone_img.cols, clone_img.rows), clone_img.type());
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
//GBR
int blue = clone_img.at<Vec3b>(i, j)[0];
int green = clone_img.at<Vec3b>(i, j)[1];
int red = clone_img.at<Vec3b>(i, j)[2];
object_img.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(alpha * blue + beta);
object_img.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(alpha * green + beta);
object_img.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(alpha * red + beta);
}
}
imshow("original_frame", clone_img);
imshow("modify_frame", object_img);
waitKey(0);
return 0;
}
void resize_img(Mat &mat, int width, int height, int interpolation) {
resize(mat, mat, Size(width, height), 0, 0, interpolation);
}
效果显示