[論文復現]何愷明博士CVPR2009去霧算法(1)


一、前言

近期打算研讀一下何博士第一篇文章,復現其論文算法,主要參考的博文有:

[1] Kaiming He論文心得 https://www.cnblogs.com/molakejin/p/5708883.html

[2] 論文原理、實現與效果 http://www.cnblogs.com/Imageshop/p/3281703.html

[3] 論文原文及相關資料下載 http://kaiminghe.com/

[4] Kaiming He谷歌學術 https://scholar.google.com/citations?user=DhtAFkwAAAAJ&hl=zh-CN

[5] 基於顏色衰減先驗去霧算法 https://www.cnblogs.com/zjuthantics/p/5276856.html

關鍵詞:暗通道先驗、matlab鼠標交互、plot更新繪制點

這是第一部分工作,主要驗證暗通道先驗理論,參考了[5]中資料。

 

二、實現

暗通道先驗:“在絕大多數非天空的局部區域里,某一些像素總會有至少一個顏色通道具有很低的值。”

[5]中給了下面這張圖很清晰的驗證了顏色衰減先驗理論,本次通過matlab編寫一個小程序能夠盡量做出下圖的效果去驗證暗通道先驗。

暗通道先驗

圖2-1 顏色衰減通道先驗效果

 

程序思想比較簡單,練習一下Matlab的鼠標事件響應函數,主要包括:讀圖-排序濾波-鼠標事件處理-繪圖

編寫過程中稍微有點繞的環節有:

1.點擊鼠標在當前位置繪制點並刪除上一鼠標位置繪制的點;

解決方法:

point1=plot(1,1,'ro');

set(point1,'Visible','off');

point1=plot(xnew,ynew,'ro');

將plot賦給句柄,然后調用句柄屬性讓其不再顯示,然后對新坐標重新命名句柄。

一開始做的是單點觀察,后來添加了平均卷積核求窗口均值,使用rectangle繪制,與point思路一樣。

2.鼠標輸入函數對划分了subplot的圖形坐標異常

[xnew,ynew,button]=ginput(1);

 划分subplot再使用ginput時,每個子Plot有自己的坐標值,這使得當鼠標點到邊界時獲得的坐標值很奇怪,此處沒有深究各個坐標值關系,簡單將溢出的坐標值移動到左上角。

3.暗通道計算過程;

首先使用排序濾波分別取三通道最小值,使用函數為ordfilt2(),如下。

a_r_f=ordfilt2(a_h,1,ones(radius,radius),'symmetric');

隨后並沒有直接對對三個通道RGB取最小值,而是分別用柱狀圖畫出了RGB值。

 

三、代碼

%%
% 霧色圖片按通道先驗
% 2018年12月21日
% 使用方法:點擊鼠標選點觀察,可同時觀察三個點,右鍵退出
% Yuquan Campus, bamboopu
% 待改進功能:1.解決BUG1邊界坐標亂碼問題;2.重新排布subplot位置更加美觀;3.柱狀圖顯示數據;4.優化速度

%%
% clean
clear;
clc;

%%
% 讀圖顯示圖片
a_rgb=im2double(imread('canyon2.bmp'));
[height,weight,scale]=size(a_rgb);
fig=figure;
h1=subplot(3,2,[1 3 5]);
imshow(a_rgb);
hold on;
% rgb卷積
a_h=a_rgb(:,:,1);
a_s=a_rgb(:,:,2);
a_v=a_rgb(:,:,3);
radius=15;
% 排序
a_r_f=ordfilt2(a_h,1,ones(radius,radius),'symmetric');
a_g_f=ordfilt2(a_s,1,ones(radius,radius),'symmetric');
a_b_f=ordfilt2(a_v,1,ones(radius,radius),'symmetric');


%%
% 回調函數游標法-失敗,原因:未成功將數組傳入回調函數,回調函數也未返回坐標值
% dcm_obj = datacursormode(fig);
% set(dcm_obj,'UpdateFcn',@myupdatefcn)
% datacursormode on

%%
% 鼠標輸入法-成功
times=0;
% 初始點句柄,設置為不顯示
r1=rectangle('Position',[weight*0.5,height*0.5,2*radius+1,2*radius+1],'EdgeColor','r');
set(r1,'Visible','off');
r2=rectangle('Position',[weight*0.5,height*0.5,2*radius+1,2*radius+1],'EdgeColor','g');
set(r2,'Visible','off');
r3=rectangle('Position',[weight*0.5,height*0.5,2*radius+1,2*radius+1],'EdgeColor','b');
set(r3,'Visible','off');
hold off;
while(0==0)
    % xnew為列數,ynew為行數
    [xnew,ynew,button]=ginput(1);
    % 鼠標右鍵退出
    if length(xnew)<1||button==3
        close;
        break
    end
    xnew=int32(xnew);
    ynew=int32(ynew);
    % 邊界處理-BUG1:使用subplot后點擊窗口外的區域坐標值未知大小
    if xnew>=weight-radius
        xnew=weight-radius;
    end
    if ynew>=height-radius
        ynew=height-radius;
    end
    if xnew<=1+radius
        xnew=1+radius;
    end
    if ynew<=1+radius
        ynew=1+radius;
    end
    % 查找值
    Value_r=a_r_f(ynew,xnew);
    Value_g=a_g_f(ynew,xnew);
    Value_b=a_b_f(ynew,xnew);
    x=[1 2 3];
    y=[Value_r,Value_g,Value_b];
    barsize=0.3;
    switch mod(times,3)
        case 0
            % 點的替換
            h1=subplot(3,2,[1 3 5]);hold on;
            set(r1,'Visible','off');
            r1=rectangle('Position',[xnew-radius,ynew-radius,2*radius+1,2*radius+1],'EdgeColor','r');
            hold off;
            
            % 子窗口顯示
            h2=subplot(3,2,2);
            bar(x,y,barsize,'Facecolor',[1,0,0]);
            ylabel('Intensity');grid on;
            set(gca,'xticklabel',{'R','G','B'});
            axis([0,4,0.,1.]);
            title('Red Point');
        case 1
            % 點的替換
            h1=subplot(3,2,[1 3 5]);hold on;
            set(r2,'Visible','off');
            r2=rectangle('Position',[xnew-radius,ynew-radius,2*radius+1,2*radius+1],'EdgeColor','g');
            hold off;
            
            % 子窗口顯示
            h3=subplot(3,2,4);
            bar(x,y,barsize,'Facecolor',[0,1,0]);
            ylabel('Intensity');grid on;
            set(gca,'xticklabel',{'R','G','B'});
            axis([0,4,0.,1.]);
            title('Green Point');
        case 2
            % 點的替換
            h1=subplot(3,2,[1 3 5]);hold on;
            set(r3,'Visible','off');
            r3=rectangle('Position',[xnew-radius,ynew-radius,2*radius+1,2*radius+1],'EdgeColor','b');
            hold off;
            
            % 子窗口顯示
            h4=subplot(3,2,6);
            bar(x,y,barsize,'Facecolor',[0,0,1]);
            ylabel('Intensity');grid on;
            set(gca,'xticklabel',{'R','G','B'});
            axis([0,4,0.,1.]);
            title('Blue Point');
        otherwise
            disp('Something went wrong.');
    end
    % 顯示數值-已取消
        disp(['R=' num2str(Value_r*255)]);
        disp(['G=' num2str(Value_g*255)]);
        disp(['B=' num2str(Value_b*255)]);
        disp([' ']);
    % 記錄點擊次數
    times=times+1;
end

  

四、效果

圖4-1暗通道先驗驗證程序

 

五、心得

 這次小程序還沒涉及到論文里的算法部分,主要是一些業務代碼,用來熟悉matlab編程,目前水平比較一般,編寫的還不夠快,調試也花了很久。碼不停題,GO!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM