該系列文章是講解Python OpenCV影像處理知識,前期主要講解影像入門、OpenCV基礎用法,中期講解影像處理的各種演算法,包括影像銳化算子、影像增強技術、影像分割等,后期結合深度學習研究影像識別、影像分類應用,希望文章對您有所幫助,如果有不足之處,還請海涵~
上一篇文章主要介紹目標檢測原理,通過七個問題來普及什么是目標檢測,然后利用ImageAI實作最簡單的目標檢測案例,這篇文章將詳細介紹影像去霧演算法,經過影像增強后的影像也能應用于目標檢測或影像分類領域,并且效果更好,本文主要講解ACE去霧演算法、暗通道先驗去霧演算法以及霧化生成演算法,并且參考了兩位計算機視覺大佬(Rizzi 何愷明)的論文,希望您喜歡,且看且珍惜,
第二階段我們進入了Python影像識別,該部分主要以目標檢測、影像識別以及深度學習相關影像分類為主,將會分享近50篇文章,感謝您一如至往的支持,作者也會繼續加油的!
文章目錄
- 一.影像去霧
- 二.ACE去霧演算法
- 1.演算法原理
- 2.代碼實作
- 三.暗通道先驗去霧演算法
- 1.演算法原理
- 2.演算法實作
- 四.影像噪聲和霧生成
- 1.加鹽噪聲
- 2.霧的模擬生成
- 五.總結
同時,該部分知識均為作者查閱資料撰寫總結,并且開設成了收費專欄,為小寶賺點奶粉錢,感謝您的抬愛,如果有問題隨時私聊我,只望您能從這個系列中學到知識,一起加油,代碼下載地址(如果喜歡記得star,一定喔):
- https://github.com/eastmountyxz/ImageProcessing-Python
影像識別:
- [Python影像識別] 四十五.物件檢測案例入門及ImageAI基礎用法
- [Python影像識別] 四十六.影像預處理之影像去霧詳解(ACE演算法和暗通道先驗去霧演算法)
影像處理:
- [Python影像處理] 一.影像處理基礎知識及OpenCV入門函式
- [Python影像處理] 二.OpenCV+Numpy庫讀取與修改像素
- [Python影像處理] 三.獲取影像屬性、興趣ROI區域及通道處理
- [Python影像處理] 四.影像平滑之均值濾波、方框濾波、高斯濾波及中值濾波
- [Python影像處理] 五.影像融合、加法運算及影像型別轉換
- [Python影像處理] 六.影像縮放、影像旋轉、影像翻轉與影像平移
- [Python影像處理] 七.影像閾值化處理及演算法對比
- [Python影像處理] 八.影像腐蝕與影像膨脹
- [Python影像處理] 九.形態學之影像開運算、閉運算、梯度運算
- [Python影像處理] 十.形態學之影像頂帽運算和黑帽運算
- [Python影像處理] 十一.灰度直方圖概念及OpenCV繪制直方圖
- [Python影像處理] 十二.影像幾何變換之影像仿射變換、影像透視變換和影像校正
- [Python影像處理] 十三.基于灰度三維圖的影像頂帽運算和黑帽運算
- [Python影像處理] 十四.基于OpenCV和像素處理的影像灰度化處理
- [Python影像處理] 十五.影像的灰度線性變換
- [Python影像處理] 十六.影像的灰度非線性變換之對數變換、伽馬變換
- [Python影像處理] 十七.影像銳化與邊緣檢測之Roberts算子、Prewitt算子、Sobel算子和Laplacian算子
- [Python影像處理] 十八.影像銳化與邊緣檢測之Scharr算子、Canny算子和LOG算子
- [Python影像處理] 十九.影像分割之基于K-Means聚類的區域分割
- [Python影像處理] 二十.影像量化處理和采樣處理及區域馬賽克特效
- [Python影像處理] 二十一.影像金字塔之影像向下取樣和向上取樣
- [Python影像處理] 二十二.Python影像傅里葉變換原理及實作
- [Python影像處理] 二十三.傅里葉變換之高通濾波和低通濾波
- [Python影像處理] 二十四.影像特效處理之毛玻璃、浮雕和油漆特效
- [Python影像處理] 二十五.影像特效處理之素描、懷舊、光照、流年以及濾鏡特效
- [Python影像處理] 二十六.影像分類原理及基于KNN、樸素貝葉斯演算法的影像分類案例
- [Python影像處理] 二十七.OpenGL入門及繪制基本圖形(一)
- [Python影像處理] 二十八.OpenCV快速實作人臉檢測及視頻中的人臉
- [Python影像處理] 二十九.MoviePy視頻編輯庫實作抖音短視頻剪切合并操作
- [Python影像處理] 三十.影像量化及采樣處理萬字詳細總結(推薦)
- [Python影像處理] 三十一.影像點運算處理兩萬字詳細總結(灰度化處理、閾值化處理)
- [Python影像處理] 三十二.傅里葉變換(影像去噪)與霍夫變換(特征識別)萬字詳細總結
- [Python影像處理] 三十三.影像各種特效處理及原理萬字詳解(毛玻璃、浮雕、素描、懷舊、流年、濾鏡等)
- [Python影像處理] 三十四.數字影像處理基礎與幾何圖形繪制萬字詳解(推薦)
- [Python影像處理] 三十五.OpenCV影像處理入門、算數邏輯運算與影像融合(推薦)
- [Python影像處理] 三十六.OpenCV影像幾何變換萬字詳解(平移縮放旋轉、鏡像仿射透視)
- [Python影像處理] 三十七.OpenCV和Matplotlib繪制直方圖萬字詳解(掩膜直方圖、H-S直方圖、黑夜白天判斷)
- [Python影像處理] 三十八.OpenCV影像增強萬字詳解(直方圖均衡化、區域直方圖均衡化、自動色彩均衡化)
- [Python影像處理] 三十九.Python影像分類萬字詳解(貝葉斯影像分類、KNN影像分類、DNN影像分類)
- [Python影像處理] 四十.全網首發Python影像分割萬字詳解(閾值分割、邊緣分割、紋理分割、分水嶺演算法、K-Means分割、漫水填充分割、區域定位)
- [Python影像處理] 四十一.Python影像平滑萬字詳解(均值濾波、方框濾波、高斯濾波、中值濾波、雙邊濾波)
- [Python影像處理] 四十二.Python影像銳化及邊緣檢測萬字詳解(Roberts、Prewitt、Sobel、Laplacian、Canny、LOG)
- [Python影像處理] 四十三.Python影像形態學處理萬字詳解(腐蝕膨脹、開閉運算、梯度頂帽黑帽運算)
- 萬字長文告訴新手如何學習Python影像處理 (上篇完結 四十四)
一.影像去霧
隨著社會的發展,環境污染逐漸加劇,越來越多的城市頻繁出現霧霾,這不僅給人們的身體健康帶來危害,還給那些依賴影像資訊的計算機視覺系統造成了不良影響,因為在霧天采集到的影像對比度和飽和度均較低,顏色易發生偏移與失真等,因此,尋找一種簡單有效的影像去霧方法,對計算機視覺的后續研究至關重要,
該部分主要從下列幾篇論文摘取對影像去霧演算法進行普及,參考及參考中文論文:
- 魏紅偉, 等. 影像去霧演算法研究綜述[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
英文原文:
- https://www.ipol.im/pub/art/2012/g-ace/?utm_source=doi
Automatic Color Enhancement (ACE) and its Fast Implementation- https://www.sciencedirect.com/science/article/abs/pii/S0167865502003239
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(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演算法能有效進行影像去霧處理,實作影像的細節增強,


最后是目標檢測去霧和女神去霧的效果,哈哈,繼續加油!


三.暗通道先驗去霧演算法
該演算法是計算機視覺領域何愷明大佬于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 !
英文原文:
- https://ieeexplore.ieee.org/document/5567108
Single Image Haze Removal Using Dark Channel Prior- https://ieeexplore.ieee.org/document/5206515
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
參考資料:
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 = '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)
輸出結果如下圖所示,效果還不錯,


五.總結
寫到這里,本文就介紹完畢,希望您喜歡,如果你是一名Python初學者或想了解影像處理知識,真心推薦該系列,并且多實踐多寫代碼,最后希望文章對您有所幫助,

八月初又認識了很多朋友,也解答了許多學生和博友的問題,雖然自己技術不是很好,但真心感激這一路走來認識了許多伙伴,也享受相互交流的程序,感恩遇見,不負青春,
這半個月交流讓我印象深刻的是復旦、浙大和武大離職讀博想當老師的朋友,我們交流了許多學習心得并鼓勵前行;也有貴財計科、軟工、電商幾位學生作業的問題;以及家鄉貴財、貴大、興義師范、貴師大、貴理工選擇考研或已經讀研同學的咨詢,我們相互學習;當然還有許多創業、作業、學習或尋求正能量的交流,包括來自廣東、南航、中北、湖北工業、建筑轉NLP、安全或AI行業的博友,最讓我享受的是,許多我教過的學生或相互鼓勵前行的博友,經常祝福我們一家并保持良好的情誼,這或許就是分享的魅力,覺不亞于一次holy shit,教育的方式多種多樣,我享受這樣的交流和鼓勵方式,山川異域,攜手同行,
最后補充一句,父母能帶給孩子最好的禮物,或許就是“處于逆境時的應對能力”,希望小珞珞能堅強、健康、快樂的成長,女神也能美麗和幸福一輩子,愛你們喲,
(By:Eastmount 2021-09-14 晚上12點 http://blog.csdn.net/eastmount/ )
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/300168.html
標籤:AI
下一篇:人人都會編程的時代已經到來了?

