专栏首页一心无二用,本人只专注于基础图像算法的实现与优化。【短道速滑二】古老的基于亮度平均值的自动Gamma校正算法。

【短道速滑二】古老的基于亮度平均值的自动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菜单。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 超像素经典算法SLIC的代码的深度优化和分析。

         现在这个社会发展的太快,到处都充斥着各种各样的资源,各种开源的平台,如github,codeproject,pudn等等,加上一些大型的官方的开源软件...

    用户1138785
  • 【算法随记二】线卷积积分及其在图像增强和特效方面的应用(一)。

      LIC (Line Integral Convolution) is a well-known texture synthesis technique pr...

    用户1138785
  • SSE图像算法优化系列七:基于SSE实现的极速的矩形核腐蚀和膨胀(最大值和最小值)算法。

      因未测试其他作者的算法时间和效率,本文不敢自称是最快的,但是速度也可以肯定说是相当快的,在一台I5机器上占用单核的资源处理 3000 * 2000的灰度...

    用户1138785
  • Java将持续向“高糖”方向发展,你真的了解Java语法糖吗?

    1. 语法糖Syntactic Sugar 糖衣语法,方便开发人员使用,JVM并不识别,会在编译阶段解语法糖,还原为基础语法。

    IT大咖说
  • Sum of Two Integers

    Tyan
  • 一个神奇的Python机器学习交互应用开放框架

    向大家推荐一款机器学习用户交互工具开发框架——Streamlit,可以使机器学习工程师能更轻松地创建自定义应用程序已在他们的模型中与数据进行交互。

    统计学家
  • 力扣 526.优美的排序(next_permutation?)

    链接:https://leetcode-cn.com/problems/beautiful-arrangement

    ACM算法日常
  • 【Codeforces 723C】Polycarp at the Radio 贪心

    n个数,用最少的次数来改变数字,使得1到m出现的次数的最小值最大。输出最小值和改变次数以及改变后的数组。

    饶文津
  • 计算矩阵中全1子矩阵的个数

    最近被我大哥安利了一道算法题, 这道题说难, 还不至于我做不出来, 说简单吧, 我还想不到最优解, 等把最优解告诉我之后, 我还正好能理解. 我甚至曾经怯怯的认...

    烟草的香味
  • 2019 CCPC 秦皇岛 Escape 最大流

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    用户2965768

扫码关注云+社区

领取腾讯云代金券