Gamma 矫正用于平衡光照不均匀
Posted jaiken
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gamma 矫正用于平衡光照不均匀相关的知识,希望对你有一定的参考价值。
伽马校正(Gamma correction) 又叫伽马非线性化(gamma nonlinearity)、伽马编码(gamma encoding) 或是就只单纯叫伽马(gamma)。是用来针对影片或是影像系统里对于光线的辉度(luminance)或是三色刺激值(tristimulus values)所进行非线性的运算或反运算。
维基百科
1、公式
其中A是一个常量,输入和输出的值都为非负实数值。一般地来说在A=1的通常情况下,输入输出的值的范围都是在0到1之间。伽马值γ < 1的情况有时被称作编码伽马值(encoding gamma),而执行这个编码运算所使用上述幂定律的过程也叫做伽马压缩(gamma compression);相对地,伽马值γ > 1的情况有时也被称作解码伽马值(decoding gamma),而执行这个解码运算所使用上述幂定律的过程也叫做“伽马展开(gamma expansion)”。
2、解释
3、详解
1、什么是Gamma曲线矫正?
Gamma曲线矫正是什么意思?Gamma曲线是一种特殊的色调曲线,当Gamma值等于1的时候,曲线为与坐标轴成45°的直线,这个时候表示输入和输出密度相同。高于1的Gamma值将会造成输出亮化,低于1的Gamma值将会造成输出暗化。总之,我们的要求是输入和输出比率尽可能地接近于1。在显示器、扫描仪、打印机等输入、输出设备中这是一个相当常见并且比较重要的概念。在计算机系统中,由于显卡或者显示器的原因会出现实际输出的图像在亮度上有偏差,而Gamma曲线矫正就是通过一定的方法来矫正图像的这种偏差的方法。一般情况下,当用于Gamma矫正的值大于1时,图像的高光部分被压缩而暗调部分被扩展,当Gamma矫正的值小于1时,图像的高光部分被扩展而暗调部分被压缩,Gamma矫正一般用于平滑的扩展暗调的细节。
2、Gamma 矫正代码
1 #include <opencv2/core/core.hpp> 2 #include <opencv2/imgproc/imgproc.hpp> 3 #include <opencv2/imgproc/types_c.h> 4 #include <opencv2/highgui/highgui.hpp> 5 #include <opencv2/highgui/highgui_c.h> 6 #include <opencv2/highgui.hpp> 7 #include <opencv2/calib3d.hpp> 8 #include <iostream> 9 ? 10 using namespace cv; 11 using namespace std; 12 ? 13 void GammaCorrection(Mat& src, Mat& dst, float fGamma) 14 { 15 unsigned char lut[256]; 16 for (int i = 0; i < 256; i++) 17 { 18 lut[i] = saturate_cast<uchar>(pow((float)(i / 255.0), fGamma) * 255.0f); 19 } 20 ? 21 dst = src.clone(); 22 const int channels = dst.channels(); 23 switch (channels) 24 { 25 case 1: 26 { 27 ? 28 MatIterator_<uchar> it, end; 29 for (it = dst.begin<uchar>(), end = dst.end<uchar>(); it != end; it++) 30 * it = lut[(*it)]; 31 ? 32 break; 33 } 34 case 3: 35 { 36 ? 37 MatIterator_<Vec3b> it, end; 38 for (it = dst.begin<Vec3b>(), end = dst.end<Vec3b>(); it != end; it++) 39 { 40 (*it)[0] = lut[((*it)[0])]; 41 (*it)[1] = lut[((*it)[1])]; 42 (*it)[2] = lut[((*it)[2])]; 43 } 44 ? 45 break; 46 ? 47 } 48 default: 49 break; 50 } 51 } 52 ? 53 int main() 54 { 55 Mat image = imread("D://Images/wrong/2.jpg"); 56 if (image.empty()) 57 { 58 cout << "Error: Could not load image" << endl; 59 return 0; 60 } 61 Mat dst; 62 float fGamma = 1 / 1.8; 63 GammaCorrection(image, dst, fGamma); 64 imwrite("D://Images/wrong/24.jpg", dst); 65 waitKey(); 66 ? 67 return 0; 68 }
1 package org.jaiken.tools; 2 ? 3 import org.opencv.core.Core; 4 import org.opencv.core.CvType; 5 import org.opencv.core.Mat; 6 import org.opencv.imgcodecs.Imgcodecs; 7 ? 8 public class GammaCorrection { 9 // 伽马校正 10 public Mat gamma(Mat src) { 11 Mat x = new Mat(); 12 src.convertTo(x, CvType.CV_32FC3); 13 Mat i = new Mat(); 14 15 Core.pow(x, 1/1.8, i); 16 Mat dst = new Mat(); 17 // 归一化 18 Core.normalize(i, dst, 0, 255, Core.NORM_MINMAX, 0); 19 Imgcodecs.imwrite("D://Images/wrong/22.jpg", dst); 20 return dst; 21 } 22 ? 23 public static void main(String[] args) { 24 System.load("D://Export/opencv_java320.dll"); 25 Mat src = Imgcodecs.imread("D://Images/wrong/2.jpg",0); 26 if (src.empty()) { 27 System.err.println("The picture doesn‘t exist"); 28 return; 29 } 30 GammaCorrection gammaCorrection = new GammaCorrection(); 31 gammaCorrection.gamma(src); 32 } 33 ? 34 }
?
效果图
这样还仅能看出图像亮度上的变化,体会不到细节上的变化,这样用阈值化和Blob 分析的方法检测下两张图像,结果图如下。
结果很明显的第四列,第五行的图像细节上更加清楚,处理结果更加的的好,而没有了图像上"线"的干扰。
以上是关于Gamma 矫正用于平衡光照不均匀的主要内容,如果未能解决你的问题,请参考以下文章