Gamma校正及其实现

原文地址:http://blog.csdn.net/lichengyu/article/details/20840135

 

2中左图为原图,中图为gamma = 1/2.2在校正结果,原图中左半侧的灰度值较高,右半侧的灰度值较低,经过gamma = 1/2.2校正后(中图),左侧的对比度降低(见胡须),右侧在对比度提高(明显可以看清面容),同时图像在的整体灰度值提高。

右图为gamma = 2.2在校正结果,校正后,左侧的对比度提高(见胡须),右侧在对比度降低(面容更不清楚了),同时图像在的整体灰度值降低。

 

值得一提的是,人眼是按照gamma < 1的曲线对输入图像进行处理的。

 

参考资料:

[1] http://en.wikipedia.org/wiki/Gamma_correction

[2] http://www.cambridgeincolour.com/tutorials/gamma-correction.htm

[3] https://github.com/bytefish/opencv/blob/master/misc/tan_triggs.cpp



代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <opencv2/core/core.hpp>  
  2. #include <opencv2/imgproc/imgproc.hpp>  
  3. #include <opencv2/highgui/highgui.hpp>  
  4.    
  5. #include <iostream>  
  6.    
  7. using namespace cv;  
  8. using namespace std;  
  9.   
  10. // Normalizes a given image into a value range between 0 and 255.  
  11. Mat norm_0_255(const Mat& src) {  
  12.     // Create and return normalized image:  
  13.     Mat dst;  
  14.     switch(src.channels()) {  
  15.     case 1:  
  16.         cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);  
  17.         break;  
  18.     case 3:  
  19.         cv::normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);  
  20.         break;  
  21.     default:  
  22.         src.copyTo(dst);  
  23.         break;  
  24.     }  
  25.     return dst;  
  26. }  
  27.   
  28. int main(int argc, const char *argv[]) {  
  29.     // Get filename to the source image:  
  30.     if (argc != 2) {  
  31.         cout << "usage: " << argv[0] << " <image.ext>" << endl;  
  32.         exit(1);  
  33.     }  
  34.     // Load image & get skin proportions:  
  35.     //Mat image = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);  
  36.     Mat image = imread(argv[1], CV_LOAD_IMAGE_COLOR);  
  37.     // Convert to floating point:  
  38.     Mat X;  
  39.     image.convertTo(X, CV_32FC1);  
  40.     //image.convertTo(X, CV_32F);  
  41.     // Start preprocessing:  
  42.     Mat I;  
  43.     float gamma = 1/2.2;  
  44.     pow(X, gamma, I);  
  45.   
  46.   
  47.     // Draw it on screen:  
  48.     imshow("Original Image", image);  
  49.     imshow("Gamma correction image", norm_0_255(I));  
  50.     //imwrite("origin.jpg", image);  
  51.     imwrite("gamma_inv2.2.jpg", norm_0_255(I));