1. 程式人生 > >【opencv】 改變影象的對比度和亮度的兩種方法

【opencv】 改變影象的對比度和亮度的兩種方法

方法一:對每個畫素點進行線性處理

兩種常用的點過程(即點運算元),是用常數對點進行乘法加法運算:

                                                                                                                      g(x) = \alpha f(x) + \beta

兩個引數 \alpha > 0 和 \beta 一般稱作 增益 和 偏置 引數。我們往往用這兩個引數來分別控制 對比度 和 亮度 。

你可以把 f(x) 看成源影象畫素,把 g(x) 看成輸出影象畫素。這樣一來,上面的式子就能寫得更清楚些:

                                                                                                                  g(i,j) = \alpha \cdot f(i,j) + \beta

其中, i 和 j 表示畫素位於 第i行 和 第j列 。

執行程式碼如下:

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

double alpha; /**< 控制對比度 */
int beta;  /**< 控制亮度 */
int main()
{
	

	Mat image = imread("2.png",CV_LOAD_IMAGE_UNCHANGED);
	if (image.empty()){
		cout << "影象載入失敗" << endl;
	}
	// 初始化  
	cout << " Basic Linear Transforms " << endl;
	cout << "-------------------------" << endl;
	cout << "* Enter the alpha value [1.0-3.0]: ";
	cin >> alpha;
	cout << "* Enter the beta value [0-100]: ";
	cin >> beta;
        Mat new_image = Mat::zeros(image.size(), image.type());

	for (int i = 0; i < image.rows; i++)
	{
		for (int j = 0; j < image.cols; j++)
		{
			for (int k = 0; k < 3; k++)
			{			
				new_image.at<Vec3b>(i, j)[k] = 
				saturate_cast<uchar>(alpha*(image.at<Vec3b>(i, j)[k]) + beta);
			}
		}
	}
	namedWindow("a",1);
	imshow("b", new_image);
	waitKey();
	return 0;
}

方法二:使用opencv函式convertTo
void Mat::convertTo( Mat& m, int rtype, double alpha=1, double beta=0 ) const;

輸入引數: m  目標矩陣。如果m的大小與原矩陣不一樣,或者資料型別與引數不匹配,那麼在函式convertTo內部會先給m重新分配空間。
rtype 指定從原矩陣進行轉換後的資料型別,即目標矩陣m的資料型別。當然,矩陣m的通道數應該與原矩陣一樣的。如果rtype是負數,那麼m矩陣的資料型別應該與原矩陣一樣。
alpha 縮放因子。預設值是1。即把原矩陣中的每一個元素都乘以alpha。
beta 增量。預設值是0。即把原矩陣中的每一個元素都乘以alpha,再加上beta。

功能 函式將源矩陣中的畫素值轉換為目標型別。最後會使用溢位保護函式saturate_cast<> ,以避免轉換過程中可能出現的溢位。函式執行如下運算:  m(x,y)=saturate_cast<rType>(alpha*(*this)(x,y)+beta); 由於有資料型別的轉換,所以需要用saturate_cast<rType>來處理資料的溢位。 程式碼如下:
#include <iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

double alpha; /**< 控制對比度 */
int beta;  /**< 控制亮度 */
int main()
{	
	Mat image = imread("2.png",CV_LOAD_IMAGE_UNCHANGED);
	if (image.empty()){
		cout << "影象載入失敗" << endl;
	}
        Mat imageConvert;
	image.convertTo(imageConvert, image.type(), 1, 50);
        namedWindow("a", 1);
	imshow("a", imageConvert);
	
	waitKey();
	return 0;
}