??歡迎訂閱《從實戰學python》專欄,用python實現爬蟲、辦公自動化、數據可視化、人工智能等各個方向的實戰案例,有趣又有用!??
治愈生活的良方 就是保持對生活的熱愛
哈嘍,大家好,我是一條。
每次和女朋友出去玩,拍照是必須的,天氣好還行,天氣要是不好,加上我這破手機,那拍的簡直慘不忍睹,自己都不過去。
但是沒什么能難倒程序員的,為了不挨罵,連夜寫出去霧算法,女朋友更崇拜我了!
??本文高能,專業知識繁多,小白可以直接文末拿代碼運行(每行都有注釋)。
??想深入研究的同學,萬字詳解包教包會!
??總之,收藏護體!
話不多說,先看看效果強不強。
自己寫的算法,不調百度api,nb克拉斯。
應用:車牌識別
應用:霧天預警
應用:景物識別
目前圖像處理技術已非常火熱,應用也非常廣泛。
圖像處理的難度不僅在于成像技術,更在于外界的天氣條件,遇到霧、雨、雪等能見度低的惡劣天氣時,成像會受到很大影響,其中霧霾天氣屢見不鮮,還使采集到的圖片辨識度、對比度、色彩飽和度都大大降低。
霧氣的消除可以從物理去霧和數字去霧兩個方向考慮,物理去霧即在成像鏡頭上優化,高清去霧的鏡頭成本昂貴,不能廣泛應用,所以研究重點在數字去霧上,即通過后期處理對圖像進行優化,從去霧算法提出至今,可用的去霧算法大致可分為基于圖像增強的去霧算法和基于圖像復原的去霧算法。
本算法基于圖像復原的暗通道先驗去霧算法,在大氣成像模型的基礎上,得出圖像恢復的基本公式。
暗通道理論指出:在大多數非空局部區域中,始終至少有一個顏色通道的某些像素值較低甚至為0。
公式的關鍵點在于透射率的計算,為了改進算法,用導向濾波對透射率進行優化。
又因為該算法本身對天空部分并不適用,所以考慮對公式增加參數,二次計算透射率,完成對算法的再一次優化。
最后再用OpenCV-Python對去霧算法進行具體實現以及運行速度的優化。最終能夠實現對絕大多數的有霧圖片快速去霧。
為了讓領域小白理解接下來我要講的內容,需要普及一些基礎知識。
像素是圖像的基本要素,也是圖像的最小單位。
一張圖片實際是由很多個小方格組成,每個小方格有固定的位置和顏色數值,這決定了圖片最終呈現的樣子,像素的多少決定了在屏幕上顯示的大小。
如果是黑白圖片,用0-255之間的一個數字來表示顏色的深淺明暗,0表示最暗(黑色),255表示最亮(白色)。
如果是彩色圖片,用三個0-255之間的數字組成的數字序列來表示紅綠藍三種顏色所占的比例,則某一個位置的像素就可以用數字序列表示為[24,180,50]。
比如一個5*4像素的彩色圖像就可以這樣存在計算機中。
通道簡單來說就是表示通道表示每個點能存放多少個數。
例如彩色圖像中每個像素點存放三個值,即3通道的,黑白圖像每個像素點存放一個數字,即單通道。
圖像的像素點不是0就是1(圖像不是黑色就是白色),圖像像素點占的位數就是1位,圖像的深度就是1,也稱作位圖。
圖像中的像素介于0-255之間,0表示完全黑色,255表示完全白色,并且在0-255之間插入了255級灰度。
當查看單個通道時,每個通道都顯示為灰度圖像而不是黑白圖像。
在通道的灰度圖像中,對比度應與通道顏色的對比度匹配,它代表了彩色光在整個圖像上的分布。
因為有3個通道,所以也有3個灰度圖像。
暗通道是一個基本假設,即在大多數非空局部區域中,始終至少有一個顏色通道的某些像素值較低。
形成這種現象的原因很多,比如色彩鮮艷的物體的表面,汽車,建筑物或城市的陰影,較暗的物體表面的陰影,這些場景的暗通道始終較暗。
暗通道實際上使用三個RGB通道中的最小通道來形成灰度圖像。
作者計算大量沒有霧的圖像,并找到規則:
每個圖像中三個RGB其中一個顏色通道具有一個灰色通道,階值非常低,幾乎接近零。
如果有霧,則有一定的灰色;
如果沒有霧,則有很多黑色(像素接近0)。
共計算了5,000多個圖像屬性,基本上都滿足這樣的先驗定理。
所以只需分別計算出三個通道中RGB的最小值即可。
大氣顆粒的散射是霧霾的主要原因。
無論是用肉眼觀察還是從拍攝的圖像中觀察,有很多霧的場景總是會受到對比度降低和視野降低的困擾。
在1925年,Keim和Nemnich等人提出霧圖像的低可見性是由于大氣中空氣中的微粒吸收和散射了光。
1976年,約翰·威利(JohnWiley)等人提出,粒子散射會導致光在傳輸過程中在目標和相機之間衰減,并增加了一層大氣散射光。
為了解決1999年大霧天能見度差的問題,SrinivasaG和Narasimhan等人建立了數學模型來改善霧像的成像過程以及霧像中包含的各種元素。
該模型認為,在強散射介質中,檢測系統的成像結果劣化的主要原因有兩個:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UrrwKMG3-1630474072464)(file:private/var/folders/j0/jf6_lq_s2wjcqpt53gnd88b80000gn/T/com.kingsoft.wpsoffice.mac/wps-libiao/ksohtml/wps6EBduQ.jpg)]
圖中顯示探測系統成像時接收到的光源主要來自兩個部分,
通過此物理模型建立得到霧天成像的數學模型為:
該公式的物理意義為經過粒子衰減能夠達到探測系統的那部分光的比例。
大多數團隊和學者在通過探測系統獲得含霧圖像并對其進行去霧圖像處理時均以上述大氣散射模型作為霧天成像的理論模型。
其主要思路是根據各種先驗知識或者圖像處理手段,從含霧圖像中估計傳輸函數或大氣光,將求解得到的參量代入到大氣散射模型中,即可恢復出目標圖像。
在強分散介質中,檢測系統成像質量的下降主要包括以下兩個原因:
暗通道先驗去霧算法最早由何凱明博士中提出。先驗與經驗相對,就是基于某種經驗所得出的結論去研究解決問題的方法,此處就是指何凱明博士統計了5000多副圖像后得出的先驗定理:
在每一幅圖像的RGB三個顏色通道中,總有一個通道的灰度值很低,幾乎趨向于0。
可以發現,有霧的時候會呈現一定的灰色,而無霧的時候咋會呈現大量的黑色(像素為接近0)。如圖:有霧圖片的灰度圖整體呈灰色,無霧圖片的非天空部分呈黑色。
在現實生活中產生這種現象的原因的有很多且很普遍,例如汽車,建筑物等城市中的陰影,有色物體的表面,比如綠葉,各種鮮艷的花朵,較暗的物體表面,這些場景圖像的RGB顏色通道中,總有一個通道的灰度值很低。
此處省去推導過程,直接上公式。
在日常生活中,即使是晴空萬里,霧也不是完全不存在的,只是濃度比較低,依然會影響人們看遠處的物體;
另外,人眼能感到景深的存在也是因為霧。
所以,去霧時也不能做到絕對,應該保留一定程度的霧,通過在式中加入一個在[0,1]之間的系數來實現。
明確需要計算哪些值。
在實際中,可以借助于暗通道圖來從有霧圖像中獲取該值。
首先根據亮度從暗通道圖中獲取前0.1%的像素,
然后在這些位置中,在原始有霧圖像I中尋找對應的具有最高亮度的點的值,作為A值,
最后計算A的平均值。
大氣光計算出之后,根據如下公式,可得到透射率。
理論已經完成,咱們直接代碼實現。
OpenCV主要提供一組通用的基礎結構。
用于開發人工視覺程序,并改善商業產品中機器的感知。
OpenCV庫具有2500多種優化算法,包括經典和最先進的機器視覺以及機器學習算法。
這些算法可用于檢測和識別面部,跟蹤移動的對象,提取對象的三維模型,從立體相機生成3D點云并組合圖像以生成高分辨率全景圖像。從圖像數據庫中查找相似圖像等等。
使用OpenCV的項目已植入街景圖像,在監視期間檢測入侵,監視采礦設備,幫助機器人導航和收集物體,并檢測泳池中的溺水事件等很多。
OpenCV支持各種編程語言,如C++,Python,Java等,OpenCV-Python是OpenCV的PythonAPI,結合了C++和Python語言的最佳特性。
綜上所述,OpenCV-Python的功能非常強大,所以本文用它來實現去霧算法。
OpenCV在很多領域都有應用,比如圖像分割、物體識別、動作識別、人臉識別、結構分析等眾多領域,功能復雜繁多。在暗通道先驗去霧算法中,除去一些計算函數,最關鍵的就是OpenCV的形態學處理。
形態變換是對圖像形狀進行的簡單操作,通常是指對二值圖像進行的操作,常見的形態變換包括腐蝕,膨脹和張開操作。
腐蝕是對前景中物體邊緣的腐蝕,其腐蝕效果與現實相同。
其原理為卷積核沿著圖像滾動,如果相應區域的圖像的像素值是1,則對應于卷積核中心的像素值保持不變,否則將全部變為0。
在卷積核中,圖像的邊緣,部分為0,則該區域的部分將全變為0并保持不變。
膨脹是腐蝕的逆過程,與腐蝕相對,
其原理同樣為卷積核沿著圖像流動,如與卷積核對應的圖像像素值之一為1,該區域將全部變為1,否則保持不變。
進行腐蝕操作后再進行膨脹操作就是開運算
閉與開相對,所以開運算的逆過程就是閉運算,進行膨脹操作后再進行腐蝕造作,原理和開運算一樣,可以用于去除二值化圖像的背景色噪點。
首先計算圖像的總像素點數,取其前0.1%。
再按像素值從小到大的順序獲取像素所在位置的下標,按按照下標從霧圖中找到對應位置的三通道值。
這樣就完成了從暗通道圖中按照亮度的大小取前0.1%的像素。然后取這些值的平均值作為大氣光A的值。
代碼如下:
def AtmLight(im,dark): [h,w]=im.shape[:2] #獲取圖像的長寬 imsz=h*w #長*寬得到總像素點個數 numpx=int(max(math.floor(imsz/1000),1)) #取總個數的前0.1% darkvec=dark.reshape(imsz,1); #復制原圖 imvec=im.reshape(imsz,3); #復制暗通道圖 darkvec1=np.transpose(darkvec) #橫縱坐標互換 indices=darkvec1.argsort(); #按像素值從小到大的順序獲取像素所在位置的下標 indices=indices[0][imsz-numpx::] #取前0.1%大的 atmsum=np.zeros([1,3]) #一行三列以0填充的矩陣 for ind in range(0,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 Recover(im, t, A, tx=0.1): res = np.empty(im.shape, im.dtype); t = cv2.max(t, tx); #如果t小于tx,取tx for ind in range(0, 3): #按公式計算 res[:, :, ind] = (im[:, :, ind] - A[0, ind]) / t + A[0, ind] return res
含天空部分的圖像去霧之后只能觀察到少許的去霧效果,圖像亮度大大降低,且天空部分過度曝光,去霧效果并不理想。
說明此算法本身確實對大面積天空部分并不適用。
針對上文得到的較為粗略的透射率,在本章對其進行優化,
何凱明曾提出過軟遮光的方法,該方法雖然獲得的透射率非常精細,但是運行速度極慢,成為致命弱點。
在實際使用中,效果并不理想。所以在本文中使用引導濾波的方法獲得更精準的透射率。
該方法的核心在于正方形的簡單模糊,而有很多個快速且獨立于半徑的算法都可以用于正方形的簡單模糊,使算法的運行速度大大提高,可以實際使用。
原理部分略過,因過于晦澀,需要深入了解的同學。
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;
算法對天空部分的處理效果并不理想,天空部分被和非天空部分會出現明顯的過渡區域和過度曝光現象。
這是算法從提出就存在的問題,為了解決這跟問題,從以下兩種思路進行優化。
在計算大氣光值時提到,A是所有按亮度取前0.1%像素點的平局值,由于天空部分的大氣光過大,影響了最后的平均值。
所以考慮設置一個最大全球大氣光值作為所有像素點的閾值,如果有像素點的值大于閾值,該值就等于閾值。
這里將閾值設置為220。
因為這種直接取閾值的方法有些絕對,所以多次實驗之后發現結果并無較大改變。
考慮到上面直接取閾值的方法有些絕對,所以想到設置一個參數來重新計算透射率。
正常情況下,天空部分的大氣光值和A使比較接近的,而只有遠離天空的地方才能用暗通道先驗算法去霧。
所以將符合條件的像素點的值與A相減,如果結果小于某個值,認為這個區域可能是天空,就需要重新計算透射率。
如果結果小于某個值,則認為該區域不是天空,不用重新計算透射率。
這里的某個值,設置為k,每個像素處的透射率用它來調節,則改良后的透射率計算公式為
經過實驗,該方法對去霧校果有非常大的改善。
窗口的大小對去霧效果來說是個關鍵的參數。
從理論角度分析,窗口更大,就有更大的概率包含暗通道,暗通道也就越暗,與無霧圖像的對比越不明顯,去霧效果也就不好。
實驗得到:窗口越大,去霧的效果越不好。窗口大小在11-51之間去霧效果最好。
ω最初是為考慮維持景深,所以保留一定程度的霧,所以其值越小,保留的霧越多,當然去霧效果越不好。
實驗后發現,取0.95最佳。
關于導向濾波中的半徑r值,因為在前面進行形態學處理暗通道的圖像成一塊一塊的。
為了使透射率率更加精準,實驗后發現,r的取值大于等于窗口大小的4倍最好。
源碼下載地址:待審核
完整論文下載地址:待審核
?今天是堅持刷題更文的第48/100天
?各位的點贊、關注、收藏、評論、訂閱就是一條創作的最大動力
為了回饋各位粉絲,禮尚往來,給大家準備了一條多年積累下來的優質資源,包括 學習視頻、面試資料、珍藏電子書等
大家可以點這里領取
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/118783.html
摘要:很多人可能會問這個故事和生成式對抗網絡有什么關系其實,只要你能理解這段故事,就可以了解生成式對抗網絡的工作原理。 男:哎,你看我給你拍的好不好?女:這是什么鬼,你不能學學XXX的構圖嗎?男:哦……男:這次你看我拍的行不行?女:你看看你的后期,再看看YYY的后期吧,呵呵男:哦……男:這次好點了吧?女:呵呵,我看你這輩子是學不會攝影了……男:這次呢?女:嗯,我拿去當頭像了上面這段對話講述了一位男...
此專欄文章是對力扣上算法題目各種方法的總結和歸納, 整理出最重要的思路和知識重點并以思維導圖形式呈現, 當然也會加上我對導圖的詳解. 目的是為了更方便快捷的記憶和回憶算法重點(不用每次都重復看題解), 畢竟算法不是做了一遍就能完全記住的. 所以本文適合已經知道解題思路和方法, 想進一步加強理解和記憶的朋友, 并不適合第一次接觸此題的朋友(可以根據題號先去力扣看看官方題解, 然后再看本文內容). 關...
??蘇州程序大白一文教你學會微信小程序開發??《??記得收藏??》 目錄 ????開講啦!!!!????蘇州程序大白?????博主介紹?前言?講講專享小程序有什么優勢? ?小程序文件分析?事件綁定?圖片問題?輪播圖swiper?自定義組件?生命周期?頁面生命周期?項目制作?緩沖事件?`es7 async`語法 ?觸底事件??下拉刷新頁面??css省略號??預覽大圖??購物車模擬??獲取地...
閱讀 1639·2023-04-25 20:36
閱讀 2048·2021-09-02 15:11
閱讀 1176·2021-08-27 13:13
閱讀 2653·2019-08-30 15:52
閱讀 4586·2019-08-29 17:13
閱讀 1000·2019-08-29 11:09
閱讀 1490·2019-08-26 11:51
閱讀 833·2019-08-26 10:56