“暗通道”到底是個什麼東西

對於圖像去霧領域的研究者來說,何凱明博士的“暗通道先驗(DCP)”可謂是奉若圭臬,接觸這個概念一年了,但一直沒有深挖,一直都是“拿來主義”,看大家粗略地一概而過,今天一時興起,想着小搞一波,咱們就稍微深入一點,看看這個神奇的“暗通道”到底是個什麼東西。

先來一段經典的代碼吧,何博士的基於暗通道先驗的單幅圖像去霧中的部分代碼,本人做了詳細的註釋,應該是可以看懂的:

clear all;
I=imread('xxxx\dehazing.png');  %讀取圖片
I=double(I);  %將讀入圖像I的uint8數據轉換爲double類型的數據
I=I./255;  %將像素值轉換到0~1之間
dark=darkfunction(I);

subplot(1,2,1);imshow(I);
subplot(1,2,2);imshow(dark);  %展示霧圖和對應的暗通道

function [dark] =darkfunction(I)
R=I(:,:,1);  %將I的第一層賦值給R,下面的G、B分別爲I的第二、三層
G=I(:,:,2);  %三個參數分別代表行、列和層
B=I(:,:,3);
[m,n]=size(R); %size求取矩陣大小,返回其行列值,即m、n
a=zeros(m,n);  %zeros返回 m x n 大小的零矩陣
for i=1:m   %i從1開始一直循環到m
    for j=1:n
        a(i,j)=min(R(i,j),G(i,j));
        a(i,j)=min(a(i,j),B(i,j));
    end;
end;  
%整個for循環就是求取所有像素的RGB三通道(層)中的最小值,最後得到
%一副和原始圖像同樣大小的灰度圖,即單通道圖像
d=ones(15,15); %ones產生15x15的全1矩陣
fun=@(block_struct)min(min(block_struct.data))*d; %最小值濾波
%@(block_struct)爲裝飾器函數,block_struct.data表示傳入的數據(圖片或者矩陣)
dark=blockproc(a,[15,15],fun); %blockproc爲分塊矩陣處理函數
dark=dark(1:m,1:n); 
end

代碼是基於matlab的,還是比較好理解的,最後的裝飾器類似於python,具體的功能就是實現最小值濾波。

以下純屬個人理解,如有錯誤還望各位指點一二:

通常彩色圖像都包括三個通道,即RGB三通道,也可以理解而成一張圖片又三層同樣大小的RGB(光學三原色:紅綠藍)三色堆疊而成,而圖片實質上是由一個個像素組成的,對應於RGB三色來說,每一種顏色都是由這三原色組合而成,比如紅色爲(255,0,0),綠色爲(0,255,0),粉紅爲(255,192,203),也就是說一張彩色圖片中的每個像素都是以這種形式來表示的。

那麼我們通常所說的暗通道,即清晰無霧的圖片中除天空區域(因爲天空區域或者白色區域和霧的特徵較爲接近)外的任一局部區域像素至少有一個通道值很低,幾乎趨近於零。那如何求暗通道呢,我們在上面的代碼中已經做了詳細的說明,便是先求每個像素在三個通道中的最小值,然後得到一張與原始圖像大小一致的灰度圖,然後再使用最小值濾波進行平滑處理,即在得到的灰度圖中,以每一個像素爲中心取一定大小的矩形窗口(本文爲15x15),取矩形窗口中灰度值的最小值代替中心像素的值,從而得到原始圖像對應的暗通道圖像。(求暗通道過程中要計算兩次最小值)

爲了更加直觀地展示暗通道圖像,我們先看一下上面代碼的結果,即霧圖和其對應的暗通道圖:

可以發現有霧的圖片對應的暗通道整體偏灰白,即其灰度值較高(0代表純黑,255代表純白,可以理解成灰度值越高其看起來越亮),然後我們再看看暗通道圖的真實面目,在matlab中輸出一下dark:

這是部分面貌,因爲體量太大,無法完全顯示出來,該圖大小爲413x550:

可以看出經過最小值濾波後的暗通道圖比較平滑,局部區域內的像素值都是一致的(關於最小值濾波的過程大家可以查一下資料,我本來想畫個圖說一下其運行原理,發現要是詳細地講解一番工作量還是比較大的,這不是本文的重點哈~)

還有一個點大家應該也注意到了,便是我們一開始在求暗通道的霧圖之前先是進行了“I=I./255;”的操作,這是因爲imshow對unit8類型的數據識別範圍爲0~255,但我們爲了增加圖片的精度,通常會將其轉換爲double,而imshow對double精度的識別範圍爲0~1,大於1則顯示白色,所以我們在進行顯示圖片前要將一開始的unit8類型轉換爲double類型之後再做 /255 的操作,這一點是不影響正常顯示最終的暗通道圖的。還有一點就是正常的清晰圖像即使不做 /255 的操作,其局部像素的最小值也是很小的,經過最小值濾波後可以近似爲零。

來看一下未做最小值濾波前的灰度圖長什麼樣吧:

這便是對每個像素的三通道取最小值所得的,爲了更加直觀,我們看一下對應的RGB三通道值:

       

不難看出,每個像素點取三通道中的最小值便可得到其對應的灰度圖。

我們再來看看一下清晰圖像和其對應的暗通道圖:

可以發現其整體偏暗,再通過其灰度值更直觀地感受一下:

以上是截取的清晰圖像求取三通道最小值後所得的灰度圖,可以發現其灰度值普遍較小~~

大概就是這樣子了,可能有些地方還比較模糊,繼續努力吧~~

如果文章對您有一點點幫助,還請打賞一二,您的鼓勵是我前進的不竭動力

微信公衆號爲:非著名IT表演藝術家

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章