1. 程式人生 > >【VC++、OpenCV3.4】影象亮度和對比度調整

【VC++、OpenCV3.4】影象亮度和對比度調整

1、影象變換可以看做畫素變換(點操作)和區域上的鄰域操作。

調整影象亮度和對比度屬於畫素變換-點操作。

g(x,y)=af(x,y)+alpha其中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;
}

效果圖: