0020-在OpenCV環境下對影象做Gamma校正
什麼是Gamma校正?
Gamma校正是對輸入影象灰度值進行的非線性操作,使輸出影象灰度值與輸入影象灰度值呈指數關係。
上面中的指數γ即為Gamma.
經過Gamma校正後的輸入和輸出影象灰度值關係如下圖所示:橫座標是輸入灰度值,縱座標是輸出灰度值,藍色曲線是gamma值小於1時的輸入輸出關係,紅色曲線是gamma值大於1時的輸入輸出關係。可以觀察到,當gamma值小於1時(藍色曲線),影象的整體亮度值得到提升,同時低灰度處的對比度增加,高灰度處的對比度降低,更利於分辯低灰度值時的影象細節;當gamma值大於1時(紅色曲線),影象的整體亮度值得到減小,同時低灰度處的對比度降低,高灰度處的對比度增加,更利於分辯高灰度值時的影象細節。
為什麼要進行Gamma校正?
人眼對外界光源的感光值與輸入光強不是呈線性關係的,而是呈指數型關係的。在低照度下,人眼更容易分辨出亮度的變化,隨著照度的增加,人眼不易分辨出亮度的變化。而攝像機感光與輸入光強呈線性關係。OpenCV環境下對影象進行Gamma校正的原始碼如下:
影象處理開發資料、影象處理開發需求、影象處理接私活掙零花錢,可以搜尋公眾號"qxsf321",並關注!
原始碼中用到的影象下載連結:http://pan.baidu.com/s/1miIGyqW 密碼:bz9r
//opencv版本:OpenCV3.0 //VS版本:VS2013 //Author:qxsf321.net #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/imgproc/types_c.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/highgui/highgui_c.h> #include <iostream> using namespace cv; using namespace std; void MyGammaCorrection(Mat& src, Mat& dst, float fGamma) { // build look up table unsigned char lut[256]; for( int i = 0; i < 256; i++ ) { lut[i] = saturate_cast<uchar>(pow((float)(i/255.0), fGamma) * 255.0f); } dst = src.clone(); const int channels = dst.channels(); switch(channels) { case 1: //灰度圖的情況 { MatIterator_<uchar> it, end; for( it = dst.begin<uchar>(), end = dst.end<uchar>(); it != end; it++ ) //*it = pow((float)(((*it))/255.0), fGamma) * 255.0; *it = lut[(*it)]; break; } case 3: //彩色圖的情況 { MatIterator_<Vec3b> it, end; for( it = dst.begin<Vec3b>(), end = dst.end<Vec3b>(); it != end; it++ ) { //(*it)[0] = pow((float)(((*it)[0])/255.0), fGamma) * 255.0; //(*it)[1] = pow((float)(((*it)[1])/255.0), fGamma) * 255.0; //(*it)[2] = pow((float)(((*it)[2])/255.0), fGamma) * 255.0; (*it)[0] = lut[((*it)[0])]; (*it)[1] = lut[((*it)[1])]; (*it)[2] = lut[((*it)[2])]; } break; } } } int main() { Mat image = imread("gamma_pending.jpg"); if (image.empty()) { cout << "Error: Could not load image" << endl; return 0; } Mat dst; float fGamma=1/2.2; MyGammaCorrection(image, dst, fGamma); imshow("Source Image", image); imshow("Dst", dst); waitKey(); return 0; }
執行結果截圖如下:
從執行結果中我們可以看出:
最左邊的圖為原圖,中圖為gamma = 1/2.2時的校正結果,原圖中左半側的灰度值較高,右半側的灰度值較低,經過gamma=1/2.2校正後(中圖),左側的對比度降低(見鬍鬚),右側在對比度提高(明顯可以看清面容),同時影象在的整體灰度值提高。
最右邊的圖為gamma = 2.2在校正結果,校正後,左側的對比度提高(見鬍鬚),右側在對比度降低(面容更不清楚了),同時影象在的整體灰度值降低。
值得一提的是:人眼是按照gamma<1的曲線對自己看到的影象進行校正的。