[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现

十月太忙,还是写一篇吧!祝大家1024节日快乐O(∩_∩)O
欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望我们都能在人生路上开心快乐、共同成长。

该系列文章主要讲解Python OpenCV图像处理和图像识别知识,前期主要讲解图像处理基础知识、OpenCV基础用法、常用图像绘制方法、图像几何变换等,中期讲解图像处理的各种运算,包括图像点运算、形态学处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理以及图像处理相关应用。

第一部分作者介绍了图像处理基础知识,第二部分介绍了图像运算和图像增强,接下来第三部分我们将详细讲解图像识别及图像处理经典案例,该部分属于高阶图像处理知识,能进一步加深我们的理解和实践能力。前面介绍了OpenGL绘制图形相关知识。这篇文章继续补充图像处理的高阶应用,即图像去雾算法。本文主要讲解ACE去雾算法、暗通道先验去雾算法以及雾化生成算法,并且参考了两位计算机视觉大佬(Rizzi和何恺明)的论文。希望对大家有所帮助,如果有不足之处,还请海涵。

文章目录

  • 一.图像去雾
    • 1.基于图像增强的去雾算法
    • 2.基于图像复原的去雾算法
    • 3.基于CNN的去雾算法
  • 二.ACE去雾算法
    • 1.区域自适应滤波
    • 2.色调重整拉伸,对图像动态扩展
  • 三.暗通道先验去雾算法
    • 1.大气散射模型
    • 2.暗通道定义
    • 3.暗通道先验理论
    • 4.公式变形
    • 5.透射率计算
  • 四.图像噪声和雾生成
    • 1.加盐噪声
    • 2.雾的模拟生成
  • 五.总结
  • 前文赏析

下载地址:记得点赞喔 O(∩_∩)O 前文赏析见文章末尾

  • https://github.com/eastmountyxz/Python-zero2one
  • 开源600多页电子书:https://github.com/eastmountyxz/HWCloudImageRecognition

作者新开的“娜璋AI安全之家”将专注于Python和安全技术,主要分享Web渗透、系统安全、人工智能、大数据分析、图像识别、恶意代码检测、CVE复现、威胁情报分析等文章。虽然作者是一名技术小白,但会保证每一篇文章都会很用心地撰写,希望这些基础性文章对你有所帮助,在Python和安全路上与大家一起进步。


一.图像去雾

随着社会的发展,环境污染逐渐加剧,越来越多的城市频繁出现雾霾,这不仅给人们的身体健康带来危害,还给那些依赖图像信息的计算机视觉系统造成了不良影响,因为在雾天采集到的图像对比度和饱和度均较低,颜色易发生偏移与失真等。因此,寻找一种简单有效的图像去雾方法,对计算机视觉的后续研究至关重要。

图像增强(Image Enhancement)是指按照某种特定的需求,突出图像中有用的信息,去除或者削弱无用的信息。图像增强的目的是使处理后的图像更适合人眼的视觉特性或易于机器识别。 在医学成像、遥感成像、人物摄影等领域,图像增强技术都有着广泛的应用。图像增强同时可以作为目标识别、目标跟踪、特征点匹配、图像融合、超分辨率重构等图像处理算法的预处理算法[1-3]。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第1张图片

近些年来,出现了众多的单幅图像去雾算法,应用比较广泛的有:

  • 直方图均衡化去雾算法
  • Retinex去雾算法
  • 暗通道先验去雾算法
  • 基于卷积神经网络的DehazeNet去雾算法

其主要可以分为 3 类:基于图像增强的去雾算法、基于图像复原的去雾算法和基于 CNN 的去雾算法。

1.基于图像增强的去雾算法

通过图像增强技术突出图像细节,提升对比度,使之看起来更加清晰,这类算法的适用性较广。具体的算法有:

  • Retinex 算法:根据成像原理消除反射分量影响,达到图像增强去雾效果。
  • 直方图均衡化算法:使图像的像素分布更加均匀,放大图像的细节。
  • 偏微分方程算法:将图像视作一个偏微分方程,计算梯度场提高对比度。
  • 小波变换算法:对图像进行分解,放大有用的部分。

此外,在这类算法的基础上出现了众多的基于图像增强原理的改进算法。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第2张图片


2.基于图像复原的去雾算法

主要是基于大气散射物理学模型,通过对大量有雾图像和无雾图像进行观察总结,得到其中存在的一些映射关系,然后根据有雾图像的形成过程来进行逆运算,从而恢复清晰图像。其中最经典的要属何恺明大佬提出的:

  • 暗通道先验去雾算法

通过对大量无雾图像进行特征分析,找到了无雾图像与大气散射模型中某些参数的先验关系。该算法复杂度低,去雾效果好,因此在其基础上出现了大量基于暗通道先验的改进算法[4-6]。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第3张图片


3.基于CNN的去雾算法

使用卷积神经网络(CNN)建立一个端到端的模型,通过有雾图像恢复出无雾图像,目前使用神经网络进行去雾的算法主要有两种思路:

  • 使用CNN生成大气散射模型的某些参数,再根据大气散射模型来恢复无雾图像
  • 使用CNN或GAN根据模糊图像生成无雾的清晰图像

CNN因其强大的学习能力在多个领域得到应用,因此也出现了采用CNN进行去雾的算法。2016年CAI等首次提出了一种名为DehazeNet的去雾网络,用于估计有雾图像的透射率。DehazeNet将有雾的模糊图像作为输入,输出其透射率,基于大气散射模型理论恢复出无雾的清晰图像[1-2]。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第4张图片

图41-5是分别对直方图均衡化、暗通道先验去雾、DehazeNet和AOD-Net去雾算法进行测试,实验结果如图所示。由图可知,基于图像增强的直方图均衡化算法的去雾图像对比度明显增强,由于不考虑降质原因,在增加对比度的同时也对噪声进行了放大,出现细节丢失与色彩偏差现象。基于物理模型的暗通道去雾算法、基于神经网络的DehazeNet和AOD-Net算法的去雾效果较直方图均衡化算法更佳。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第5张图片

其他去雾算法对比结果如图41-6所示,比如城市和道路有无图像去雾效果。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第6张图片

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第7张图片

正如总结王道累老师[2]总结的一样,目前针对有雾图像去雾的算法主要是从基于图像增强、图像复原和卷积神经网络3个方向进行的。

  • 基于图像增强的方法不考虑有雾图像的形成过程,而是直接通过突出图像的细节,提高对比度等方式,从而使有雾图像看上去更加清晰。
  • 基于图像复原的方法则是追寻图像降质的物理过程,通过物理模型还原出清晰的图像。
  • 基于 CNN 的方法则是利用神经网络强大的学习能力,寻找有雾图像与图像复原物理模型中某些系数的映射关系或者使用 GAN,根据有雾图像还原出无雾的清晰图像。

上述3类去雾算法对于雾天图像都有着明显的去雾效果,尽管其在实际生活中已经得到了广泛的应用,但下述几点仍有可能是今后图像去雾领域的研究重点和难点:

  • 更加真实的雾天图像数据集
    采用神经网络进行去雾的算法在效果上好于图像增强和复原的方法,但是由于在自然界中很难拍摄到一组背景相同的有雾图像和无雾图像,因此目前训练神经网络所采用的数据集均是通过合成得到的,虽然能够在一定程度上拟合自然环境,但是仍然存在着一些差距。所以目前急需一种由在真实环境中获取到的具有相同背景的有雾图像和无雾图像构建的数据集,来提高神经网络去雾算法的鲁棒性和稳定性。
  • 更加简便的去雾算法
    目前各类算法能够有效去除单幅图像上的雾霾,但相对较好的算法都存在着时间复杂度高的问题,很难应用到视频去雾或者需求较多的复杂任务中去。
  • 鲁棒性更强的去雾算法
    上述算法都只对图像上存在的均匀的薄雾有较好的去雾效果,对于浓雾或者分布不均的团雾则效果较差,因此找到一种适用范围更广的去雾方法将会是一个极具挑战性的课题。

二.ACE去雾算法

该部分主要介绍参考相关论文进行叙述,简单介绍ACE算法的原理知识。如果读者想详细了解其原理,推荐阅读这些大佬的英文原文[7-8]。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第8张图片

图像对比度增强的算法在很多场合都有用处,特别是在医学图像中,这是因为在众多疾病的诊断中,医学图像的视觉检查时很有必要的。Retinex算法是代表性的图像增强算法,它根据人的视网膜和大脑皮层模拟对物体颜色的波长光线反射能力而形成,对复杂环境下的一维条码具有一定范围内的动态压缩,对图像边缘有着一定自适应的增强。

自动色彩均衡(Automatic Color Enhancement,ACE)算法是Rizzi[8]大神在Retinex算法的理论上提出的,它通过计算图像目标像素点和周围像素点的明暗程度及其关系来对最终的像素值进行校正,实现图像的对比度调整,产生类似人体视网膜的色彩恒常性和亮度恒常性的均衡,具有很好的图像增强效果。

ACE算法包括两个步骤:

  • 一是对图像进行色彩和空域调整,完成图像的色差校正,得到空域重构图像。模仿视觉系统的侧抑制性和区域自适应性,进行色彩的空域调整。侧抑制性是一个生理学概念,指在某个神经元受到刺激而产生兴奋时,再刺激相近的神经元,后者所发生的兴奋对前者产生的抑制作用。
  • 二是对校正后的图像进行动态扩展。对图像的动态范围进行全局调整,并使图像满足灰度世界理论和白斑点假设。算法针对单通道,再延伸应用到RGB彩色空间3通道图像,即对3个通道分别处理再进行整合完成。

1.区域自适应滤波

输入图像I(灰度图为例),该步是对单通道图像I中所有点p的区域自适应滤波,得到完成色差校正,空域重构后的中间结果图像,计算公式如下:

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第9张图片

式中:Ic§-Ic(j)为p、j两个像素点间灰度差值,表达拟生物学上的侧抑制性;d(p,j)表示距离度量函数,使用两点间的欧氏距离,作用上控制点j对p的影响权重,映射出滤波的区域适应性;Sα(x)是亮度表现函数(奇函数),本文算法选择经典Saturation函数。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第10张图片

不同亮度函数和参数的选择控制了对比度增强的程度,经典的Saturation函数在饱和前取越大的斜率,结果的对比度增强越明显。极限情况是sign函数形式,而Sign函数由于无差别过度增强放大,导致噪声同样得到放大效果不佳,最终选择Saturation函数作为相对亮度表现函数。公式如下:

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第11张图片


2.色调重整拉伸,对图像动态扩展

将上式得到的中间量拉伸映射到[0, 255]中,占满动态范围[0, 255](8位灰度图像),计算公式如下,式中:[minR,maxR]是中间量L(x)的全部定义域,该项使图像达到全局白平衡。

在这里插入图片描述

下图是条形码图像进行ACE图像增强后的效果图,通过图像增强后的图(b)对比度更强,改善了原图像的明暗程度,增强的同时保持了图像的真实性[6]。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第12张图片

最后,再次推荐大家去阅读ACE算法英文论文。其实验对比效果如图41-8所示,大家在写该主题论文的时候,也需要注意和传统方法对比。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第13张图片

由于OpenCV中暂时没有ACE算法包,下面代码是借鉴“zmshy2128”老师的文章[9-11],修改实现的彩色直方图均衡化处理,以及被我扩展为Python3版本。推荐读者结合论文详细分析其代码实现过程。

# -*- coding: utf-8 -*-
# By: zmshy2128老师 & Eastmount 修改成(Python3)
# 参考: https://www.cnblogs.com/zmshy2128/p/6135551.html
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(h**2+w**2)
    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算法能有效进行图像去雾处理,实现图像的细节增强。图41-9显示行驶中的车辆去雾效果。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第14张图片

图41-10显示了大雾天游动的鸭群去雾效果。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第15张图片

图41-11显示了城市大雾天气的去雾对比效果。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第16张图片


三.暗通道先验去雾算法

该算法是计算机视觉领域何恺明大佬于2009年提出的图像去雾经典算法,并获取当年CVPR最佳论文。论文题目为《Single Image Haze Removal Using Dark Channel Prior》,何老师的很多文章都值得大家学习,是真的非常厉害。如果您是研究图像去雾或计算机视觉领域的读者,建议大家认真阅读这篇英文原文,能在2009年提出该算法真的很惊艳[12-13]。

暗通道先验(Dark Channel Prior, DCP)去雾算法依赖大气散射模型进行去雾处理,通过对大量有雾图像和无雾图像进行观察总结,得到其中存在的一些映射关系,然后根据有雾图像的形成过程来进行逆运算,从而恢复清晰图像[14-15]。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第17张图片

算法实现过程及原理如下,参考何恺明老师和何涛老师的论文[12-15]。

1.大气散射模型

在计算机视觉和计算机图形学中,下列方程所描述的大气散射模型被广泛使用。方程右边第一项为场景直接衰减项,第二项为环境光项。

在这里插入图片描述

具体参数解释如下:

  • x是图像的空间坐标
  • I(x)代表有雾图像(待去雾图像)
  • J(x)代表无雾图像(待恢复图像)
  • A代表全球大气光值
  • t(x)代表透射率

2.暗通道定义

在绝大多数非天空的局部区域中,某些像素总会至少有一个颜色通道的值很低。对于一幅图像J(x),其暗通道的数学定义表示如下:

在这里插入图片描述

其中,Ω(x)表示以x为中心的局部区域,上标c表示RGB三个通道。该公式的意义用代码表达也很简单,首先求出每个像素RGB分量中的最小值,存入一副和原始图像大小相同的灰度图中,然后再对这幅灰度图进行最小值滤波,滤波的半径由窗口大小决定。


3.暗通道先验理论

暗通道先验理论指出:对于非天空区域的无雾图像J(x)的暗通道趋于0,即:

在这里插入图片描述

实际生活中造成暗原色中低通道值主要有三个因素:

  • 汽车、建筑物和城市中玻璃窗户的阴影,或者是树叶、树与岩石等自然景观的投影;
  • 色彩鲜艳的物体或表面,在RGB的三个通道中有些通道的值很低(比如绿色的草地/树/植物,红色或黄色的花朵/叶子,或者蓝色的水面);
  • 颜色较暗的物体或者表面,例如灰暗色的树干和石头。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第18张图片

总之,自然景物中到处都是阴影或者彩色,这些景物的图像的暗原色总是很灰暗的,而有雾的图像较亮。因此,可以明显的看到暗通道先验理论的普遍性。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第19张图片


4.公式变形

根据大气散射模型,将第一个公式稍作处理,变形为下式:

在这里插入图片描述

假设每一个窗口的透射率t(x)为常数,记为t’(x),并且A值已给定,对式两边同时进行两次最小值运算,可得:

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第20张图片

其中,J(x)是要求的无雾图像,根据前述的暗通道先验理论可知:

在这里插入图片描述

因此可推导出:

在这里插入图片描述


5.透射率计算

将上式带入可得到透射率t’(x)的预估值,如下所示:

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第21张图片

现实生活中,即便晴空万里,空气中也会存在一些颗粒,在眺望远处的景物时,人们还是能感觉到雾的存在。另外,雾的存在让人们感受到景深,因此在去雾的同时有必要保留一定程度的雾。可以通过引入一个0到1之间的因子w(一般取0.95)对预估透射率进行修正,如式所示:

在这里插入图片描述

以上的推导过程均假设大气光值A是已知的,在实际中,可以借助暗通道图从原始雾图中求取。具体步骤如下:

  • 先求取暗通道图,在暗通道图中按照亮度大小提取最亮的前0.1%的像素
  • 在原始雾图I(x)中找对应位置上具有最高亮度的点的值,作为大气光值A

此外,由于透射率t偏小时,会造成J偏大,恢复的无雾图像整体向白场过度,因此有必要对透射率设置一个下限值t0(一般取值为0.1),当t值小于t0时,取t=t0。将以上求得的透射率和大气光值代入公式,最终整理得到图像的恢复公式如下:

在这里插入图片描述

这就是暗通道先验去雾算法的原理过程,下面简单补充论文中的处理效果图。再次推荐大家阅读何老师的原文。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第22张图片

实现代码引用木盏老师的,感觉比作者的写得好[16-17],核心代码如下:

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 11 00:16:07 2021
@author: xiuzhang
参考资料:
https://blog.csdn.net/leviopku/article/details/83898619
"""
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(im*p,cv2.CV_64F,(r,r))
    cov_Ip = mean_Ip - mean_I*mean_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 = 'city.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-dehaze.png", J*255 )
    cv2.imwrite("car-contrast.png", arr*255)
    cv2.waitKey();

城市雾天的去雾效果如图41-16所示,可以发现暗通道先验去雾算法的效果非常棒。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第23张图片

如果想和后续目标汽车检测结合,同样可以先去雾再进行检测,如图41-16所示。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第24张图片


四.图像噪声和雾生成

图像处理总少不了噪声添加或生成,最后补充两个简单的椒盐噪声和雾气模拟生成的代码。这与本文的实验紧密相关,能为我们提供更多的GAN生成样本。后面人工智能系列文章,我们看看能不能利用GAN学习真实雾化场景图像。

1.加盐噪声

原图是一张风景图像如图41-17所示。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第25张图片

图像增加椒盐噪声的代码如下:

# -*- coding: utf-8 -*-
# By: Eastmount
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)

输出结果如下图所示。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第26张图片


2.雾的模拟生成

该部分代码如下:

# -*- coding: utf-8 -*-
# By: Eastmount
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) 

输出结果如图41-19所示,效果还不错。

[Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现_第27张图片


五.总结

本文主要讲解两种经典的图像去雾算法,分别是ACE去雾算法和暗通道先验去雾算法,同时补充了雾化生成的算法。本文推荐大家学习Rizzi和何恺明两位计算机视觉大佬的论文。

感谢在求学路上的同行者,不负遇见,勿忘初心。图像处理系列主要包括三部分,分别是:

在这里插入图片描述

在这里插入图片描述

请添加图片描述

忙碌的11月,忙碌的2023。转眼四年过去,我和她都不容易,两人每次看“致谢”都会泪目,青春变了,唯有情感不变,希望一家人健康快乐。刚到寝室,要战斗了!

(By:Eastmount 2023-12-05 夜于贵阳 http://blog.csdn.net/eastmount/ )


参考文献:

  • [1] 魏红伟, 等. 图像去雾算法研究综述[J]. 软件导刊, 2021.
  • [2] 王道累, 等. 图像去雾算法的综述及分析[J]. 图学学报, 2021.
  • [3] OpenCV图像增强万字详解(直方图均衡化、自动色彩均衡化)—— Eastmount
  • [4] 尹胜楠, 等. 基于快速ACE算法的视觉里程计图像增强方法[J]. 电子测量与仪器学报, 2021.
  • [5] 李景文, 等. 基于暗通道先验改进的自动色彩均衡算法[J]. 科学技术与工程, 2019.
  • [6] 杨秀璋, 等. 一种改进的复杂环境下条形码图像增强和定位算法[J]. 现代计算机, 2020.
  • [7] Pascal Gertreuer. Automatic Color Enhancement (ACE) and its Fast Implementation. https://www.ipol.im/pub/art/2012/g-ace/?utm_source=doi.
  • [8] Rizzi A., et al. A new algorithm for unsupervised global and local color correction. https://www.sciencedirect.com/science/article/abs/pii/S0167865502003239.
  • [9] 自动色彩均衡(ACE)快速算法 - zmshy2128老师
  • [10] OpenCV—python 自动色彩均衡(ACE)- SongpingWang
  • [11] [Python图像识别] 四十六.图像预处理之图像去雾详解——Eastmount.
  • [12] He Kaiming, et al. Single Image Haze Removal Using Dark Channel Prior. https://ieeexplore.ieee.org/ document/5567108.
  • [13] He Kaiming, et al.Single image haze removal using dark channel prior. https://ieeexplore.ieee.org/ document/5206515.
  • [14] 何涛, 等. 基于暗通道先验的单幅图像去雾新算法[J]. 计算机科学, 2021.
  • [15] 王蓉, 等. 基于改进加权融合暗通道算法的图像去雾研究[J]. 浙江科技学院学报, 2021.
  • [16] 图像去雾算法的原理、实现、效果(速度可实时)—— 挚爱图像处理
  • [17] 图像去雾之何凯明暗通道先验去雾算法原理及c++代码实现 —— Do it !

前文赏析

尽管该部分占大量篇幅,但我舍不得删除,哈哈!

第一部分 基础语法

  • [Python从零到壹] 一.为什么我们要学Python及基础语法详解
  • [Python从零到壹] 二.语法基础之条件语句、循环语句和函数
  • [Python从零到壹] 三.语法基础之文件操作、CSV文件读写及面向对象

第二部分 网络爬虫

  • [Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例
  • [Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解
  • [Python从零到壹] 六.网络爬虫之BeautifulSoup爬取豆瓣TOP250电影详解
  • [Python从零到壹] 七.网络爬虫之Requests爬取豆瓣电影TOP250及CSV存储
  • [Python从零到壹] 八.数据库之MySQL基础知识及操作万字详解
  • [Python从零到壹] 九.网络爬虫之Selenium基础技术万字详解(定位元素、常用方法、键盘鼠标操作)
  • [Python从零到壹] 十.网络爬虫之Selenium爬取在线百科知识万字详解(NLP语料构造必备技能)

第三部分 数据分析和机器学习

  • [Python从零到壹] 十一.数据分析之Numpy、Pandas、Matplotlib和Sklearn入门知识万字详解(1)
  • [Python从零到壹] 十二.机器学习之回归分析万字总结全网首发(线性回归、多项式回归、逻辑回归)
  • [Python从零到壹] 十三.机器学习之聚类分析万字总结全网首发(K-Means、BIRCH、层次聚类、树状聚类)
  • [Python从零到壹] 十四.机器学习之分类算法三万字总结全网首发(决策树、KNN、SVM、分类算法对比)
  • [Python从零到壹] 十五.文本挖掘之数据预处理、Jieba工具和文本聚类万字详解
  • [Python从零到壹] 十六.文本挖掘之词云热点与LDA主题分布分析万字详解
  • [Python从零到壹] 十七.可视化分析之Matplotlib、Pandas、Echarts入门万字详解
  • [Python从零到壹] 十八.可视化分析之Basemap地图包入门详解
  • [Python从零到壹] 十九.可视化分析之热力图和箱图绘制及应用详解
  • [Python从零到壹] 二十.可视化分析之Seaborn绘图万字详解
  • [Python从零到壹] 二十一.可视化分析之Pyechart绘图万字详解
  • [Python从零到壹] 二十二.可视化分析之OpenGL绘图万字详解
  • [Python从零到壹] 二十三.十大机器学习算法之决策树分类分析详解(1)
  • [Python从零到壹] 二十四.十大机器学习算法之KMeans聚类分析详解(2)
  • [Python从零到壹] 二十五.十大机器学习算法之KNN算法及图像分类详解(3)
  • [Python从零到壹] 二十六.十大机器学习算法之朴素贝叶斯算法及文本分类详解(4)
  • [Python从零到壹] 二十七.十大机器学习算法之线性回归算法分析详解(5)
  • [Python从零到壹] 二十八.十大机器学习算法之SVM算法分析详解(6)
  • [Python从零到壹] 二十九.十大机器学习算法之随机森林算法分析详解(7)
  • [Python从零到壹] 三十.十大机器学习算法之逻辑回归算法及恶意请求检测应用详解(8)
  • [Python从零到壹] 三十一.十大机器学习算法之Boosting和AdaBoost应用详解(9)
  • [Python从零到壹] 三十二.十大机器学习算法之层次聚类和树状图聚类应用详解(10)

第四部分 Python图像处理基础

  • [Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置
  • [Python从零到壹] 三十四.OpenCV入门详解——显示读取修改及保存图像
  • [Python从零到壹] 三十五.图像处理基础篇之OpenCV绘制各类几何图形
  • [Python从零到壹] 三十六.图像处理基础篇之图像算术与逻辑运算详解
  • [Python从零到壹] 三十七.图像处理基础篇之图像融合处理和ROI区域绘制
  • [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)
  • [Python从零到壹] 三十九.图像处理基础篇之图像几何变换(镜像仿射透视)
  • [Python从零到壹] 四十.图像处理基础篇之图像量化处理
  • [Python从零到壹] 四十一.图像处理基础篇之图像采样处理
  • [Python从零到壹] 四十二.图像处理基础篇之图像金字塔向上取样和向下取样

第五部分 Python图像运算和图像增强

  • [Python从零到壹] 四十三.图像增强及运算篇之图像点运算和图像灰度化处理
  • [Python从零到壹] 四十四.图像增强及运算篇之图像灰度线性变换详解
  • [Python从零到壹] 四十五.图像增强及运算篇之图像灰度非线性变换详解
  • [Python从零到壹] 四十六.图像增强及运算篇之图像阈值化处理
  • [Python从零到壹] 四十七.图像增强及运算篇之腐蚀和膨胀详解
  • [Python从零到壹] 四十八.图像增强及运算篇之形态学开运算、闭运算和梯度运算
  • [Python从零到壹] 四十九.图像增强及运算篇之顶帽运算和底帽运算
  • [Python从零到壹] 五十.图像增强及运算篇之图像直方图理论知识和绘制实现
  • [Python从零到壹] 五十一.图像增强及运算篇之图像灰度直方图对比分析万字详解
  • [Python从零到壹] 五十二.图像增强及运算篇之图像掩膜直方图和HS直方图
  • [Python从零到壹] 五十三.图像增强及运算篇之直方图均衡化处理
  • [Python从零到壹] 五十四.图像增强及运算篇之局部直方图均衡化和自动色彩均衡化处理
  • [Python从零到壹] 五十五.图像增强及运算篇之图像平滑(均值滤波、方框滤波、高斯滤波)
  • [Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波、双边滤波)
  • [Python从零到壹] 五十七.图像增强及运算篇之图像锐化Roberts、Prewitt算子实现边缘检测
  • [Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel、Laplacian算子实现边缘检测
  • [Python从零到壹] 五十九.图像增强及运算篇之图像锐化Scharr、Canny、LOG实现边缘检测

第六部分 Python图像识别和图像高阶案例

  • [Python从零到壹] 六十.图像识别及经典案例篇之基于阈值及边缘检测的图像分割
  • [Python从零到壹] 六十一.图像识别及经典案例篇之基于纹理背景和聚类算法的图像分割
  • [Python从零到壹] 六十二.图像识别及经典案例篇之基于均值漂移算法和分水岭算法的图像分割
  • [Python从零到壹] 六十三.图像识别及经典案例篇之图像漫水填充分割应用
  • [Python从零到壹] 六十四.图像识别及经典案例篇之图像傅里叶变换和傅里叶逆变换详解
  • [Python从零到壹] 六十五.图像识别及经典案例篇之图像霍夫变换详解
  • [Python从零到壹] 六十六.图像识别及经典案例篇之基于机器学习的图像分类
  • [Python从零到壹] 六十七.图像识别及经典案例篇之基于卷积神经网络的MNIST图像分类
  • [Python从零到壹] 六十八.图像识别及经典案例篇之图像特效(毛玻璃、浮雕、油漆和模糊特效变换)
  • [Python从零到壹] 六十九.图像识别及经典案例篇之图像特效(素描和卡通特效)
  • [Python从零到壹] 七十.图像识别及经典案例篇之图像特效(怀旧、流年、光照和水波特效)
  • [Python从零到壹] 七十一.图像识别及经典案例篇之图像特效(滤镜和均衡化特效)
  • [Python从零到壹] 七十二.图像识别及经典案例篇之OpenGL入门及绘制基本图形和3D图
  • [Python从零到壹] 七十三.图像识别及经典案例篇之图像去雾ACE算法和暗通道先验去雾算法实现

第七部分 NLP与文本挖掘

第八部分 人工智能入门知识

第九部分 网络攻防与AI安全

第十部分 知识图谱构建实战

扩展部分 人工智能高级案例

你可能感兴趣的:(Python从零到壹,python,算法,图像去雾,ACE算法,暗通道算法)