[论文复现]何恺明博士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!

转载于:https://www.cnblogs.com/bamboopu/p/10154910.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值