伽马校正_预估校正算法

伽马校正_预估校正算法自动伽马校正(AutoGammaCorrection)算法目录文章目录自动伽马校正(AutoGammaCorrection)算法目录理论代码实现参考资料理论在对图像进行处理过程中,查找到一篇对图像进行自动gamma校正的论文,论文名称及链接见参考文献1.文章的核心描述如下:Averageofbrightnessissimpleelementthatcanbecomputedintheleastamountoftime.Basicapproachin

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

自动伽马校正(Auto Gamma Correction)算法

微信公众号:幼儿园的学霸

目录

理论

在对图像进行处理过程中,查找到一篇对图像进行自动gamma校正的论文,论文名称及链接见参考文献1.

文章的核心描述如下:

Average of brightness is simple element that can be computed in the least amount of time. Basic approach in this article present a technique to estimate appropriate gamma based on average brightness. …, We suppose a gamma which changes average of brightness to 1/2, …

其大概意思是:假定一副合理的图像其所有像素(归一化后)的均值应该在0.5左右,那么自动伽马校正的伽马值就要使得目标图像向这个目标前进。
假设X是图像的平均值,那么自动伽马校正所需要的伽马值应该基于下列公式进行计算:
公式
公式描述

根据论文描述:

This paper proposes a method which estimates a power that transport average amount of brightness to center of histogram.

即通过自动gamma校正后图像的灰度直方图将向中心进行偏移。

代码实现

按照上述公式,可以很快实现该算法。代码如下。
1.在实现过程中,采用了查找表的思想,以加快图像处理速度。
2.针对多通道图像,对各通道的gamma再次进行求均值,作为gamma校正的gamma值,以避免多通道图像的偏色现象。该修改在原论中并不存在。

//
// Created by liheng on 11/22/20.
//

#include <iostream>
#include <chrono>
#include <opencv2/opencv.hpp>

//自动Gamma校正算法
//Input Param:src--输入图像,3 channels or 1channels
//Output Param:dst--归一化后的图像,type as src
//Return:   null
void AutoGammaCorrection(const cv::Mat &src, cv::Mat &dst)
{
    const int channels = src.channels();
    const int type = src.type();
    assert( type==CV_8UC1 || type==CV_8UC3 );


    //======计算gamma值========//
    auto mean = cv::mean(src);//求均值
    mean[0] = std::log10(0.5) / std::log10(mean[0]/255);//gamma = -0.3/log10(X)
    if( 3==channels )
    {
        mean[1] = std::log10(0.5) / std::log10(mean[1]/255);//gamma = -0.3/log10(X)
        mean[2] = std::log10(0.5) / std::log10(mean[2]/255);//gamma = -0.3/log10(X)

        //多通道图像,对求得的gamm再次平均,避免偏色现象
        auto mean3 = (mean[0]+mean[1]+mean[2])/3;
        mean[0]=mean[1]=mean[2] = mean3;
    }



    //=======计算gamma查找表,减少计算量=======//
    //查找表,数组的下标对应图片里面的灰度值
    //lut(0,10)=(50,60,70)表示通道1灰度值为10的像素其对应的值为50;
    // 通道2灰度值为10的像素其对应的值为60;
    // 通道3灰度值为10的像素其对应的值为70
    cv::Mat lut(1,256,src.type());
    if( 1==channels )
    {
        for(int i=0; i<256;++i)//灰度等级[0,255]
        {
            //将灰度值归一化0-1之间
            float Y = i*1.0f/255;// or Y=i*0.00392;
            //求该灰度值gamma校正后的值
            Y = std::pow(Y,mean[0]);

            lut.at<unsigned char>(0,i) = cv::saturate_cast<unsigned char>(Y*255);
        }
    }
    else if(3==channels)
    {
        for(int i=0; i<256;++i)//灰度等级[0,255]
        {
            //将灰度值归一化0-1之间
            float Y = i*1.0f/255;// or Y=i*0.00392;
            //求该灰度值gamma校正后的值
            auto B = cv::saturate_cast<unsigned char>(std::pow(Y,mean[0])*255);
            auto G = cv::saturate_cast<unsigned char>(std::pow(Y,mean[1])*255);
            auto R = cv::saturate_cast<unsigned char>(std::pow(Y,mean[2])*255);

            lut.at<cv::Vec3b>(0,i) = cv::Vec3b(B,G,R);
        }
    }


    //=========利用查找表进行校正==========//
    cv::LUT(src,lut,dst);
}

int main()
{
    std::string image_path = "../autogamma.png";
    cv::Mat src = cv::imread(image_path,cv::IMREAD_COLOR);
    cv::imshow("src",src);

    cv::Mat dst1,dst2;
    AutoGammaCorrection(src,dst1);
    src.convertTo(src,CV_32FC3,1.0/255);
    cv::pow(src,0.7,dst2);
    cv::normalize(dst2,dst2,0,255,cv::NORM_MINMAX);
    cv::convertScaleAbs(dst2,dst2);

    cv::imshow("dst1",dst1);
    cv::imshow("dst2",dst2);
    cv::waitKey(0);
}

效果如下:

类别 图像 直方图
原图 原图 原直方图
自动gamma校正 自动gamma校正 自动gamma校正直方图
手动gamma校正 手动gamm校正 手动校正gamma直方图

可以看到,
1.自动gamma校正通过自动计算gamma值来调整图像,比手工设定gamma值要明显方便很多。
2.经过自动gamma校正后的图像,其直方图的中心相对原图向中心进行了平移。

参考资料

1.自动伽马校正原英文论文 Automatic gamma correction based on average of
brightness



下面的是我的公众号二维码图片,按需关注。
图注:幼儿园的学霸

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/190046.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • onResume的作用

    onResume的作用描述:今天在做一个功能的时候,从Aactivity跳到Bactivity。由于Bactivity的操作,影响了Aactivity的数据,所以再回到A的时候,需要A能够进行刷新操作。但是默认跳回去的时候,A界面还是上次那个。解决方案:重写Aactivity的onResume()方法,在onResume()方面里进行刷新操作。因为按照activity的生命周期模型,当activ

    2022年6月2日
    59
  • SQL语句大全实例

    SQL语句实例 表操作  例1 对于表的教学管理数据库中的表STUDENTS,可以定义如下:  CREATE TABLE STUDENTS  (SNO     NUMERIC(6,0)NOTNULL  SNAME   CHAR(8)NOTNULL  AGE     NUMERIC(3,0)  SEX

    2022年4月3日
    66
  • 3dmax建模前景_3d建模师未来发展前景

    3dmax建模前景_3d建模师未来发展前景简单来说,没前途。本来不想说这个话题的,但是想了好久,觉得还是来说两句。我本人是从事建筑表现效果图行业的,主要用的软件就是3DMAX+VRay+PS。正式从业到现在已经三年了,半路出家。3DMAX这个软件深入很多个行业,广告、影视、工业设计、建筑设计、三维动画、多媒体制作、游戏、以及工程可视化等。但其实没有哪个行业是只用这一款软件的,在不少行业3DMAX也逐步被更新的软件替代。MAX强大在它是一个平台,所以他的上限很高,比一般的软件都要高很多,但是下限也很高,不是那么容易上手。.

    2022年9月11日
    0
  • Android uvc_文明6行星探索

    Android uvc_文明6行星探索文章选取android下linux-3.10作为分析对象,具体的UVC初始化过程可以参考csdn大神写的博客,地址是:http://blog.csdn.net/orz415678659。uvc加载摄像头的过程无非是初始化设备,加载设备,获取设备相关参数并加载相关参数到buffer,此时就已经将视频和控制参数加载到buffer了,这篇文章主要关注的是控制相关的参数。需要关注的两个核心文件是:…

    2025年6月24日
    0
  • Elastic Job 入门详解

    Elastic Job 入门详解Elastic job是当当网架构师张亮,曹昊和江树建基于Zookepper、Quartz开发并开源的一个Java分布式定时任务,解决了Quartz不支持分布式的弊端。Elastic job主要的功能有支持弹性扩容,通过Zookepper集中管理和监控job,支持失效转移等,这些都是Quartz等其他定时任务无法比拟的。

    2022年6月17日
    30
  • 数据库概念设计与逻辑设计[通俗易懂]

    数据库概念设计与逻辑设计[通俗易懂]一、概念设计概念设计的目的就是为了建立概念数据模型,概念数据模型也称为高级数据模型,之所以称为高级数据模型是因为它更接近于人的思维,而不是机器的思维,相比于关系模型更容易理解,此处的高级和低级的概念,与程序语言领域的高低级是一样的。我们通常称Java语言为高级语言,汇编语言为低级语言,是因为高级语言对于我们而言要比汇编语言更容易理解。关于概念数据模型,我们一般都会采用E-R图进行描述。E-R图的规则如下:1.实体采用矩形框,联系采用菱形框,属性采用椭圆形框。2.实体、联系、属性必须使用文字描

    2022年10月9日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号