在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校正算法。的更多相关文章

  1. SSE图像算法优化系列二十四: 基于形态学的图像后期抗锯齿算法--MLAA优化研究。

    偶尔看到这样的一个算法,觉得还是蛮有意思的,花了将近10天多的时间研究了下相关代码. 以下为百度的结果:MLAA全称Morphological Antialiasing,意为形态抗锯齿是AMD推出的完 ...

  2. 【计算机视觉】基于局部二值相似性模式(LBSP)的运动目标检测算法

    基于局部二值相似性模式(LBSP)的运动目标检测算法 kezunhai@gmail.com http://blog.csdn.net/kezunhai 本文根据论文:Improving backgro ...

  3. NX二次开发-基于MFC界面的NX对Excel读写操作(OLE方式(COM组件))

    NX二次开发API里没有对EXCAL读写操作的相关函数,市面上有很多种方法去实现,比如UFUN调KF,ODBC,OLE(COM组件)等等.这里我是用的OLE(COM组件)方式去做的,这种在VC上创建的 ...

  4. NX二次开发-基于NX开发向导模板的NX对Excel读写操作(OLE方式(COM组件))

    在看这个博客前,请读者先去完整看完:NX二次开发-基于MFC界面的NX对Excel读写操作(OLE方式(COM组件))https://ufun-nxopen.blog.csdn.net/article ...

  5. (二)基于商品属性的相似商品推荐算法——Flink SQL实时计算实现商品的隐式评分

    系列随笔: (总览)基于商品属性的相似商品推荐算法 (一)基于商品属性的相似商品推荐算法--整体框架及处理流程 (二)基于商品属性的相似商品推荐算法--Flink SQL实时计算实现商品的隐式评分 ( ...

  6. 基于Matlab的MMSE的语音增强算法的研究

    本课题隶属于学校的创新性课题研究项目.2012年就已经做完了,今天一并拿来发表.   目录: --基于谱减法的语音信号增强算法..................................... ...

  7. 基于OpenSLL的RSA加密应用(非算法)

    基于OpenSLL的RSA加密应用(非算法) iOS开发中的小伙伴应该是经常用der和p12进行加密解密,而且在通常加密不止一种加密算法,还可以加点儿盐吧~本文章主要阐述的是在iOS中基于openSL ...

  8. 基于模糊Choquet积分的目标检测算法

    本文根据论文:Fuzzy Integral for Moving Object Detection-FUZZ-IEEE_2008的内容及自己的理解而成,如果想了解更多细节,请参考原文.在背景建模中,我 ...

  9. 基于OpenSSL的RSA加密应用(非算法)

    基于OpenSSL的RSA加密应用(非算法) iOS开发中的小伙伴应该是经常用der和p12进行加密解密,而且在通常加密不止一种加密算法,还可以加点儿盐吧~本文章主要阐述的是在iOS中基于openSL ...

  10. 基于搜索的贝叶斯网络结构学习算法-K2

    基于搜索的贝叶斯网络结构学习算法-K2 2018-04-05 19:34:18 ItsBlue 阅读数 3172更多 分类专栏: 贝叶斯网络 网络结构学习   版权声明:本文为博主原创文章,遵循CC ...

随机推荐

  1. Newbie_calculations

    拿到这道题是个应用程序,经过上次的经验就跟程序交互了一下,结果根本交互不了,输入什么东西都没有反应 然后打开ida分析发现有几个函数还有一堆的操作数,看到这一堆东西就没心思分析了,后面才知道原来就是要 ...

  2. CodeDesk-一个新款跨平台桌面开发框架

    CodeDesk 的灵感来自 Electron和Photino.这是一个基于 .NET 的开源项目. CodeDesk 的目标是使开发人员能够在跨平台的本机应用程序中使用 Web UI(HTML.Ja ...

  3. 从DPlayer说起,有哪些开源的H5播放器

    引言 ​ H5指的是HTML5,也就是介绍网页播放器(只是列出而已).首先我不是什么大佬,并没有完全体验过以下我会介绍的全部播放器:其次,因为我水平比较低,主要介绍拥有中文文档的播放器,不了解开发的朋 ...

  4. 计算网络之MSTP协议与VRRP协议

    一.MSTP协议 MSTP协议出现是基于STP协议和RSTP协议的,要了解MSTP协议就需要先了解其它两个协议 首先,STP协议是交换机生成树协议,它的出现主要是为了解决二层交换机环路的问题,当多个交 ...

  5. 如何用MySQL快速导入sql数据?

    在 MySQL 中,可以使用多种方法来快速导入 SQL 数据.以下是一些常用的方法和技巧,以帮助你在 MySQL 中快速导入大量的 SQL 数据. 1. 使用 mysql 命令行工具 - 将 SQL ...

  6. 吉特日化MES & SQL Server 无法执行数据库脚本

    打开服务器打算远程执行一下脚本,突发发现数据库无法执行脚本,就想着是不是安装了 海康AGV 控制系统的问题导致,问题如下: 问题截图如下: 报错信息如下: ====================== ...

  7. 使用CEF(七)详解macOS下基于CEF的多进程应用程序CMake项目搭建

    由于macOS下的应用程序结构导致了CEF这样的多进程架构程序在项目结构.运行架构上有很多细节需要关注,这一块的内容比起Windows要复杂的多,所以本文将会聚焦macOS下基于CEF的多进程应用架构 ...

  8. Python+Selenium+Webdriver+unittest 实现登录126邮箱

    第一版:登录 #encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webd ...

  9. Pytorch实现YOLOv3训练自己的数据集

    1.说明: 最近一直在研究深度学习框架PyTorch,就想使用pytorch去实现YOLOv3的object detection.在这个过程中也在各大论坛.贴吧.CSDN等中看了前辈们写的文章,在这里 ...

  10. Flask-SQLAlchemy常用新旧查询语法对比

    https://docs.sqlalchemy.org/en/20/tutorial/data.html 新旧版语法的说明 在2.x的SQLALchemy中,查询语法为: db.session.exe ...