自动色彩均衡算法(ACE)原理及实现-程序员宅基地

技术标签: 自动色彩均衡  图像增强与滤波  机器视觉与图像处理  

前注:ACE在图像处理方面可以有两种表示,一种是本篇要说的:Automatic Color Equalization,即自动彩色均衡;还有一种是:Adaptive Contrast Enhancement,即自适应对比度增强 。不要搞混了~_~

高动态范围图像处理:

高动态范围图像是指在一幅图像中,既有明亮的区域又有阴影区域,为了使细节清晰,需要满足以下几点:

(1)对动态范围具有一定的压缩能力;

(2)对亮暗区域的细节有一定的显示能力;

(3)满足上面条件基础上不破坏图像的清晰度。

对于高动态范围处理,基于人眼视觉系统(HSV)在颜色连续和亮度连续方面得到较好的满足。

自动色彩均衡算法原理:

Rizzi等依据Retinex理论提出了自动颜色均衡算法,该算法考虑了图像中颜色和亮度的空间位置关系,进行局部特性的自适应滤波,实现具有局部和非线性特征的图像亮度与色彩调整和对比度调整,同时满足灰色世界理论假设和白色斑点假设。

ACE算法包括两个步骤:


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

(1)

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

     

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

其中,一种简单的线性扩展可以表示为:


还可以将其映射到[0,255]的空间中:

          (5)

通过上面的操作,ACE可看成是人类视觉系统的简化模型,其增强过程是与人的感知是一致的。

自动彩色均衡算法改进:

式(1)算法复杂度较高,对于一副像素数为N的图像,需要执行O(N2)级次非线性映射计算,图像尺寸越大,耗时越多,所以针对式(1)产生了许多加速改进算法。例如:LLLUT加速策略【4】,参考【3】将ACE转换为对规范直方图均衡化的一种平滑和局部修正的方法,并给出了求解最优模型:


其中,

对于改进方法,可以考虑的因素:
1)其他的坡度函数Sa(t),多项式函数逼近;


2)除了1/||x-y||外的权重函数的选择;
3)在求和的过程中,y可以限制在一个小窗口中;
4)L(x)的一些其他的方法;

程序下载地址:http://www.ipol.im/pub/art/2012/g-ace/

另外,可以参照参考[8]的python程序,这里po一下:

import cv2  
import numpy as np  
import math  

def stretchImage(data, s=0.005, bins = 2000):    #线性拉伸,去掉最大最小0.5%的像素值,然后线性拉伸至[0,1]  
    ht = np.histogram(data, bins);  
    d = np.cumsum(ht[0])/float(data.size)  
    lmin = 0; lmax=bins-1  
    while lmin<bins:  
        if d[lmin]>=s:  
            break  
        lmin+=1  
    while lmax>=0:  
        if d[lmax]<=1-s:  
            break  
        lmax-=1  
    return np.clip((data-ht[1][lmin])/(ht[1][lmax]-ht[1][lmin]), 0,1)  

g_para = {}  
def getPara(radius = 5):                      #根据半径计算权重参数矩阵  
    global g_para  
    m = g_para.get(radius, None)  
    if m is not None:  
        return m  
    size = radius*2+1  
    m = np.zeros((size, size))  
    for h in range(-radius, radius+1):  
        for w in range(-radius, radius+1):  
            if h==0 and w==0:  
                continue  
            m[radius+h, radius+w] = 1.0/math.sqrt(h**2+w**2)  
    m /= m.sum()  
    g_para[radius] = m  
    return m  

def zmIce(I, ratio=4, radius=300):                     #常规的ACE实现  
    para = getPara(radius)  
    height,width = I.shape  
    zh,zw = [0]*radius + range(height) + [height-1]*radius, [0]*radius + range(width)  + [width -1]*radius  
    Z = I[np.ix_(zh, zw)]  
    res = np.zeros(I.shape)  
    for h in range(radius*2+1):  
        for w in range(radius*2+1):  
            if para[h][w] == 0:  
                continue  
            res += (para[h][w] * np.clip((I-Z[h:h+height, w:w+width])*ratio, -1, 1))  
    return res  

def zmIceFast(I, ratio, radius):                #单通道ACE快速增强实现  
    height, width = I.shape[:2]  
    if min(height, width) <=2:  
        return np.zeros(I.shape)+0.5  
    Rs = cv2.resize(I, ((width+1)/2, (height+1)/2))  
    Rf = zmIceFast(Rs, ratio, radius)             #递归调用  
    Rf = cv2.resize(Rf, (width, height))  
    Rs = cv2.resize(Rs, (width, height))  

    return Rf+zmIce(I,ratio, radius)-zmIce(Rs,ratio,radius)      

def zmIceColor(I, ratio=4, radius=3):               #rgb三通道分别增强,ratio是对比度增强因子,radius是卷积模板半径  
    res = np.zeros(I.shape)  
    for k in range(3):  
        res[:,:,k] = stretchImage(zmIceFast(I[:,:,k], ratio, radius))  
    return res  

if __name__ == '__main__':  
    m = zmIceColor(cv2.imread('3.jpg')/255.0)*255  
    cv2.imwrite('zmIce.jpg', m)  

参考:

  1. http://www.ipol.im/pub/art/2012/g-ace/
  2. 《ACE: An automatic color equalization algorithm》
  3. 《Automatic Color Enhancement (ACE) and its FastImplementation》[J].IPOL
  4. 《A local linear lut method for increasing the speed of generic image fiLLLUTering algorithm》[R].Technical Report
  5. 《Perceptual Color Correction Through Varia-tional Techniques》[J].IEEE
  6. 《自动色彩均衡算法的快速优化》[J].武汉大学学报
  7. http://blog.csdn.net/u013626386/article/details/47808761
  8. http://blog.csdn.net/zmshy2128/article/details/53470357   --python
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/piaoxuezhong/article/details/78357815

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签