Gamma校正及其OpenCV实现
參考:[1]http://www.cambridgeincolour.com/tutorials/gamma-correction.htm
[2]http://en.wikipedia.org/wiki/Gamma_correction
一、什么是Gamma校正?
Gamma校正是对输入图像灰度值进行的非线性操作,使输出图像灰度值与输入图像灰度值呈指数关系:
[2]
这个指数即为Gamma.
经过Gamma校正后的输入和输出图像灰度值关系如图1所看到的:横坐标是输入灰度值,纵坐标是输出灰度值,蓝色曲线是gamma值小于1时的输入输出关系,红色曲线是gamma值大于1时的输入输出关系。能够观察到,当gamma值小于1时(蓝色曲线),图像的总体亮度值得到提升,同一时候低灰度处的对照度得到添加,更利于分辩低灰度值时的图像细节。

图1 Gamma校正.
二、为什么进行Gamma校正?
1. 人眼对外界光源的感光值与输入光强不是呈线性关系的,而是呈指数型关系的。在低照度下,人眼更easy分辨出亮度的变化,随着照度的添加,人眼不易分辨出亮度的变化。而摄像机感光与输入光强呈线性关系。如图2所看到的:

图2 人眼和摄像机的感光与实际输入光强的关系[1]。
为方便人眼辨识图像,须要将摄像机採集的图像进行gamma校正。
2. 为能更有效的保存图像亮度信息,需进行Gamma校正。
未经gamma校正和经过gamma校正保存图像信息如图3所看到的:
图3 未经gamma校正和经过gamma校正保存图像信息.
能够观察到,未经gamma校正的情况下,低灰度时,有较大范围的灰度值被保存成同一个值,造成信息丢失;同一时候高灰度值时,非常多比較接近的灰度值却被保存成不同的值,造成空间浪费。经过gamma校正后,改善了存储的有效性和效率。
三、利用OpenCV实现的Gamma校正
void MyGammaCorrection(Mat& src, Mat& dst, float fGamma)
{
CV_Assert(src.data); // accept only char type matrices
CV_Assert(src.depth() != sizeof(uchar)); // 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; }
}
}
Gamma校正及其OpenCV实现的更多相关文章
- Gamma校正与线性空间
基础知识部分 为了方便理解,首先会对(Luminance)的相关概念做一个简单介绍.如果已经了解就跳到后面吧. 我们用Radiant energy(辐射能量)来描述光照的能量,单位是焦耳(J),因为光 ...
- Gamma校正与线性工作流
1 Gamma校正是什么?8位亮度值x(0-1)经过x^0.45的一个提亮过程. 2 为什么需要Gamma校正 人的眼睛是以非线性方式感知亮度,在自然界中,人感觉到的一半亮度其实只有全部能量的0.2, ...
- 聊聊Unity的Gamma校正以及线性工作流
0x00 前言的前言 这篇小文其实是在清明节前后起的头,不过后来一度搁笔.一直到这周末才又想起来起的这个头还没有写完,所以还是直接用一个月前的开头,再将过程和结尾补齐. 0x01 前言 结束了在南方一 ...
- 图像处理之gamma校正
1 gamma校正背景 在电视和图形监视器中,显像管发生的电子束及其生成的图像亮度并不是随显像管的输入电压线性变化,电子流与输入电压相比是按照指数曲线变化的,输入电压的指数要大于电子束的指数.这说明暗 ...
- gamma校正
1 gamma校正背景 在电视和图形监视器中,显像管发生的电子束及其生成的图像亮度并不是随显像管的输入电压线性变化,电子流与输入电压相比是按照指数曲线变化的,输入电压的指数要大于电子束的指数.这说明暗 ...
- OpenGL核心技术之Gamma校正
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你/2.2次幂.Gamma校正后的暗红色就会成为(0.5,0.0 ...
- gamma校正原理
http://blog.csdn.net/u013286409/article/details/50239377 目录(?)[-] 图2中左图为原图,中图为gamma = 1/2.2在校正结果,原 ...
- SSE图像算法优化系列十九:一种局部Gamma校正对比度增强算法及其SSE优化。
这是一篇2010年比较古老的文章了,是在QQ群里一位群友提到的,无聊下载看了下,其实也没有啥高深的理论,抽空实现了下,虽然不高大上,还是花了点时间和心思优化了代码,既然这样,就顺便分享下优化的思路和经 ...
- Gamma原理及快速实现算法(C/C++)(转)
源:Gamma原理及快速实现算法(C/C++) 原文:http://blog.csdn.net/lxy201700/article/details/24929013 参考 http://www.cam ...
随机推荐
- iOS中使用RegexKitLite来试用正则表达式 使用ARC 20个错误解决办法
You can also disable the ARC for the RegexKitLite only by adding a flag: select the project -> YO ...
- OC与JS交互前言-b
一.WebView加载HTML UIWebView提供了三个方法来加载html资源 1. loadHTMLString:baseURL: 把html文件的内容以字符串的形式加载到webView里面,然 ...
- Codeforces Round #316 div2
一场充满血腥hack之战!!! Problem_A: 题意: n个候选人在m个城市进行投票,每个城市选出票数最多的一个候选人为城市候选人,如果票数相同,则取编号小的候选人. 再从这m个城市候选人中选出 ...
- XE5 开发android平台搭建
转载自:http://www.cnblogs.com/hezihang/p/3319980.html Delphi XE5的Android开发平台搭建 Delphi XE5支持Android AR ...
- [BZOJ 3531] [Sdoi2014] 旅行 【离线+LCT】
题目链接:BZOJ - 3531 题目分析 题目询问一条路径上的信息时,每次询问有某种特定的文化的点. 每个点的文化就相当于一种颜色,每次询问一条路径上某种颜色的点的信息. 可以使用离线算法, 类似于 ...
- 李洪强漫谈iOS开发[C语言-027]-自增与自减运算符
- win10全系列官方MSDN原版系统安装密钥、版本区别、镜像下载地址与激活教程
微软发布win10正式版已经过去几天了,相信很多同学都心情高涨的装上了期待已久的win10系统,但也有很多同学面对win10系统的众多版本感到一脸茫然,的确,微软在win10系统版本上的划分确实有点多 ...
- delphi-json组件,速度非常快,要比superobject快好几倍
delphi-json组件,速度非常快,要比superobject快好几倍https://github.com/ahausladen/JsonDataObjectshttp://bbs.2ccc.co ...
- String.format 细节
String.format(Locale.US, format, args); format 参数 如果有% 那么%后面必须跟一个合法的字符,否则崩溃, 因为在String.format中 %为特殊字 ...
- git rebase实战
在develop分支上rebase另外一个分支master,是将master作为本地,develop作为远端来处理的. 最后的效果是,develop分支看起来像是在master分支的最新的节点之后才进 ...