图像Gamma(伽玛)校正的原理及OpenCV代码实现

article/2025/10/16 3:19:12

什么是Gamma校正?

Gamma校正是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数关系。

Gamma校正的原理表达式如下:

\LARGE V_{out}=AV_{in}^{\gamma}

上面中的指数γ即为Gamma。这就是Gamma校正的名称来历。

其中\small V_{in}的取值范围是0~1,最重要的参数就是式子中的参数γ。

γ的值决定了输入图像和输出图像之间的灰度映射方式,即决定了是增强低灰度值区域还是增高灰度值区域。
γ>1时,即下图中的红色曲线,图像的高灰度区域对比度得到增强,直观效果是一幅偏亮的图变暗了下来。
γ<1时,即下图中的蓝色曲线,图像的低灰度区域对比度得到增强,直观效果是一幅偏暗的图变亮了起来。
γ=1时,不改变原图像。

Gamma校正表达式的曲线图如下:

横坐标是输入灰度值,纵坐标是输出灰度值,蓝色曲线是gamma值小于1时的输入输出关系,红色曲线是gamma值大于1时的输入输出关系。
可以观察到,当gamma值小于1时(蓝色曲线),图像的整体亮度值得到提升,同时低灰度处的对比度增加,高灰度处的对比度降低,更利于分辩低灰度值时的图像细节;
当gamma值大于1时(红色曲线),图像的整体亮度值得到减小,同时低灰度处的对比度降低,高灰度处的对比度增加,更利于分辩高灰度值时的图像细节。

为什么要进行Gamma校正?
一个典型的例子:人眼对外界光源的感光值与输入光强不是呈线性关系的,而是呈指数型关系的。在低照度下,人眼更容易分辨出亮度的变化,随着照度的增加,人眼不易分辨出亮度的变化。而相机感光与输入光强呈线性关系。为了适应我们人眼的特性,我们就需要对相机拍摄得到的原始图像作Gamma校正。

在OpenCV环境下实现的Gamma校正代码如下:

//出处:昊虹AI笔记网(hhai.cc)
//用心记录计算机视觉和AI技术//博主微信/QQ 2487872782
//QQ群 271891601
//欢迎技术交流与咨询//OpenCV版本 OpenCV3.0#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;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("E:/material/images/P0034-Gamma-correction.jpg");if (image.empty()){cout << "Error: Could not load image" << endl;return 0;}Mat dst1;Mat dst2;float fGamma1=1/2.2;float fGamma2=2;MyGammaCorrection(image, dst1, fGamma1);MyGammaCorrection(image, dst2, fGamma2);cv::namedWindow("Source Image", WINDOW_NORMAL);cv::namedWindow("Gamma=1/2.2", WINDOW_NORMAL);cv::namedWindow("Gamma=2", WINDOW_NORMAL);imshow("Source Image", image);imshow("Gamma=1/2.2", dst1);imshow("Gamma=2", dst2);waitKey();return 0;
}

 从上面的结果中我们可以看出,当γ值小于1时,图像的低灰度区域对比度得到了增强,这样就使得一幅偏暗的图变得明亮了起来;而当γ值大于1时,图像的高灰度区域对比度得到了增强,这就会使得一幅偏亮的图暗下来。

接下来再测试下彩色图片的效果。

用下面这张图进行测试:

 上面这张图的百度网盘下载链接:

链接:https://pan.baidu.com/s/1FPaoTbFRKITnVtvFIoL1Yw?pwd=eq8i 

运行效果如下图所示:


http://chatgpt.dhexx.cn/article/C92g1IQ9.shtml

相关文章

Gamma校正

下面是自己所整理的一些gamma校正的东西如有侵权请联系删除。 Gamma矫正&#xff1a; 伽马矫正也称幂律变换&#xff0c;一般用于平滑的扩展暗调的细节。 进行伽马矫正的原因是人类的眼睛在感知光线时&#xff0c;眼睛对亮度的感知遵循近似的幂函数&#xff08;如图&#xf…

图像Gamma校正

1. gamma校正的起因&#xff1a;人眼感知光线的特殊性 对于现实世界的光的强度来说&#xff0c;描述光的强弱&#xff0c;是根据光子在单位面积上的光子数量来描述的&#xff0c;这是物理规则&#xff0c;这是没错的&#xff0c;光的亮度&#xff08;强度&#xff09;是和光子数…

Gamma校正原理及实现

gamma校正原理&#xff1a;   假设图像中有一个像素&#xff0c;值是 200 &#xff0c;那么对这个像素进行校正必须执行如下步骤&#xff1a;   1. 归一化 &#xff1a;将像素值转换为 0 &#xff5e; 1 之间的实数。 算法如下 : ( i 0. 5)/256 这里包含 1 个除法和 1…

python手撕分水岭算法

python手撕分水岭算法 1 分水岭算法实现 主要思路就是&#xff1a; 利用一个优先队列与有序队列&#xff08;有序队列其实可以不用&#xff09;。优先队列是按像素的灰度值排列的&#xff0c;灰度值低的先被淹。通过统计像素的附近的点的标记种类个数来确认当前像素点的标记…

分水岭算法java,OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法...

1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry)&#xff0c;它属于立体视觉(stereo vision)几何学&#xff0c;立体视觉是计算机视觉的一个分支&#xff0c;它从同一物体的两张不同图像提取三维信息。 极几何的工作原理&#x…

分水岭算法-python-opencv

分水岭算法简单原理&#xff1a; 对于一个图像的灰度值&#xff0c;将图像放平&#xff0c;可以看成是类似与山谷与山顶的图像&#xff0c;灰度值小的就是山底。先找到若干个山底&#xff0c;同时加水&#xff0c;当加到一定程度时候&#xff0c;某些山顶会被淹没&#xff0c;…

分水岭算法解析[halcon]

分水岭算法 分水岭算法是根据分水岭的构成来考虑图像的分割&#xff0c; 它是—种基于拓扑理论的数学形态学的分割方法。 首先&#xff0c; 把一幅图像看作起伏的地形&#xff0c; 图像的每像素灰度值作为这个地形的高度&#xff0c; 极小值是盆地&#xff0c; 极大值为山脊。…

opencv-分水岭算法图像分割

分水岭算法图像分割 目标   本节我们将要学习   • 使用分水岭算法基于掩模的图像分割   • 函数&#xff1a;cv2.watershed()    原理   任何一副灰度图像都可以被看成拓扑平面&#xff0c;灰度值高的区域可以被看成是山峰&#xff0c;灰度值低的区域可以被看成是山…

分水岭算法的python实现及解析

1 算法简介 分水岭算法的原理很容易查到&#xff0c;但是很多文章都是直接用的opencv或matlab函数&#xff0c;看不到具体实现方法&#xff0c;这篇文章希望能对大家有点帮助。 分水岭算法就是往山谷中注水&#xff0c;把不同湖水接触的位置称作分水岭&#xff0c;这么做的结…

opencv28:分水岭算法的图像分割

目标 在本章中&#xff0c;将学习 使用分水岭算法实现基于标记的图像分割函数&#xff1a;cv2.watershed() 理论 任何灰度图像都可以看作是一个地形表面&#xff0c;其中高强度的像素表示山峰&#xff0c;低强度表示山谷。可以用不同颜色的水(标签)填充每个孤立的山谷(局部…

OpenCV-分水岭算法

文章目录 分水岭算法cv2.watershed示例 分水岭算法 任何灰度图像都可以看作是一个地形表面&#xff0c;其中高强度表示山峰&#xff0c;低强度表示山谷。你开始用不同颜色的水(标签)填充每个孤立的山谷(局部最小值)。随着水位的上升&#xff0c;根据附近的山峰(坡度)&#xff…

【OpenCV】- 分水岭算法

文章目录 什么是图像分割分水岭算法1、实现分水岭算法&#xff1a;watershed()函数2、处理流程&#xff08;视频&#xff09;3、示例程序&#xff08;书中&#xff09; 什么是图像分割 将图像中像素根据一定的规则分为若干个cluster集合&#xff0c;每个集合包含一类对象 如下…

OpenCV分水岭算法详解

原理分析 分水岭算法主要用于图像分段&#xff0c;通常是把一副彩色图像灰度化&#xff0c;然后再求梯度图&#xff0c;最后在梯度图的基础上进行分水岭算法&#xff0c;求得分段图像的边缘线。 下面左边的灰度图&#xff0c;可以描述为右边的地形图&#xff0c;地形的高度是由…

分水岭算法 matlab实现

背景 做图像分割的时候用到了&#xff0c;就学习了一下 大概思想 把图像中的像素大小理解成山地的海拔&#xff0c;向山地灌水&#xff0c;海拔低的地方会积水&#xff0c;这些地方称之为谷底。随着水位上升&#xff0c;不同谷底的水会相遇&#xff0c;相遇的地方就是分水岭。…

分水岭算法c语言,Opencv分水岭算法学习

分水岭算法可以将图像中的边缘转化成“山脉”&#xff0c;将均匀区域转化为“山谷”&#xff0c;这样有助于分割目标。 分水岭算法是一种基于拓扑理论的数学形态学的分割方法&#xff0c;其基本思想是把图像看作是测地学上的拓扑地貌&#xff0c;图像中的每一点像素的灰度值表示…

分水岭算法

引言&#xff1a;它是基于拓扑理论的形态学处理方法。将一张图像假想成为一张地貌特征图。 原理理解&#xff1a;灰度图被看作拓扑平面&#xff0c;灰度高看成山峰&#xff0c;灰度低看成山谷。从山谷开始注水&#xff0c;随着水位升高水流会相遇汇合。为了防止汇合&#xff0…

Opencv分水岭算法——watershed自动图像分割用法

分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特征。 其他图像分割方法,如阈值,边缘检测等都不会考虑像素在…

目标分割算法之分水岭算法

分水岭算法 1.经典算法原理及实现 传统的目标分割算法主要分为两种 1.基于像素相似性&#xff1a;阈值分割、k-means分割 2.基于像素邻域关系&#xff1a;区域生长、分水岭、基于标记分水岭 分水岭算法原理 如图中展现了凹凸不平的地貌&#xff0c;视觉上明显的位置有盆地及…

分水岭算法的理解和应用

分水岭算法 主要思想 图像的灰度空间很像地球表面的整个地理结构&#xff0c;每个像素的灰度值代表高度。分水岭就是灰度值较大的像素连成的线。二值化阈值可以理解为水平面&#xff0c;比灰度二值化阈值小的像素区域会被淹没。随着水位线的升高&#xff0c;被淹没的区域越来越…

分水岭算法及其实现

&#xff11; - 算法描述 1.1 分水岭算法的原理   分水岭的概念是以三维方式来形象化一幅图像为基础的&#xff1a;两个空间坐标再加上强度。在这种“地形学”解释中&#xff0c;考虑三种类型的点&#xff1a;&#xff08;a&#xff09;局部最小值点&#xff0c;该点对应一个…