opencv學習之一亮度對比度調節
阿新 • • 發佈:2018-11-16
修改影象的對比度和亮度
目標
- 獲取畫素值
- 初始化零矩陣
- 學習使用cv::saturate_cast和作用“
- 學習一些比較酷的畫素轉換
原理
影象處理
通常影象處理操作就是一個函式,包含一個或者多個輸入影象然後產生一個輸出結果。
影象轉化可以看成兩種操作,一種是畫素點的操作,第二種就是臨域的操作(就是影象的一個區域內的操作)
畫素點轉化
這種影象處理每一個輸出畫素點的值依賴於相對應的輸入畫素點的值的加減處理。做這些處理的兩個基本的例子就是影象的亮度和對比度的調節。
亮度和對比度調節
通常的影象處理的公式如下:
g(x)=αf(x)+β
引數alpha>0,alpha叫增益因子和beta叫偏移因子。alpha控制對比度,beta控制亮度。
下面的公式更符合影象處理,g(i,j)表示輸出點,f(i,j)表示輸入點基本i,j代表影象中的行和列位置。
g(i,j)=α⋅f(i,j)+β
程式碼
下面的程式碼執行的是g(i,j)=α⋅f(i,j)+β的操作。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
double alpha; /*< Simple contrast control */
int beta; /*< Simple brightness control */
int main( int argc, char** argv )
{
Mat image = imread( argv[1] );
Mat new_image = Mat::zeros( image.size(), image.type() );
std::cout<<" Basic Linear Transforms "<<std::endl;
std::cout<<"-------------------------"<<std ::endl;
std::cout<<"* Enter the alpha value [1.0-3.0]: ";std::cin>>alpha;
std::cout<<"* Enter the beta value [0-100]: "; std::cin>>beta;
for( int y = 0; y < image.rows; y++ ) {
for( int x = 0; x < image.cols; x++ ) {
for( int c = 0; c < 3; c++ ) {
new_image.at<Vec3b>(y,x)[c] =
saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );
}
}
}
namedWindow("Original Image", 1);
namedWindow("New Image", 1);
imshow("Original Image", image);
imshow("New Image", new_image);
waitKey();
return 0;
}
程式說明
- 我們開始建立兩個引數alpha和beta,然後通用使用者輸入。
double alpha;
double beta;
2.使用cv::imread讀取一張圖片
Mat image = imread(argv[1]);
3.建立一張圖片矩陣,初始化矩陣為0,並且與image同樣大小和同樣的通道數。
Mat new_image = Mat::zeros(image.size(),image.type());
4.下面執行操作g(i,j)=α⋅f(i,j)+β ,我們將會遍歷每一個畫素。因為影象的格式是BGR,我們每個畫素需要操作三個值(BGR)。我們需要分別操作它們。
for( int y = 0; y < image.rows; y++ ) {
for( int x = 0; x < image.cols; x++ ) {
for( int c = 0; c < 3; c++ ) {
new_image.at<Vec3b>(y,x)[c] =
saturate_cast<uchar>( alpha*( image.at<Vec3b>(y,x)[c] ) + beta );
}
}
}
這裡遍歷每一個畫素使用image.at(y,x)[c]。
由於計算結果可能會超出範圍或者不是整數,我們使用cv::saturate_cast來確保計算結果可用。
5.最後,我們建立一個視窗來顯示影象。
namedWindow("Original Image", 1);
namedWindow("New Image", 1);
imshow("Original Image", image);
imshow("New Image", new_image);
waitKey(0);
其實可以使用cv::Mat::convertTo會更高效。
image.convertT(new_image,-1,aplha,beta);
函式原型:
void cv::Mat::convertTo ( OutputArray m,
int rtype,
double alpha = 1,
double beta = 0
) const
函式執行公式如下:
m(x,y)=saturate_cast(α(∗this)(x,y)+β)
引數說明:
m是輸出矩陣。
rtype期望輸出矩陣型別。
執行結果
使用alpha=2.2 beta=50。然後得到執行結果
***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****
Basic Linear Transforms
-------------------------
* Enter the alpha value [1.0-3.0]: 2.2
* Enter the beta value [0-100]: 50
*