一、灰度世界算法

① 算法原理

灰度世界算法以灰度世界假设为基础,该假设认为:对于一幅有着大量色彩变化的图像,R,G,B三个分量的平均值趋于同一灰度值Gray。从物理意义上讲,灰色世界法假设自然界景物对于光线的平均反射的均值在总体上是个定值,这个定值近似地为“灰色”。颜色平衡算法将这一假设强制应用于待处理图像,可以从图像中消除环境光的影响,获得原始场景图像。

一般有两种方法确定Gray值

1) 使用固定值,对于8位的图像(0~255)通常取128作为灰度值

2) 计算增益系数,分别计算三通道的平均值avgR,avgG,avgB,则:

Avg=(avgR+avgG+avgB)/3

kr=Avg/avgR , kg=Avg/avgG , kb=Avg/avgB

利用计算出的增益系数,重新计算每个像素值,构成新的图片

② 算法优缺点

这种算法简单快速,但是当图像场景颜色并不丰富时,尤其出现大块单色物体时,该算法常会失效。

③ 算法展示

 def grey_world(nimg):  
nimg = nimg.transpose(2, 0, 1).astype(np.uint32)  
   avgB = np.average(nimg[0])  
   avgG = np.average(nimg[1])  
   avgR = np.average(nimg[2])  
 
   avg = (avgB + avgG + avgR) / 3  
 
   nimg[0] = np.minimum(nimg[0] * (avg / avgB), 255)  
   nimg[1] = np.minimum(nimg[1] * (avg / avgG), 255)  
   nimg[2] = np.minimum(nimg[2] * (avg / avgR), 255)  
   return  nimg.transpose(1, 2, 0).astype(np.uint8)  

① 效果图对比

     

    

第一组图片场景颜色丰富,利用灰度世界假设法校正效果明显;第二组图片中颜色相对单一,校正效果也不是很理想;这也就导致了‘灰度世界假设算法’无法通用.

二、直方图均衡化

① 算法原理

直方图均衡化的基本思想是把原始图的直方图变换为均匀分布的形式,这样就增加了象素灰度值的动态范围从而可达到增强图像整体对比度的效果

假设,一张图像的直方图如下图(左)所示,均衡化后,图像直方图如下图(右)显示

   

② 算法优缺点

直方图均衡化,一般可用于灰度图像的对比增强(如:人脸阴影部位增强);

如果直接对彩色图像R,G,B三通道分别均衡化后再合并,极容易出现颜色不均、失真等问题,所以,一般会将RGB图像转换到YCrCb空间,对Y通道进行均衡化(Y通道代表亮度成分)

③ 算法展示

在python中opencv3提供了能将灰度图直接均衡化的方法:equalizeHist(img),借助这个方法,可以实现彩色图像的均衡化

 def hisEqulColor(img):  
    ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)  
    channels = cv2.split(ycrcb)  
    cv2.equalizeHist(channels[0], channels[0]) #equalizeHist(in,out)  
    cv2.merge(channels, ycrcb)  
    img_eq=cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR)  
   return img_eq  

④ 效果图对比

    

   

                                                       

第一组、第二组彩色图像中均衡化后图片对比原图更清晰,细节突出;第三组灰度图,均衡化在光照不均调节明暗的功能上,效果更明显

三、视网膜-大脑皮层(Retinex)增强算法

① 算法原理

    视网膜-大脑皮层(Retinex)理论认为世界是无色的,人眼看到的世界是光与物质相互作用的结果,也就是说,映射到人眼中的图像和光的长波(R)、中波(G)、短波(B)以及物体的反射性质有关

其中I是人眼中看到的图像,R是物体的反射分量,L是环境光照射分量,(x, y)是二维图像对应的位置

它通过估算L来计算R,具体来说,L可以通过高斯模糊和I做卷积运算求得,用公式表示为:

其中F是高斯模糊的滤波器,“ * ”表示卷积运算

其中σ称为高斯周围空间常数(Gaussian Surround Space Constant),也就是算法中所谓的尺度,对图像处理有比较大的影响,对于二维图像,等于对应位置即:

即:一般认为光照分量是原图像经过高斯滤波后的结果

② 算法优缺点

Retinex算法,从SSR(单尺度Retinex)到MSR(多尺度Retinex)以及到最常用的MSRCR(带颜色恢复的多尺度Retinex);其中色彩恢复主要目的是来调节由于图像局部区域对比度增强而导致颜色失真的缺陷.

先看一组公式:

RMSRCR(x,y)'=G⋅RMSRCR(x,y)+b

RMSRCR (x,y)=C(x,y)RMSR(x,y)

C(x,y)=f[I'(x,y)]=f[I(x,y)/∑I(x,y)]Ci(x,y)=f[Ii′(x,y)]=f[Ii(x,y)∑j=1NIj(x,y)]

f[I'(x,y)]=βlog[αI'(x,y)]=β{log[αI'(x,y)]−log[∑I(x,y)]}

如果是灰度图像,只需要计算一次即可,如果是彩色图像,如RGB三通道,则每个通道均需要如上进行计算

G表示增益Gain(一般取值:5)

b表示偏差Offset(一般取值:25)

I (x, y)表示某个通道的图像

C表示某个通道的彩色回复因子,用来调节3个通道颜色的比例;

f(·)表示颜色空间的映射函数;

β是增益常数(一般取值:46);

α是受控制的非线性强度(一般取值:125)

MSRCR算法利用彩色恢复因子C,调节原始图像中3个颜色通道之间的比例关系,从而把相对较暗区域的信息凸显出来,达到了消除图像色彩失真的缺陷。 处理后的图像局部对比度提高,亮度与真实场景相似,在人们视觉感知下,图像显得更加逼真;但是MSRCR算法处理图像后,像素值一般会出现负值。所以从对数域r(x, y)转换为实数域R(x, y)后,需要通过改变增益Gain,偏差Offset对图像进行修正

关于Retinex算法更多的细节,可以查看https://www.cnblogs.com/wangyong/p/8665434.html

③ 算法展示

④  效果图对比

      

(原图)                                                                                           (SSR)

     

(MSR)                                                                            (MSRCR)

      

(原图)                                                                                     (SSR)

      

(MSR)                                                                                    (MSRCR)

上面的两组图片,可以看到第一组的效果明显,第二组的效果很差;同时可和‘灰度世界算法’的结果进行比较;一般认为,Retinex算法比较适合航空图片的处理,‘去雾’效果显著。

四、自动白平衡(AWB)

① 算法原理

用一个简单的概念来解释什么是白平衡:假设,图像中R、G、B最高灰度值对应于图像中的白点,最低灰度值的对应于图像中最暗的点;其余像素点利用(ax+b)映射函数把彩色图像中R、G、B三个通道内的像素灰度值映射到[0.255]的范围内.

白平衡的本质是让白色的物体在任何颜色的光源下都显示为白色,这一点对人眼来说很容易办到,因为人眼有自适应的能力,只要光源的色彩不超出一定的限度,就可以自动还原白色。但相机就不同了,无论是图像传感器还是胶卷都会记录光源的颜色,白色的物体就会带上光源的颜色,白平衡所要做的就是把这个偏色去掉。

② 算法优缺点

自动白平衡是一个很复杂的问题,目前还没有一个万能的方法可以解决所有场景的白平衡问题

截止2017年,出现不少利用神经网络实现自动白平衡的算法,也会有专门的文档对这部分进行详细的介绍。

③ 算法展示

利用Lab颜色空间,对图片进行自动白平衡操作.

③ 效果图对比

      

    

可以看出,这两组效果图和‘灰度世界假设’算法得出的效果图很类似,主要是因为上述的白平衡算法也是基于‘灰度世界’这个假设下的

五、自动色彩均衡(ACE)

① 算法原理

ACE算法源自retinex算法,可以调整图像的对比度,实现人眼色彩恒常性和亮度恒常性,该算法考虑了图像中颜色和亮度的空间位置关系,进行局部特性的自适应滤波,实现具有局部和非线性特征的图像亮度与色彩调整和对比度调整,同时满足灰色世界理论假设和白色斑点假设。

第一步:对图像进行色彩/空域调整,完成图像的色差校正,得到空域重构图像;

式中,Rc 是中间结果,Ic(p)-Ic(j)为两个不同点的亮度差,d(p,j)表示距离度量函数,r(*)为亮度表现函数,需是奇函数;这一步可以适应局部图像对比度,r(*)能够放大较小的差异,并丰富大的差异,根据局部内容扩展或者压缩动态范围。一般得,r(*)为:

第二步:对校正后的图像进行动态扩展。ACE算法是对单一色道进行的,对于彩色图片需要对每一个色道分别处理

其中存在一种简单的线性扩展:

R(x)=round[127.5+w*Rc(p)],其中,w表示线段[(0,mc),(255,Mc)]的斜率,且有:

Mc=min[Rc(p)],Mc=max[Rc(p)]

第三步:利用下面的公式将R(x)展到[0,1]之间,得到增强后的通道

②算法优缺点

ACE的增强效果普遍比retinex好。需要注意的是,ACE中当前像素是与整个图像的其他像素做差分比较,计算复杂度非常非常高,这也是限制它应用的最主要原因。

所以,一般算法中,会通过指定采样数来代替与整副图像的像素点信息进行差分计算,减少运算量,提高效率。

③ 算法展示

 #饱和函数  
def calc_saturation(diff,slope,limit):  
    ret = diff * slope  
    if ret > limit:  
        ret = limit  
    elif (ret < (-limit)):  
      ret = -limit  
    return ret  
 
def automatic_color_equalization(nimg, slope=10, limit=1000, samples=500):  
 
    nimg = nimg.transpose(2, 0, 1)  
  
    #Convert input to an ndarray with column-major memory order(仅仅是地址连续,内容和结构不变)  
    nimg = np.ascontiguousarray(nimg, dtype=np.uint8)       width=nimg.shape[2]  
    height=nimg.shape[1]  
  
    cary=[]  
  
    #随机产生索引  
    for i in range(0,samples):  
        _x=random.randint(0,width)%width  
        _y=random.randint(0,height)%height  
 
       dict={"x":_x,"y":_y}  
       cary.append(dict)  
 
 
   mat=np.zeros((3,height,width),float)  
  
   r_max = sys.float_info.min  
   r_min = sys.float_info.max  
 
   g_max = sys.float_info.min  
   g_min = sys.float_info.max  
  
   b_max = sys.float_info.min  
   b_min = sys.float_info.max  
  
  for i in range(height):  
        for j in range(width):  
            r=nimg[0,i,j]  
            g=nimg[1,i,j]  
            b=nimg[2,i,j]               r_rscore_sum = 0.0  
            g_rscore_sum = 0.0  
            b_rscore_sum = 0.0  
            denominator = 0.0  
  
           for _dict in cary:  
                _x=_dict["x"] #width  
                _y=_dict["y"] #height  
  
                #计算欧氏距离  
               dist=np.sqrt(np.square(_x-j)+np.square(_y-i))  
                if (dist < height / 5):  
                    continue;  
 
               _sr=nimg[0,_y,_x]  
                _sg=nimg[1,_y,_x]  
                _sb=nimg[2,_y,_x]  
  
                r_rscore_sum +=calc_saturation(int(r) - int(_sr),slope,limit) / dist  
                g_rscore_sum +=calc_saturation(int(g) - int(_sg),slope,limit) / dist  
                b_rscore_sum +=calc_saturation(int(b) - int(_sb),slope,limit) / dist  
 
                denominator += limit / dist  
 
            r_rscore_sum = r_rscore_sum / denominator  
            g_rscore_sum = g_rscore_sum / denominator  
            b_rscore_sum = b_rscore_sum / denominator  
  
            mat[0,i,j]=r_rscore_sum  
            mat[1,i,j]=g_rscore_sum  
            mat[2,i,j]=b_rscore_sum  
 
            if r_max<r_rscore_sum:  
                r_max=r_rscore_sum  
            if r_min>r_rscore_sum:  
                r_min=r_rscore_sum  
  
            if g_max<g_rscore_sum:  
                g_max=g_rscore_sum  
            if g_min>g_rscore_sum:  
                g_min=g_rscore_sum  
  
            if b_max<b_rscore_sum:  
                b_max=b_rscore_sum  
            if b_min>b_rscore_sum:  
                b_min=b_rscore_sum  
  
   for i in range(height):  
        for j in range(width):  
           nimg[0, i, j] = (mat[0, i, j] - r_min) * 255 / (r_max - r_min)  
           nimg[1, i, j] = (mat[1, i, j] - g_min) * 255 / (g_max - g_min)  
           nimg[2, i, j] = (mat[2, i, j] - b_min) * 255 / (b_max - b_min)  
  
   return nimg.transpose(1, 2, 0).astype(np.uint8)

④ 效果图对比

        

      

总结:查看各种传统算法的效果图,ACE自动色彩均衡算法具有比较好的普遍性和效果,当然,对于一些图片ACE也不能得到很好地效果,所以,这就需要我们不断的去深入研究和学习,接下来会学习神经网络在色彩恒常性方面的应用并进行效果对比。

作为一枚技术小白,写这篇笔记的时候参考了很多博客论文,在这里表示感谢,同时,转载请注明出处......

光照问题之常见算法比较(附Python代码)的更多相关文章

  1. XGBoost参数调优完全指南(附Python代码)

    XGBoost参数调优完全指南(附Python代码):http://www.2cto.com/kf/201607/528771.html https://www.zhihu.com/question/ ...

  2. 建模分析之机器学习算法(附python&R代码)

    0序 随着移动互联和大数据的拓展越发觉得算法以及模型在设计和开发中的重要性.不管是现在接触比较多的安全产品还是大互联网公司经常提到的人工智能产品(甚至人类2045的的智能拐点时代).都基于算法及建模来 ...

  3. 机器学习经典分类算法 —— k-近邻算法(附python实现代码及数据集)

    目录 工作原理 python实现 算法实战 约会对象好感度预测 故事背景 准备数据:从文本文件中解析数据 分析数据:使用Matplotlib创建散点图 准备数据:归一化数值 测试算法:作为完整程序验证 ...

  4. 机器学习经典分类算法 —— k-均值算法(附python实现代码及数据集)

    目录 工作原理 python实现 算法实战 对mnist数据集进行聚类 小结 附录 工作原理 聚类是一种无监督的学习,它将相似的对象归到同一个簇中.类似于全自动分类(自动的意思是连类别都是自动构建的) ...

  5. Python——EM(期望极大算法)教学(附详细代码与注解)

    今天,我们详细的讲一下EM算法. 前提准备 Jupyter notebook 或 Pycharm 火狐浏览器或谷歌浏览器 win7或win10电脑一台 网盘提取csv数据 需求分析 实现高斯混合模型的 ...

  6. tf–idf算法解释及其python代码实现(下)

    tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...

  7. tf–idf算法解释及其python代码实现(上)

    tf–idf算法解释 tf–idf, 是term frequency–inverse document frequency的缩写,它通常用来衡量一个词对在一个语料库中对它所在的文档有多重要,常用在信息 ...

  8. 神经网络BP算法C和python代码

    上面只显示代码. 详BP原理和神经网络的相关知识,请参阅:神经网络和反向传播算法推导 首先是前向传播的计算: 输入: 首先为正整数 n.m.p.t,分别代表特征个数.训练样本个数.隐藏层神经元个数.输 ...

  9. KNN算法原理(python代码实现)

    kNN(k-nearest neighbor algorithm)算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性 ...

随机推荐

  1. HDU-3746-KMP理解失配

    这个有点意思,要理解失配数组 题意是要计算出需要构造成循环节相连的最小个数 利用失配构造函数求出单个循环节,然后计算出需要的加上的珠子个数 #include <cstdio> #inclu ...

  2. mybatis There is no getter for property named '*' in 'class java.lang.String

    1.原因 server层     xxxx.get("1234") map <if test="aaa != null and aaa.id != null and ...

  3. 洛谷 P2764 最小路径覆盖问题 解题报告

    P2764 最小路径覆盖问题 问题描述: 给定有向图\(G=(V,E)\).设\(P\) 是\(G\) 的一个简单路(顶点不相交)的集合.如果\(V\) 中每个顶点恰好在\(P\) 的一条路上,则称\ ...

  4. luogu2178/bzoj4199 品酒大会 (SA+单调栈)

    他要求的就是lcp(x,y)>=i的(x,y)的个数和a[x]*a[y]的最大值 做一下后缀和,就只要求lcp=i的了 既然lcp(x,y)=min(h[rank[x]+1],..,[h[ran ...

  5. 解决Ubuntu17.04以上系统,yarn init报错

    安装yarn的时候老是装了个cmdtes的东西,官网是说删掉cmdtest重装就行,但是真没用. 正确的解决办法应该是像这位说的一样,先修改一下源,sudo apt update再下载,就能下载到真正 ...

  6. Windows 10中设置自动登录

    步骤 使用WinKey+R打开运行,输入netplwiz. 在打开的用户账户对话框-用户选项卡-取消勾选要使用本计算机,用户必须输入用户名和密码(E). 点击应用按钮,在弹出的自动登录对话框中输入相关 ...

  7. BeautifulSoup 获取无标签文本

    比如: <p>aaa</p>bbb <p>ccc</p>ddd 怎么获取bbb和ddd呢? 结果:

  8. HDFS集群PB级数据迁移方案-DistCp生产环境实操篇

    HDFS集群PB级数据迁移方案-DistCp生产环境实操篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 用了接近2个星期的时间,终于把公司的需要的大数据组建部署完毕了,当然,在部 ...

  9. GO语言的进阶之路-面向对象编程

    GO语言的进阶之路-面向对象编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 当你看完这篇文章之时,我可以说你的Golang算是入门了,何为入门?就是你去看Docker 源码能看 ...

  10. linux的一个find命令配合rm删除某天前的文件

    语句写法: find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; 例1: 将/usr/local/backups目录下所有10天前 ...