圖像恢復的MAP推理公式:
$\hat{x}\text{}=\text{}$arg min$_{x}\frac{1}{2}||\textbf{y}\text{}-\text{}\textbf{H}x||^{2}\text{}+\text{}\lambda\Phi(x)$
正則化項$\Phi(x)$對應恢復的表現扮演了至關重要的角色:
$\textbf{z}_{k+1}\text{}=\text{}Denoiser(\textbf{x}_{k+1},\sqrt{\lambda/\mu})$
然后介紹現在的降噪先驗只要采取model-based 優化方法去解決inverse problem,包括:
-- total variation(TV)法 ==》 常常制造watercolor-like 鬼影、偽影
-- 高斯混合模型(Gaussian mixture model,GMM)
-- K-SVD ==》高計算消耗
-- 非局部均值(Non-local means) ==》如果圖像不具有自相似屬性,會過度平滑不規則的結構
-- BM3D==》 如果圖像不具有自相似屬性,會過度平滑不規則的結構
圖像的顏色先驗是一個十分重要的考慮因素,因為圖像大多數圖像是RGB格式。
而由於不同圖像通道之間的相關性,聯合處理圖像的不同通道常常會產生更好的表現比獨立處理每個顏色通道。
許多工作都只對灰度圖像進行建模,而對於彩色圖像的建模較少;
作者指出CBM3D 因為聯合處理了RGB通道,收獲了不錯的效果,同時作者提出可以使用判別學習方法去自動化的揭示潛在的彩色圖像先驗,而不是依靠手工設計的pipeline;
CNN降噪先驗具有速度、表現、判別彩色圖像建模的優勢,同時CNN去學習判別式降噪器(discriminative denoiser)有一些原因:
-- CNN 的前向傳播由於GPU的存在而並行計算
-- CNN 表現出了強大的先驗建模能力with deep architecture
-- CNN利用外部先驗,作為了BM3D為代表的內部先驗的補充
-- 利用判別式學習的優勢
模型結構
CNN denoiser 如上圖所示,網絡包含七層,其中第一層是"擴張卷積(擴張指標為1,感知域還是3*3)+RELU",2-6層為“擴張卷積(擴張指標分別為2 3 4 3 2)+BN+RELU”, 最后一層為“擴展卷積(1),相當於正常的卷積運算,且每個中間層的特征圖的數量都為64
擴張卷積filter and 增大的感知域
-- 在圖像降噪中,上下文的信息能夠促進毀壞像素的重建;
-- 為了捕獲上下文的信息,通過前向的卷積操作去增大感知域是一個成功的方法;
有兩種基本的增大感知域的方法:
-- 一個是增大filter size 弊端:會引入更多的參數,增大了計算負擔
-- 一個是增大模型的深度
使用擴張卷積去獲取filter size 和模型深度的平衡, 在保持 3*3 filter 的基礎上 增大感知域, 整個7層網絡實現了 33*33 的感知域, 相當於16層的3*3普通卷積;
其中擴張卷積的filter size 和 擴張指標s 之間的關系為: size = (2s+1)*(2s+1)
使用BN和殘差學習加快訓練
對於高斯降噪問題,結合BN和殘差學習是十分有幫助的,他們都能夠互相的獲益(在他的論文中有講Residual learning of deep CNN for image denoising.) 對於模型的遷移也有用;
殘差學習方式,就是模型的目標不是直接學習產生降噪的圖片,而是學習噪聲即殘差,即輸入的帶噪聲的圖片和干凈圖片的差。
使用小尺寸的圖像作為訓練集去避免邊緣偽影
-- 由於CNN的特點,如果沒有合適的處理,CNN的降噪圖片將會產生邊緣偽影;
-- 對稱pandding 和 zero padding是兩種解決這個問題的方法
-- 對於擴張指數為4的操作,在邊緣pads 4 zeros,那其他的擴張指數呢?
-- 經驗主義的使用了小尺寸的訓練樣本 去避免邊緣偽影,原因包括:
-- 將大尺寸的圖像crop 成小尺寸的patches,有利於CNN去看到更多的邊沿信息,比如將70*70的patches crop成四個非重疊的35*35的patches,邊緣信息被擴大了;
-- 就patch的大小可以作對比試驗進行驗證;
-- 當訓練的patch尺寸小於感知域后,這個性能會下降;
學習實際的降噪器模型with 小間隔的噪聲水平
-- 想要得到精確的子問題的解是非常困難且time-consuming的去優化的,使用不精確但是快速的子問題的解能夠加快收斂(兩篇文獻:The augmented lagrange multiplier method for exact recovery of corrupted low-rank matrices.和 From learning models of natural im age patches to whole image restoration.)
-- 所以 沒有必要去學習很多判別式降噪模型for 每個噪聲水平。
-- 盡管$\textbf{z}_{k+1}\text{}=\text{}Denoiser(\textbf{x}_{k+1},\sqrt{\lambda/\mu})$ 是一個降噪器,但他與傳統的高斯降噪有着不同的目標。
-- 傳統的高斯降噪是恢復出潛在的干凈圖像,無論要去噪的圖像的噪聲類型和噪聲水平如何,這里的去噪器都會發揮自己的作用。也就是說,不管這個圖像有沒有噪聲,都會發揮作用!
-- 所以一個理想的判別降噪器應該使用當前的噪聲水平進行訓練:
訓練了一系列的噪聲水平在0-50同時獨立的以2為間隔的模型,產生了25個模型為圖像的先驗進行建模;迭代方案的存在,使他恢復足以滿足。
實驗
圖像降噪:
-- 將每個圖片 crop 成了35*35的patches,因為使用殘差學習的方式,損失函數:
$\textit{l}(\Theta)\text{}=\text{}\frac{1}{2N}\sum_{i=1}^{N}||f(y_{i};\Theta)\text{}-\text{}(y_{i}\text{}-\text{}x_{i})||^{2}$
-- 訓練結束的標志 訓練損失在五個連續的epoch固定
-- 使用了旋轉翻轉等數據擴充技巧;
-- 從不同方法的PSNR 進行了對比, 分別書灰度圖和彩色圖
-- 從不同方法的運行時間進行了對比
圖像去模糊:
模糊核的選擇:
-- 一個常見的模糊的高斯模糊核,標准差為1.6, 來自論文(Understanding and evaluating blind deconvolution algorithms)的前兩個的真實模糊核;
-- 我們只需將顏色去噪器插入到HQS框架中;
-- 在公式6中:
-- 兩個參數中,$\lambda$ 與$\sigma^{2}$相聯系同時在迭代中保持固定,其中$\mu$控制着降噪器的噪聲水平;
公式6(a)的快速解法:
$x_{k+1}=(H^{T}H+\mu I)^{-1}(H^{T}y+\mu z_{k}) \text{ }\text{ }\text{ }\text{ }\text{ }\text{ }(7)$
-- 由於hqs框架是基於去噪的,因此我們將每次迭代中去噪的噪聲級隱式的確定為μ。
-- 在我們的實驗設置中,根據噪聲水平,它以指數形式從49衰減到[1,15]中的值。
-- 實驗代碼核心迭代部分
%模擬仿真的模糊噪聲圖片 k = fspecial('gaussian', 25, 1.6);%相當於是模糊算子 y = imfilter(im2double(x), k, 'circular', 'conv') + sigma*randn(size(x)); %denominator 表示是H^{T}H, H模糊算子與他的共軛矩陣相乘 V = psf2otf(k,[w,h]);%psf2otf(PSF) 其作用是將一個空間點擴散函數轉換為頻譜面的光學傳遞函數,執行的也是對PSF的FFT變換,變為了頻域; denominator = abs(V).^2;%y = abs(3+4i) y=5 %H^{T}*y H的共軛矩陣乘以輸入y upperleft = conj(V).*fft2(y); % conj(V) V=5-2i ==> 5+2i %訓練的特點噪聲水平\sigma的一組denoiser,其\sigma以指數形式的衰減的不同模型; modelSigmaS = logspace(log10(modelSigma1),log10(modelSigma2),totalIter); %\lamba與噪聲水平\sigma^2有關且在迭代中保持固定,\mu控制着降噪器的噪聲水平,%rho隱式的表示\mu,見下面的計算方法與降噪器的噪聲水平和噪聲水平有關 rho = lamda*255^2/(modelSigmaS(itern)^2);%[243.742,267.099,292.694,320.742,351.476] upperleft = for itern = 1:totalIter %%% step 1 rho = lamda*255^2/(modelSigmaS(itern)^2); z = real(ifft2((upperleft + rho*fft2(z))./(denominator + rho))); if ns(itern+1)~=ns(itern) [net] = loadmodel(modelSigmaS(itern),CNNdenoiser); net = vl_simplenn_tidy(net); if useGPU net = vl_simplenn_move(net, 'gpu'); end end %%% step 2 res = vl_simplenn(net, z,[],[],'conserveMemory',true,'mode','test'); residual = res(end).x; z = z - residual; end
真實模糊圖像的測試
設置了兩個重要的估計圖像噪聲水平 和 降噪器去噪水平的 超參數: % There are two important parameters to tune: % (1) image noise level of blurred image: Isigma and % (2) noise level of the last denoiser: Msigma. %使用了 別人的方法 產生的模糊核 圖像作為先驗的條件 %% read blurred image and its estimated kernel % blurred image Iname = 'im01_ker01'; y = im2single(imread(fullfile(folderTestCur,[Iname,'.png']))); % estimated kernel %k = imread(fullfile(folderTestCur,[Iname,'_kernel.png'])); k = imread(fullfile(folderTestCur,[Iname,'_out_kernel.png'])); if size(k,3)==3 k = rgb2gray(k); end k = im2single(k); k = k./(sum(k(:))); %歸一化 %比較重要的部分是邊緣的處理 %% handle boundary boundary_handle = 'case2'; switch boundary_handle case {'case1'} % option (1), edgetaper to better handle circular boundary conditions, (matlab2015b) % k(k==0) = 1e-10; % uncomment this for matlab 2016--2018? ks = floor((size(k) - 1)/2); y = padarray(y, ks, 'replicate', 'both'); for a=1:4 y = edgetaper(y, k); end case {'case2'} % option (2) H = size(y,1); W = size(y,2); y = wrap_boundary_liu(y, opt_fft_size([H W]+size(k)-1)); end
需要明白為什么需要進行邊緣條件的變化,是讓模糊核完全重合和圖像,所以需要用模糊核 進行 一些 padding 操作