【短道速滑二】古老的基于亮度平均值的自动Gamma校正算法。
在github上搜索代码Auto Gamma Correction,找到一个比较古老的代码,详见:https://github.com/PedramBabakhani/Automatic-Gamma-Correction,配套的代码使用VHDL语言写的,看了半天一个for循环没有,是在看不懂,幸好里面有篇算法对应的论文下载,论文名字叫《ASIC implementation of automatic gamma correction based on average of brightness 》,下载看了下,大概搞明白了他的大概意思。
文章的核心思想很简单,就是他假定一幅合理的图像应该所有像素的平均值应该是0.5左右(归一化后的),所以那么自动伽马校正的伽马值就要使得目标图像向这个目标前进。
假定X是图像的平均值,那么自动伽马需符合下述要求:

一步一步的往下推导,有:
-----》
--------》
就是这么简单哪,如果写个代码也就是几分钟的事情。
int IM_AutoGammaCorrection(unsigned char *Src, unsigned char *Dest, int Width, int Height, int Stride)
{
int Channel = Stride / Width;
if ((Src == NULL) || (Dest == NULL)) return IM_STATUS_NULLREFRENCE;
if ((Width <= 0) || (Height <= 0)) return IM_STATUS_INVALIDPARAMETER;
if ((Channel != 1) && (Channel != 3) && (Channel != 4)) return IM_STATUS_NOTSUPPORTED;
int AvgB, AvgG, AvgR, AvgA;
int Status = IM_GetAverageValue(Src, Width, Height, Stride, AvgB, AvgG, AvgR, AvgA);
if (Status != IM_STATUS_OK) return Status;
if (Channel == 1)
{
float Gamma = -0.3 / (log10(AvgB / 256.0f));
unsigned char Table[256];
for (int Y = 0; Y < 256; Y++) // 另外一种方式是:pow(Y / 255.0, 1.0 / Gamma)
{
Table[Y] = IM_ClampToByte((int)(pow(Y / 255.0f, Gamma) * 255.0f));
}
return IM_Curve(Src, Dest, Width, Height, Stride, Table, Table, Table);
}
else
{
float GammaB = -0.3 / (log10(AvgB / 256.0f));
float GammaG = -0.3 / (log10(AvgG / 256.0f));
float GammaR = -0.3 / (log10(AvgR / 256.0f)); unsigned char TableB[256], TableG[256], TableR[256];
for (int Y = 0; Y < 256; Y++) // 另外一种方式是:pow(Y / 255.0, 1.0 / Gamma)
{
TableB[Y] = IM_ClampToByte((int)(pow(Y / 255.0f, GammaB) * 255.0f));
TableG[Y] = IM_ClampToByte((int)(pow(Y / 255.0f, GammaG) * 255.0f));
TableR[Y] = IM_ClampToByte((int)(pow(Y / 255.0f, GammaR) * 255.0f));
}
return IM_Curve(Src, Dest, Width, Height, Stride, TableB, TableG, TableR);
}
}
效果似乎还是很不错的。

对于正常的图像,基本上没有啥变化,这也是必须要有的特性。

论文里提出了另外一种更适合于硬件实现的方式。
他把图像分成很多个16*16的小块,比如N*M个(文章中固定死了,也是16*16个),然后对16*16的小块,每次提取对应位置的一个像素,共计N*M个像素,计算这N*M像素的平均值,然后依据这个平均值计算出伽马值,这样就能计算出16*16个Gamma值,这些Gamma值肯定不会是完全相同的,文章中也统计了他们的差异大小,最后用这个256个gamma的平均值作为最后的正副图像的平均值。

这代码写的有点狗屎 ......
注意上面的取样是全部平均取样,不是某一个块集中取样。
这样写的结果和全图取平均还是有一定区别的,不过效果基本上差不多。
整个过程就这么简单,不过对于彩色图像,如果直接分通道实现,似乎会出现一定的偏色现象,我想这个不应该是Gamma调整该出现的作用,应该予以消除,如下所示:

解决方法有把三通道求得的Gamma值再求平均值,作为每个通道的Gamma值,也可以对亮度通道做Gamma,然后在返回到RGB空间等等。

如上所示,基本没有这个现象。
当然,这种全局的Gamma校正还是有很多问题,比如容易出现块状,容易增强噪音等等,需要和某些局部算法结合在一起来实现更好的结果。
本文Demo下载地址: http://files.cnblogs.com/files/Imageshop/SSE_Optimization_Demo.rar,见其中的Adjust-> Auto Gamma Correction菜单。
【短道速滑二】古老的基于亮度平均值的自动Gamma校正算法。的更多相关文章
- SSE图像算法优化系列二十四: 基于形态学的图像后期抗锯齿算法--MLAA优化研究。
偶尔看到这样的一个算法,觉得还是蛮有意思的,花了将近10天多的时间研究了下相关代码. 以下为百度的结果:MLAA全称Morphological Antialiasing,意为形态抗锯齿是AMD推出的完 ...
- 【计算机视觉】基于局部二值相似性模式(LBSP)的运动目标检测算法
基于局部二值相似性模式(LBSP)的运动目标检测算法 kezunhai@gmail.com http://blog.csdn.net/kezunhai 本文根据论文:Improving backgro ...
- NX二次开发-基于MFC界面的NX对Excel读写操作(OLE方式(COM组件))
NX二次开发API里没有对EXCAL读写操作的相关函数,市面上有很多种方法去实现,比如UFUN调KF,ODBC,OLE(COM组件)等等.这里我是用的OLE(COM组件)方式去做的,这种在VC上创建的 ...
- NX二次开发-基于NX开发向导模板的NX对Excel读写操作(OLE方式(COM组件))
在看这个博客前,请读者先去完整看完:NX二次开发-基于MFC界面的NX对Excel读写操作(OLE方式(COM组件))https://ufun-nxopen.blog.csdn.net/article ...
- (二)基于商品属性的相似商品推荐算法——Flink SQL实时计算实现商品的隐式评分
系列随笔: (总览)基于商品属性的相似商品推荐算法 (一)基于商品属性的相似商品推荐算法--整体框架及处理流程 (二)基于商品属性的相似商品推荐算法--Flink SQL实时计算实现商品的隐式评分 ( ...
- 基于Matlab的MMSE的语音增强算法的研究
本课题隶属于学校的创新性课题研究项目.2012年就已经做完了,今天一并拿来发表. 目录: --基于谱减法的语音信号增强算法..................................... ...
- 基于OpenSLL的RSA加密应用(非算法)
基于OpenSLL的RSA加密应用(非算法) iOS开发中的小伙伴应该是经常用der和p12进行加密解密,而且在通常加密不止一种加密算法,还可以加点儿盐吧~本文章主要阐述的是在iOS中基于openSL ...
- 基于模糊Choquet积分的目标检测算法
本文根据论文:Fuzzy Integral for Moving Object Detection-FUZZ-IEEE_2008的内容及自己的理解而成,如果想了解更多细节,请参考原文.在背景建模中,我 ...
- 基于OpenSSL的RSA加密应用(非算法)
基于OpenSSL的RSA加密应用(非算法) iOS开发中的小伙伴应该是经常用der和p12进行加密解密,而且在通常加密不止一种加密算法,还可以加点儿盐吧~本文章主要阐述的是在iOS中基于openSL ...
- 基于搜索的贝叶斯网络结构学习算法-K2
基于搜索的贝叶斯网络结构学习算法-K2 2018-04-05 19:34:18 ItsBlue 阅读数 3172更多 分类专栏: 贝叶斯网络 网络结构学习 版权声明:本文为博主原创文章,遵循CC ...
随机推荐
- MySQL 数据库表格创建、数据插入及获取插入的 ID:Python 教程
创建表格 要在MySQL中创建表格,请使用"CREATE TABLE"语句. 确保在创建连接时定义了数据库的名称. 示例创建一个名为 "customers" 的 ...
- 混合应用与Hybrid App开发上架流程透析
Hybrid App(混合 App)已经成为大家接触最为广泛的 App 形式,不管是我们用到的微信.支付宝还是淘宝.京东等大大小小的应用都非常热衷于Hybrid App 带来的研发效率提升和灵活性. ...
- git推送时报错:fatal: unable to access 'https://github.com/xxx/xxx.git/': Failed to connect to 127.0.0.1 port 31181 after 2063 ms: Connection refused
一.报错原因 1.因为git在拉取或者提交项目时,中间会有git的http和https代理,但是我们本地环境本身就有SSL协议了,所以取消git的https代理即可,不行再取消http的代理. 2.当 ...
- vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
这章我们讲回调,英文名:Beyond callbacks 一.章节覆盖: 回调函数及其限制,如网关/边缘服务示例所示 未来和承诺--链接异步操作的简单模型 响应式扩展--一个更强大的模型,特别适合组合 ...
- org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException报错问题
这个原因是 高版本SpringBoot整合swagger 造成的 我的项目是2.7.8 swagger版本是3.0.0 就会出现上面的报错 解决方式: 1.配置WebMvcConfigurer.jav ...
- Taurus .Net Core 微服务开源框架:Admin 插件【4-8】 - 配置管理-Mvc【Plugin-Limit 接口访问限制、IP限制、Ack限制】
前言: 继上篇:Taurus .Net Core 微服务开源框架:Admin 插件[4-7] - 配置管理-Mvc[Plugin-Metric 接口调用次数统计] 本篇继续介绍下一个内容: 1.系统配 ...
- C++ Qt开发:SqlRelationalTable关联表组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍SqlRela ...
- DVWA Brute Force(暴力破解)全等级
Brute Force(暴力破解) 目录: Brute Force(暴力破解) 1.Low 2.Medium 3.High 方法1--Burp爆破 方法2--Python脚本爆破 4.Impossib ...
- node版本管理工具推荐
hello,今天给大家分享几款 node 版本管理的工具. 背景 在开发前端项目的时候,特别是新到公司接手一个多年维护的老项目时,如果 node 版本不正确,有的插件可能无法正确安装,比如我之前提到的 ...
- 关于three.js中的矩阵更新
目录 1. 概述 2. 详解 1. 概述 使用如下代码绘制一个面: 'use strict'; function init() { //console.log("Using Three.js ...