本文共享自华为云社区《[Python图画处理] 三十.图画预处理之图画去雾详解(ACE算法和暗通道先验去雾算法)丨【拜托了,物联网!】》,作者:eastmount 。
一.图画去雾
随着社会的发展,环境污染逐渐加剧,越来越多的城市频繁呈现雾霾,这不只给人们的身体健康带来危害,还给那些依赖图画信息的核算机视觉系统形成了不良影响,因为在雾天收集到的图画比照度和饱和度均较低,色彩易发生偏移与失真等。因而,寻觅一种简略有用的图画去雾办法,对核算机视觉的后续研讨至关重要。
该部分首要从下列几篇论文摘取对图画去雾算法进行遍及,引证及参阅中文论文:
- 魏红伟, 等. 图画去雾算法研讨综述[J]. 软件导刊, 2021.
- 王道累, 等. 图画去雾算法的综述及剖析[J]. 图学学报, 2021.
- OpenCV图画增强万字详解(直方图均衡化、部分直方图均衡化、主动色彩均衡化)- Eastmount
图画增强(Image Enhancement)是指依照某种特定的需求,杰出图画中有用的信息,去除或许削弱无用的信息。图画增强的意图是使处理后的图画更适合人眼的视觉特性或易于机器辨认。 在医学成像、遥感成像、人物拍摄等范畴,图画增强技能都有着广泛的运用。图画增强同时能够作为方针辨认、方针盯梢、特征点匹配、图画交融、超分辨率重构等图画处理算法的预处理算法。
近些年来,呈现了很多的单幅图画去雾算法,运用比较广泛的有:
- 直方图均衡化去雾算法
- Retinex去雾算法
- 暗通道先验去雾算法
- 依据卷积神经网络的DehazeNet去雾算法
其首要能够分为 3 类:依据图画增强的去雾算法、依据图画康复的去雾算法和依据 CNN 的去雾算法。
(1) 依据图画增强的去雾算法
经过图画增强技能杰出图画细节,进步比照度,使之看起来愈加明晰,这类算法的适用性较广。具体的算法有:
-
Retinex 算法
依据成像原理,消除了反射重量的影响,到达了图画增强去雾的作用
-
直方图均衡化算法
使图画的像素分布愈加均匀,扩大了图画的细节
-
偏微分方程算法
将图画视作一个偏微分方程,经过核算梯度场进步比照度
-
小波变换算法
对图画进行分解,扩大有用的部分
此外,在这类算法的基础上呈现了很多的依据图画增强原理的改善算法。
(2) 依据图画康复的去雾算法
首要是依据大气散射物理学模型,经过对很多有雾图画和无雾图画进行观察总结,得到其间存在的一些映射联系,然后依据有雾图画的构成进程来进行逆运算,然后康复明晰图画。其间最经典的要属何恺明大佬提出的:
-
暗通道先验去雾算法
经过对很多无雾图画进行特征剖析,找到了无雾图画与大气散射模型中某些参数的先验联系。该算法杂乱度低,去雾作用好,因而在其基础上呈现了很多依据暗通道先验的改善算法。
(3) 依据CNN的去雾算法
运用 CNN 建立一个端到端的模型,经过有雾图画康复出无雾图画,目前运用神经网络进行去雾的算法首要有两种思路:
- 运用 CNN 生成大气散射模型的某些参数,然后再依据大气散射模型来康复无雾图画
- 运用 CNN (例如 GAN)直接依据含糊图画生成无雾的明晰图画
CNN 因其强壮的学习能力在多个范畴得到运用,因而也呈现了选用 CNN 进行去雾的算法。2016年CAI等首次提出了一种名为DehazeNet的去雾网络,用于估计有雾图画的透射率。DehazeNet 将有雾的含糊图画作为输入,输出其透射率,依据大气散射模型理论康复出无雾的明晰图画。
下图是别离对直方图均衡化、暗通道先验去雾、DehazeNet和AOD-Net去雾算法进行测试,试验成果如图所示。由图可知,依据图画增强的直方图均衡化算法的去雾图画比照度显着增强,因为不考虑降质原因,在增加比照度的同时也对噪声进行了扩大,呈现细节丢失与色彩偏差现象。依据物理模型的暗通道去雾算法、依据神经网络的 DehazeNet 和 AOD-Net 算法的去雾作用较直方图均衡化算法更佳。
其他去雾算法比照成果如下图所示,比如城市和路途有无图画去雾作用比照。
最终,正如总结王道累教师总结的相同,目前针对有雾图画去雾的算法首要是从依据图画增强、图画康复和 CNN 3 个方向进行的。
- 依据图画增强的办法不考虑有雾图画的构成进程,而是直接经过杰出图画的细节,进步比照度等方式,然后使有雾图画看上去愈加明晰。
- 依据图画康复的办法则是寻找图画降质的物理进程,经过物理模型康复出明晰的图画。
- 依据 CNN 的办法则是运用神经网络强壮的学习能力,寻觅有雾图画与图画康复物理模型中某些系数的映射联系或许运用 GAN,依据有雾图画康复出无雾的明晰图画。
上述 3 类去雾算法关于雾天图画都有着显着的去雾作用,尽管其在实践生活中已经得到了广泛的运用,但下述几点仍有可能是往后图画去雾范畴的研讨重点和难点:
-
愈加实在的雾天图画数据集
选用神经网络进行去雾的算法在作用上好于图画增强和康复的办法,可是因为在天然界中很难拍摄到一组布景相同的有雾图画和无雾图画,因而目前训练神经网络所选用的数据集均是经过合成得到的,尽管能够在必定程度上拟合天然环境,可是仍然存在着一些差距。所以目前急需一种由在实在环境中获取到的具有相同布景的有雾图画和无雾图画构建的数据集,来进步神经网络去雾算法的鲁棒性和稳定性。 -
愈加简洁的去雾算法
目前各类算法能够有用去除单幅图画上的雾霾,但相对较好的算法都存在着时刻杂乱度高的问题,很难运用到视频去雾或许需求较多的杂乱任务中去。 -
鲁棒性更强的去雾算法
上述算法都只对图画上存在的均匀的薄雾有较好的去雾作用,关于浓雾或许分布不均的团雾则作用较差,因而找到一种适用规模更广的去雾办法将会是一个极具挑战性的课题。
二.ACE去雾算法
1.算法原理
该部分首要介绍参阅作者书本以及相关论文进行叙述,简略介绍ACE算法的原理知识。假如读者想详细了解其原理,引荐阅览英文原文,详见下面的参阅文献,都是大佬。
引证及参阅中文论文:
尹胜楠, 等. 依据快速ACE算法的视觉里程计图画增强办法[J]. 电子测量与仪器学报, 2021.
李景文, 等. 依据暗通道先验改善的主动色彩均衡算法[J]. 科学技能与工程, 2019.
杨秀璋, 等. 一种改善的杂乱环境下条形码图画增强和定位算法[J]. 现代核算机, 2020.
OpenCV—python 主动色彩均衡(ACE)- SongpingWang
OpenCV图画增强万字详解(直方图均衡化、部分直方图均衡化、主动色彩均衡化)- Eastmount
英文原文:
- www.ipol.im/pub/art/201…
Automatic Color Enhancement (ACE) and its Fast Implementation- www.sciencedirect.com/science/art…
A new algorithm for unsupervised global and local color correction(原作者Rizzi大佬)
图画比照度增强的算法在很多场合都有用处,特别是在医学图画中,这是因为在很多疾病的确诊中,医学图画的视觉检查时很有必要的。Retinex算法是代表性的图画增强算法,它依据人的视网膜和大脑皮层模仿对物体色彩的波长光线反射能力而构成,对杂乱环境下的一维条码具有必定规模内的动态压缩,对图画边缘有着必定自适应的增强。
主动色彩均衡(Automatic Color Enhancement,ACE) 算法是Rizzi大神在Retinex算法的理论上提出的,它经过核算图画方针像素点和周围像素点的明暗程度及其联系来对终究的像素值进行校正,完成图画的比照度调整,发生相似人体视网膜的色彩恒常性和亮度恒常性的均衡,具有很好的图画增强作用。
ACE算法包含两个步骤:
-
一是对图画进行色彩和空域调整,完结图画的色差校正,得到空域重构图画。
模仿视觉系统的侧按捺性和区域自适应性,进行色彩的空域调整。侧按捺性是一个生理学概念,指在某个神经元受到影响而发生振奋时,再影响附近的神经元,后者所发生的振奋对前者发生的按捺作用。
-
二是对校正后的图画进行动态扩展。
对图画的动态规模进行大局调整,并使图画满意灰度世界理论和白斑点假定。算法针对单通道,再延伸运用到RGB五颜六色空间的3通道图画,即对3个通道别离处理再进行整合完结。
(1) 区域自适应滤波
输入图画I(灰度图为例),该步是对单通道图画I中所有点p的区域自适应滤波,得到完结色差校正,空域重构后的中心成果图画,核算公式如下:
式中:Ic-Ic(j)为p、j两个像素点间灰度差值,表达拟生物学上的侧按捺性;d(p,j)表明间隔度量函数,运用两点间的欧氏间隔,作用上操控点j对p的影响权重,映射出滤波的区域适应性;Sa(x)是亮度体现函数(奇函数),本文算法挑选经典Saturation函数。
不同亮度函数和参数的挑选操控了比照度增强的程度,经典的Saturation函数在饱和前取越大的斜率,成果的比照度增强越显着,如图2所示,极限情况是sign函数形式,而Sign函数因为无差别过度增强扩大,导致噪声相同得到扩大作用不佳,终究挑选Saturation函数作为相对亮度体现函数。公式如下:
(2) 色调重整拉伸,对图画动态扩展
将式(1)中得到的中心量拉伸映射到 [0, 255] 中,占满动态规模 [0, 255](8位灰度图画),核算公式如下,式中:[minR,maxR]是中心量L(x)的悉数界说域,该项使图画到达大局白平衡。
下图是条形码图画进行ACE图画增强后的作用图,经过图画增强后的图(b)比照度更强,改善了原图画的明暗程度,增强的同时保持了图画的实在性。
ACE算法英文介绍如下:
试验比照作用如下图所示,咱们在写该主题论文的时候,留意和传统办法比照。
2.代码完成
因为OpenCV中暂时没有ACE算法包,下面的代码是借鉴“zmshy2128”教师的文章,修正完成的五颜六色直方图均衡化处理。后面有机会作者详细剖析其代码完成进程。
-
主动色彩均衡(ACE)快速算法 – zmshy2128教师
–– coding: utf-8 ––
By:Eastmount CSDN 2021-03-12
惨zmshy2128教师文章并修正成Python3代码
import cv2 import numpy as np import math import matplotlib.pyplot as plt
#线性拉伸处理 #去掉最大最小0.5%的像素值 线性拉伸至[0,1] def stretchImage(data, s=0.005, bins = 2000):
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(h2+w2) m /= m.sum() g_para[radius] = m return m#常规的ACE完成 def zmIce(I, ratio=4, radius=300):
para = getPara(radius) height,width = I.shape zh = [] zw = [] n = 0 while n < radius: zh.append(0) zw.append(0) n += 1 for n in range(height): zh.append(n) for n in range(width): zw.append(n) n = 0 while n < radius: zh.append(height-1) zw.append(width-1) n += 1 #print(zh) #print(zw)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
#单通道ACE快速增强完成 def zmIceFast(I, ratio, radius): print(I) height, width = I.shape[:2] if min(height, width) <=2: return np.zeros(I.shape)+0.5 Rs = cv2.resize(I, (int((width+1)/2), int((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)
#rgb三通道别离增强 ratio是比照度增强因子 radius是卷积模板半径
def zmIceColor(I, ratio=4, radius=3):
res = np.zeros(I.shape) for k in range(3): res[:,:,k] = stretchImage(zmIceFast(I[:,:,k], ratio, radius)) return res#主函数 if name == ‘main‘: img = cv2.imread(‘car.png’) res = zmIceColor(img/255.0)*255 cv2.imwrite(‘car-Ice.jpg’, res)
运转成果如图所示,ACE算法能有用进行图画去雾处理,完成图画的细节增强。
最终是方针检测去雾和女神去雾的作用,哈哈,持续加油!
三.暗通道先验去雾算法
该算法是核算机视觉范畴何恺明大佬于2009年提出的图画去雾经典算法,并获取当年CVPR最佳论文。论文标题为《Single Image Haze Removal Using Dark Channel Prior》。下图是大佬的百科简介,是真的凶猛,值得咱们咱们学习。
- 2003年5月,何恺明拿到保送清华的资历,是当年执信中学仅有保送上清华大学的学生;高考成果出炉今后,何恺明取得满分900分的成绩,成为当年广东省9位满分状元之一。
- 2009年,何恺明成为首获核算机视觉范畴三大国际会议之一CVPR“最佳论文奖”的我国学者。
- 在2015年的ImageNet图画辨认大赛中,何恺明和他的团队用“图画辨认深度差残学习”系统,击败谷歌、英特尔、高通等业界团队,荣获榜首。
- 何恺明作为榜首作者取得了CVPR 2009,CVPR 2016和ICCV 2017(Marr Prize)的最佳论文奖,并取得了ICCV 2017最佳学生论文奖。
- 2018年,第31届核算机视觉和模式辨认大会(Conference on Computer Vision and Pattern Recognition, CVPR)在美国盐湖城召开,何恺明取得本届大会的PAMI年青学者奖。
1.算法原理
言归正传,假如是图画处理或研讨图画去雾范畴的作者,建议咱们认真阅览这篇英文原文,能在2009年提出该算法真的很冷艳。
引证及参阅中文论文:
- 何涛, 等. 依据暗通道先验的单幅图画去雾新算法[J]. 核算机科学, 2021.
- 王蓉, 等. 依据改善加权交融暗通道算法的图画去雾研讨[J]. 浙江科技学院学报, 2021.
- 图画去雾算法的原理、完成、作用(速度可实时)- 挚爱图画处理
- 图画去雾之何凯明暗通道先验去雾算法原理及c++代码完成 – Do it !
英文原文:
- ieeexplore.ieee.org/document/55…
Single Image Haze Removal Using Dark Channel Prior- ieeexplore.ieee.org/document/52…
Single image haze removal using dark channel prior
暗通道先验(Dark Channel Prior, DCP)去雾算法 依赖大气散射模型进行去雾处理,经过对很多有雾图画和无雾图画进行观察总结,得到其间存在的一些映射联系,然后依据有雾图画的构成进程来进行逆运算,然后康复明晰图画。
算法完成进程及原理如下,参阅何恺明教师和何涛教师的论文。
(1) 大气散射模型
在核算机视觉和核算机图形学中,方程所描绘的大气散射模型被广泛运用。参数解释如下:
- x是图画的空间坐标
- I(x)代表有雾图画(待去雾图画)
- J(x)代表无雾图画(待康复图画)
- A代表全球大气光值
- t(x)代表透射率
方程右边榜首项为场景直接衰减项,第二项为环境光项。
(2) 暗通道界说
在绝大多数非天空的部分区域中,某些像素总会至少有一个色彩通道的值很低。关于一幅图画J(x),其暗通道的数学界说表明如下:
其间,(x)表明以x为中心的部分区域,上标c表明RGB三个通道。该公式的意义用代码表达也很简略,首要求出每个像素RGB重量中的最小值,存入一副和原始图画巨细相同的灰度图中,然后再对这幅灰度图进行最小值滤波,滤波的半径由窗口巨细决定。
(3) 暗通道先验理论
暗通道先验理论指出:关于非天空区域的无雾图画J(x)的暗通道趋于0,即:
实践生活中形成暗原色中低通道值首要有三个要素:
- a) 轿车、建筑物和城市中玻璃窗户的阴影,或许是树叶、树与岩石等天然景观的投影;
- b) 色彩鲜艳的物体或表面,在RGB的三个通道中有些通道的值很低(比如绿色的草地/树/植物,红色或黄色的花朵/叶子,或许蓝色的水面);
- c) 色彩较暗的物体或许表面,例如暗淡色的树干和石头。
总归,天然景象中处处都是阴影或许五颜六色,这些景象的图画的暗原色总是很暗淡的,而有雾的图画较亮。因而,能够显着的看到暗通道先验理论的普遍性。
(4) 公式变形
依据大气散射模型,将榜首个公式稍作处理,变形为下式:
假定每一个窗口的透射率t(x)为常数,记为t’(x),并且A值已给定,对式两头同时进行两次最小值运算,可得:
其间,J(x)是要求的无雾图画,依据前述的暗通道先验理论可知:
因而可推导出:
(5) 透射率核算
将上式带入可得到透射率t’(x)的预估值,如下所示:
现实生活中,即便晴空万里,空气中也会存在一些颗粒,在眺望远处的景象时,人们还是能感觉到雾的存在。别的,雾的存在让人们感受到景深,因而在去雾的同时有必要保存必定程度的雾。能够经过引入一个0到1之 间 的 因 子 w(一 般取0.95)对预估透射率进行修正,如式所示:
以上的推导进程均假定大气光值A是已知的,在实践中,能够凭借暗通道图从原始雾图中求取。具体步骤如下:
- 先求取暗通道图,在暗通道图中依照亮度的巨细提取最亮的前0.1%的像素
- 在原始雾图I(x)中找对应位置上具有最高亮度的点的值,作为大气光值A
此外,因为透射率t偏小时,会形成J偏大,康复的无雾图画全体向白场过度,因而有必要对透射率设置一个下限值t0(一般取值为0.1),当t值小于t0 时,取t=t0。将以上求得的透射率和大气光值代入公式,终究收拾得到图画的康复公式如下:
这就是暗通道先验去雾算法的原理进程,下面简略弥补论文中的处理作用图。
再次膜拜偶像,极力引荐咱们阅览论文。
2.算法完成
完成代码引证木教师的,感觉比我写得好,参阅如下:
-
openCV+python完成图画去雾 – 木盏教师
–– coding: utf-8 ––
“”” Created on Sat Sep 11 00:16:07 2021 @author: xiuzhang
参阅资料: blog.csdn.net/leviopku/ar… “””
import sys import cv2 import math import numpy as np
def DarkChannel(im,sz): b,g,r = cv2.split(im) dc = cv2.min(cv2.min(r,g),b) kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(sz,sz)) dark = cv2.erode(dc,kernel) return dark
def AtmLight(im,dark): [h,w] = im.shape[:2] imsz = h*w numpx = int(max(math.floor(imsz/1000),1)) darkvec = dark.reshape(imsz,1) imvec = im.reshape(imsz,3)
indices = darkvec.argsort() indices = indices[imsz-numpx::] atmsum = np.zeros([1,3]) for ind in range(1,numpx): atmsum = atmsum + imvec[indices[ind]] A = atmsum / numpx; return A
def TransmissionEstimate(im,A,sz): omega = 0.95 im3 = np.empty(im.shape,im.dtype)
for ind in range(0,3): im3[:,:,ind] = im[:,:,ind]/A[0,ind] transmission = 1 - omega*DarkChannel(im3,sz) return transmission
def Guidedfilter(im,p,r,eps): mean_I = cv2.boxFilter(im,cv2.CV_64F,(r,r)) mean_p = cv2.boxFilter(p, cv2.CV_64F,(r,r)) mean_Ip = cv2.boxFilter(imp,cv2.CV_64F,(r,r)) cov_Ip = mean_Ip – mean_Imean_p
mean_II = cv2.boxFilter(im*im,cv2.CV_64F,(r,r)) var_I = mean_II - mean_I*mean_I a = cov_Ip/(var_I + eps) b = mean_p - a*mean_I mean_a = cv2.boxFilter(a,cv2.CV_64F,(r,r)) mean_b = cv2.boxFilter(b,cv2.CV_64F,(r,r)) q = mean_a*im + mean_b return q
def TransmissionRefine(im,et): gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) gray = np.float64(gray)/255 r = 60 eps = 0.0001 t = Guidedfilter(gray,et,r,eps)
return t
def Recover(im,t,A,tx = 0.1): res = np.empty(im.shape,im.dtype) t = cv2.max(t,tx)
for ind in range(0,3): res[:,:,ind] = (im[:,:,ind]-A[0,ind])/t + A[0,ind] return res
if name == ‘main‘:
fn = 'car-02.png' src = cv2.imread(fn) I = src.astype('float64')/255 dark = DarkChannel(I,15) A = AtmLight(I,dark) te = TransmissionEstimate(I,A,15) t = TransmissionRefine(src,te) J = Recover(I,t,A,0.1) arr = np.hstack((I, J)) cv2.imshow("contrast", arr) cv2.imwrite("car-02-dehaze.png", J*255 ) cv2.imwrite("car-02-contrast.png", arr*255) cv2.waitKey();
完成作用如下图所示:
假如想和后续方针轿车检测结合,相同能够先去雾再进行检测,如下图所示:
四.图画噪声和雾生成
图画处理总少不了噪声增加或生成,下面弥补两个简略的椒盐噪声和雾气模仿生成的代码。这与本文的试验紧密相关,能为咱们供给更多的GAN生成样本。后面人工智能系列文章,GAN咱们看看能不能学习实在雾化场景的图画,值得等候,哈哈!
1.加盐噪声
原图是一张风景图画:
代码如下:
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#读取图片
img = cv2.imread("fj.png", cv2.IMREAD_UNCHANGED)
rows, cols, chn = img.shape
#加噪声
for i in range(50000):
x = np.random.randint(0, rows)
y = np.random.randint(0, cols)
img[x,y,:] = 210
cv2.imshow("noise", img)
#等候显示
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('fj-res.png',img)
输出成果如下图所示:
2.雾的模仿生成
代码如下:
import numpy as np
import cv2 as cv
import os
import random
file = ['fj.png']
output = 'fj-wu.png'
for file_img in file:
#打开图画
img = cv.imread(file_img)
mask_img = cv.imread(file_img)
#雾的色彩
mask_img[:, :] = (166, 178, 180)
#里面参数可调,首要调整雾的浓度
image = cv.addWeighted(img,
round(random.uniform(0.03, 0.28), 2),
mask_img, 1, 0)
#保存的文件夹
cv.imwrite(output, image)
输出成果如下图所示,作用还不错。
点击关注,榜首时刻了解华为云新鲜技能~