精华内容
下载资源
问答
  • 一、雾图形成模型: —待去雾图像;—恢复的无雾的图像;—全球大气光成分;—透射率 变形: ...c为R、G、B三通道。...经过大量实验,局部找最点进行均匀去雾有很好的效果,由此推出Dark Channel Prior将全局改为

    一、雾图形成模型:

    I(x)=J(x)t(x)+A(1-t(x))

    I(x)—待去雾图像;J(x)—恢复的无雾的图像;A—全球大气光成分;t(x)—透射率

    变形:

    \frac{I^{c}(x)}{A^{c}}=t(x)\frac{J^{c}(x)}{A^{c}}+1-t(x)

    c为R、G、B三通道。

    二、Dark Channel Prior——统计规律

    对于一个无雾图像,每个局部区域很可能至少一个颜色通道会有很低的值,或黑色东西。(非天空区域)

    每个局部区域都总有一些很暗的东西。

    Dark Object Subtraction:利用全图最暗点来去除全局均匀的雾。

    经过大量实验,局部找最暗点进行均匀去雾有很好的效果,由此推出Dark Channel Prior将全局改为局部去雾。

    三、暗通道先验

    任意输入图像J,暗通道表达式:

    J^{dark}(x)=_{y\in \Omega (x)}^{min}(_{c\in \left \{ r,g,b \right \}}^{min}J^{c}(y))

    J^{c}—彩色图像的每个通道;\Omega (x)—以像素x为中心的一个窗口

    在以x为中心的最小区域中找出r,g,b通道中最低值。

    求每个像素RGB分量最小值,存入一副和原始图像大小相同的灰度图中,再对这幅灰度图进行最小值滤波。

    WindowSize = 2\times Radius+1

    窗口大小                        滤波半径

    四、有无雾图像区别

    有雾:暗通道存在大面积灰白情况

    无雾:暗通道大部分黑色

    展开全文
  • 本文主要讲解,何恺明暗通道先验去雾以及加权最小二乘算法的原理部分,对应代码可在资源处下载。1暗通道先验去雾模型 公式(1)是常用的雾霭形成模型: (1)其中,I(x)为实际拍摄到的有雾视频帧,J(x)为去雾后的原...

    本文主要讲解,何恺明暗通道先验去雾以及加权最小二乘算法的原理部分,对应代码可在资源处下载。

    1暗通道先验去雾模型

     公式(1)是常用的雾霭形成模型:

                                (1)

    其中,I(x)为实际拍摄到的有雾视频帧,J(x)为去雾后的原视频帧,A表示全球大气光成分,先对暗原色的亮度进行排序,从中选出暗原色亮度最大的像素的0.1%的值,它们对应原图中所有强度值的最大值即为A;t(x)用来描述太阳光通过媒介投射到摄像机过程中没有被散射的部分,简称透射率图或介质传输率,可表示为(0≤t(x)≤1)。而去雾就是通过I(x)得到J(x)的过程。方程右边的J(x)t(x)叫做直接衰减项,A(1-t(x))则是大气光成分,它反映了大气散射光对成像光强的影响,造成了视频帧的不同程度模糊和色调的偏移。

    何恺明等通过大量统计,发现在自然场景视频帧中非天空部分的局部区域里的某些像素点,至少有一个颜色通道的值很低以至趋于0。因此进而他提出了暗通道先验去雾模型,即对任意的自然场景无雾图像J(x),其暗通道满足:

                        (2)

    其中J(x)是无雾图像在RGB三个颜色通道中的暗原色,相对应的I(x)是某一RGB的单色通道的实际有雾帧,在以为中心的局部邻域内,将(2)式带入(1)式后得

                        (3)

    参数w是调整因子,且满足0<w<1,其值越小,去雾效果越不明显。添加w是为了针对性的保留视频帧遥远景物的雾,A被定义为某一单色通道的大气光成分。因为户外自然场景中总是会存在一些杂质,彻底去雾会造成视觉上失真,之后将(3)式求得的透射率图带入到(1)式中,即可求得去雾后图像J(x)

                                        (4)

        暗通道先验模型通常建立在户外自然场景基础上,当取景对象在较大范围内和天空接近并且没有阴影覆盖的时候,视频帧中的灰白色和空气颜色接近,暗通道先验模型会错误处理该区域的透射率,造成去雾后的对应区域上亮度降低,从而使得暗通道先验假设不成立。另外由于含雾图像在某一邻域内的RGB通道最小值和暗通道先验求解的结果不匹配,而使暗通道先验模型去雾造成去雾图像边缘不平滑。综上所述,对基于暗通道先验的去雾算法而言,获取合适的透射率图t(x)和正确的大气光成分A,是得到无雾视频的两个关键因素。


     

    2导向滤波和加权最小二乘滤波原理

    2.1导向滤波原理

          导向滤波由局部线性模型发展而来,它作为一种高效且能够提取方向信息的滤波器组,任意方向的滤波器可以由一组基滤波器线性累加而成。何恺明首次将之用于图像去雾,针对计算透射率初估计值的过程中出现一定程度的块效应,提出用导向滤波来细化之前得到的粗略透射率图。

        导向滤波输出图中的任意一个像素点i可以表示为一个加权平均:

                                   (5)

    上式中i和j是处理像素的像平面的横坐标和纵坐标,wij(I)是可以作为目标效果的导向图像I和原始图像P。

        在利用导向滤波时,定义核函数为:

                                  (6)

        根据上式可以看出,qi和Ii之间是局部线性关系,其中i为像素坐标,I代表引导图像,q为结果影像,可以认为qi是在大小为wk、以像素k为中心的窗口内所有像素的线性变换。此处对应的就是经过优化后的透射率分布图,定义价值函数如下:

                         (7)

    公式(7)中的E为正则化参数,主要是为了避免系数ak过大。之后采用最小二乘法求解得到系数如下:

                              (8)

                                            (9)

    其中uk是含雾图像I在窗口wk中的平均值,是I在窗口wk中的方差,|w|是窗口wk中像素的数量,pk是待滤波图像p在窗口wk中的平均值。

           在导向滤波器中,滤波半径的选取对去雾后的效果有一定影响。当滤波半径较大时,导向滤波图会更大范围内进行平行线输出,使得透射率图与有雾视频帧的边缘特征更加相似且内容丰富,降低了边缘不平滑现象。但是滤波半径过大,会使无雾视频帧在对应区域出现颜色过饱和或者去雾不足现象。

    2.2加权最小二乘滤波原理

           加权最小二乘法滤波能有效的保留视频帧中的部分边缘信息。该算法无法保留较多的对比度较小的边缘,也不能一次性完整提取对比度较大的细节,所以需要渐进式提取边缘。异方差性是相对于同方差而言的,随机误差项具有不同的方差,则称线性回归模型存在异方差性,加权最小二乘法在很大程度上解决了异方差性问题,首先用某一权数对样本观测值或残差加权,再使用普通最小二乘法估计参数模型。对于输入视频帧g,寻求结果视频帧u,一方面希望u尽可能接近g,与此同时,u除了在g一些边缘梯度变化比较大的地方外应该越平滑越好,形式上即寻求式(10)的值最小

                  (10)  

          其中下标p为像素位置。数据项的目的是尽可能缩小u和g的差距,第二项则是用偏导数实现平滑,这和输入的视频帧g有很大关系。当g边缘梯度变换很大时,我们希望其约束小一些,而当g边缘梯度变换很小时,这些细节信息可认为不重要,对其约束可以大一些。而ax和ay为平滑权重,一般取值在1.2至2.0之间,主要目的是控制其对梯度的敏感度。负责两项的值平衡,从而使平滑效果有所不同。在视频帧中,一维梯度中的算子在任何位置都是不变的,在此可定义为常量,然后对求二阶导数,在使式(10)取得最小值的情况下,可求得结果视频帧u的最优值。



    附上一些去雾效果:



    展开全文
  • 根据暗通道先验原理估计出大气光强度和初始透射率,采用局部多项式核回归对透射率进行精细化处理,利用细化后的透射率和估计出的大气光强度恢复雾霾图像。通过大量的实验数据表明,该方法可以有效地对雾霾图像实现...
  •  首先看看暗通道先验是什么:  在绝大多数非天空的局部区域里,某一些像素总会有至少一个颜色通道具有很低的值。换言之,该区域光强度的最小值是个很小的数。  我们给暗通道一个数学定义,对于任意的...

    http://blog.csdn.net/s12244315/article/details/50292049

      在图像去雾这个领域,几乎没有人不知道《Single Image Haze Removal Using Dark Channel Prior》这篇文章,该文是2009年CVPR最佳论文。作者

    何凯明博士,2007年清华大学毕业,2011年香港中文大学博士毕业,可谓是功力深厚,感叹于国内一些所谓博士的水平,何这样的博士才可以真正叫做

    Doctor。

         关于何博士的一些资料和论文,大家可以访问这里:http://research.microsoft.com/en-us/um/people/kahe/

        

         本文主要上是对《Single Image Haze Removal Using Dark Channel Prior》的翻译、整理、及部分解释、代码实现。如果您的英文水平好,建议看原

    文可能来的更爽些。

        一、论文思想的简单描述 

         首先看看暗通道先验是什么:

           在绝大多数非天空的局部区域里,某一些像素总会有至少一个颜色通道具有很低的值。换言之,该区域光强度的最小值是个很小的数。

      我们给暗通道一个数学定义,对于任意的输入图像J,其暗通道可以用下式表达:

                                        

          式中Jc表示彩色图像的每个通道 ,Ω(x)表示以像素X为中心的一个窗口。 

        式(5)的意义用代码表达也很简单,首先求出每个像素RGB分量中的最小值,存入一副和原始图像大小相同的灰度图中,然后再对这幅灰度图进行最小值

    滤波,滤波的半径由窗口大小决定,一般有WindowSize = 2 * Radius + 1;          

          暗通道先验的理论指出:

                                                                           

         实际生活中造成暗原色中低通道值主要有三个因素:a)汽车、建筑物和城市中玻璃窗户的阴影,或者是树叶、树与岩石等自然景观的投影;b)色彩鲜艳的物

    体或表面,在RGB的三个通道中有些通道的值很低(比如绿色的草地/树/植物,红色或黄色的花朵/叶子,或者蓝色的水面);c)颜色较暗的物体或者表面,

    例如灰暗色的树干和石头。总之,自然景物中到处都是阴影或者彩色,这些景物的图像的暗原色总是很灰暗的。

         在作者的论文中,统计了5000多副图像的特征,也都基本符合这个先验,因此,我们可以认为其实一条定理。

          有了这个先验,接着就需要进行一些数学方面的推导来最终解决问题。

      首先,在计算机视觉和计算机图形中,下述方程所描述的雾图形成模型被广泛使用:

                                                       

       其中,I(X)就是我们现在已经有的图像(待去雾的图像),J(x)是我们要恢复的无雾的图像,A是全球大气光成分, t(x)为透射率。现在的已知条件就是

    I(X),要求目标值J(x),显然,这是个有无数解的方程,因此,就需要一些先验了。

      将式(1)稍作处理,变形为下式:

                                                        

        如上所述,上标C表示R/G/B三个通道的意思。

        首先假设在每一个窗口内透射率t(x)为常数,定义他为,并且A值已经给定,然后对式(7)两边求两次最小值运算,得到下式:

                                      

        上式中,J是待求的无雾的图像,根据前述的暗原色先验理论有:

                                                   

         因此,可推导出:

                                                             

        把式(10)带入式(8)中,得到:

                                                     

        这就是透射率的预估值。

        在现实生活中,即使是晴天白云,空气中也存在着一些颗粒,因此,看远处的物体还是能感觉到雾的影响,另外,雾的存在让人类感到景深的存在,因此,有

    必要在去雾的时候保留一定程度的雾,这可以通过在式(11)中引入一个在[0,1] 之间的因子,则式(11)修正为:

                                                   

         本文中所有的测试结果依赖于:  ω=0.95。

         上述推论中都是假设全球达气光A值时已知的,在实际中,我们可以借助于暗通道图来从有雾图像中获取该值。具体步骤如下:

          1) 从暗通道图中按照亮度的大小取前0.1%的像素。

              2) 在这些位置中,在原始有雾图像I中寻找对应的具有最高亮度的点的值,作为A值。

         到这一步,我们就可以进行无雾图像的恢复了。由式(1)可知:  J = ( I - A)/t + A  

         现在I,A,t都已经求得了,因此,完全可以进行J的计算。

         当投射图t 的值很小时,会导致J的值偏大,从而使淂图像整体向白场过度,因此一般可设置一阈值T0,当t值小于T0时,令t=T0,本文中所有效果图均以

    T0=0.1为标准计算。

         因此,最终的恢复公式如下:

                                    

         当直接用上述理论进行恢复时,去雾的效果其实也是很明显的,比如下面一些例子:

       

           

                     有雾图                                             去雾图

          注意到第一幅图的原图两个字的周围明显有一块不协调的地方,而第二图顶部水平方向似乎有一块没有进行去雾处理,这些都是由于我们的透射率图过于粗

    糙了。

          要获得更为精细的透射率图,何博士在文章中提出了了soft matting方法,能得到非常细腻的结果。但是他的一个致命的弱点就是速度特慢,不使用于实际

    使用。在2011年,何博士又除了一片论文,其中提到了导向滤波的方式来获得较好的透射率图。该方法的主要过程集中于简单的方框模糊,而方框模糊有多重和

    半径无关的快速算法。因此,算法的实用性特强,关于这个导向滤波算法大家在何博士的网站可以自己去研习下,除了在去雾方面外,还有着其他多方面的应

    用,这部分本文不多述。

         使用了导向滤波后的去雾效果:

         

      


      二、各参数对去雾结果的影响

      第一:窗口的大小。这个对结果来说是个关键的参数,窗口越大,其包含暗通道的概率越大,暗通道也就越黑。我们不去从理论角度分析,从实践的效果来

    看,似乎窗口越大,去雾的效果越不明显,如下图所示:

            

                                  (a) 原始图像                            (b) 窗口大小=11

          

                  (c) 窗口大小=21                         (d) 窗口大小=101 

      我的建议是窗口大小在11-51之间,即半径在5-25之间。

         式(12)中的ω具有着明显的意义,其值越小,去雾效果越不明显,举例如下:

          

                                        (a) 原始图像                                   (b)    ω=0.5         

              

                                           (c)    ω=0.8                                                                       (d)    ω=1 

        三:编码的步骤

      如果你仔细的分析了原文的细路,加上适当的参考,编码其实并不是很困难。

      1)根据原始图像求暗通道。

          2)按文中所描述的算法自动获得全球大气光的值。

         这里说明一点,原始论文中的A最终是取原始像素中的某一个点的像素,我实际上是取的符合条件的所有点的平均值作为A的值,我这样做是因为,如果是取

    一个点,则各通道的A值很有可能全部很接近255,这样的话会造成处理后的图像偏色和出现大量色斑。原文作者说这个算法对天空部分不需特备处理,我实际发

    现该算法对有天空的图像的效果一般都不好。天空会出现明显的过渡区域。作为解决方案,我增加了一个参数,最大全球大气光值,当计算的值大于该值时,则

    就取该值。  

               

                            原图                                                         未对A值做限定                  最大A值限定为220

           3) 按式(12)计算预估的透射率图。

      在式(12)中,每个通道的数据都需要除以对应的A值,即归一化,这样做,还存在一个问题,由于A的选取过程,并不能保证每个像素分量值除以A值后都

    小于1,从而导致t的值可能小于0,而这是不容许的,原文作者并没有交代这一点是如何处理的。我在实际的编码中发现,如果真的这样做了,其效果也并不是很

    理想 ,因此,我最后的办法是在式(12)中,不考虑A的计算。

            4)计算导向滤波图。

       这里可以直接用原始的图像做导向图,当然也可以用其灰度图,但是用RGB导向图在下一步的计算中会占用比较大的时间。

            5)按照《Guided Image Filtering》论文中的公式(5)、(6)、(8)编码计算获得精细的透射率图。c++代码见上一篇文章。

    还有一点就是,上述计算需要在[0,1]范围内进行,也就是说导向图和预估的透射率图都必须从[0,255]先映射到[0,1]在进行计算。

          关于guidedfilter中的半径r值,因为在前面进行最小值后暗通道的图像成一块一块的,为了使透射率图更加精细,建议这个r的取值不小于进行最小值滤波的

    半径的4倍,如下图所示:

        

              (a)  r=最小值滤波半径的2倍                        (b) r=最小值滤波半径的8倍

          可以看到,当r比较小的时候,在透射率图中基本看不到什么细节信息,因此恢复处的图像边缘处不明显。

          参数eps的取值也有所讲究,他主要是为了防止计算中除以0的错误以及为了使得某些计算结果不至于过大,一般建议取值0.001或者更小。

          如果使用的彩色RGB图做导向图,计算时间上会增加不少,所的到的透射率图的边缘会比灰度图所处理的保留了更多的细节,效果上略微比灰度图好。

           以RGB图为导向图的计算中,涉及到3*3部分矩阵求逆的过程,如果用非matlab语言写,可以先借助于matlab的符号计算功能,以及其中的符号计算命令

    simple,把计算结果算出来,然后再再其他高级语言中实现。

           (6) 按式(22)进行无雾图像的恢复。

    mfc头文件:

    [cpp] view plain copy
    1. #pragma once  
    2. #include "afxwin.h"  
    3. #include <cv.h>  
    4. #include "cxcore.h"    
    5. #include "math.h"   
    6. #include <highgui.h>  
    7. #include<vector>  
    8. #include <iostream>    
    9. #include "opencv2/core/core.hpp"      
    10. #include "opencv2/highgui/highgui.hpp"      
    11. #include "opencv2/imgproc/imgproc.hpp"      
    12.   
    13.   
    14. using namespace std;  
    15. using namespace cv;  
    16.   
    17. class Ctry :  
    18.     public CCmdTarget  
    19. {  
    20. public:  
    21.     Ctry();  
    22.     virtual ~Ctry();  
    23.     DECLARE_MESSAGE_MAP()  
    24.     afx_msg void OnTryTyr1();  
    25.     afx_msg void OnTryPath();  
    26.   
    27. public:  
    28.     Mat getimage(Mat &a);  
    29.     Mat guidedFilter2(cv::Mat I, cv::Mat p, int r, double eps);  
    30.     IplImage* getDarkChannel(IplImage* &src);  
    31.     IplImage* getMinIcy(IplImage* dark,int w);  
    32.     double getA(IplImage* dark, IplImage*hazeImage);  
    33.     IplImage* getTransmission(IplImage* Icy, double Ac);  
    34.   
    35.     IplImage* getDehazedImage(IplImage* hazeImage, IplImage* guidedt,double Ac);  
    36.   
    37. public:  
    38.   
    39.   
    40.   
    41.   
    42. };  

    mfc源文件:

    [cpp] view plain copy
    1. #include "stdafx.h"  
    2. #include "Ctry.h"  
    3. #include "Resource.h"  
    4. #include<cv.h>  
    5.   
    6. #define PI 3.14159  
    7.   
    8. Ctry::Ctry()  
    9. {  
    10. }  
    11.   
    12. Ctry::~Ctry()  
    13. {  
    14. }  
    15.   
    16. BEGIN_MESSAGE_MAP(Ctry, CCmdTarget)  
    17.     ON_COMMAND(ID_TRY_TYR1, &Ctry::OnTryTyr1)  
    18.     ON_COMMAND(ID_TRY_PATH, &Ctry::OnTryPath)  
    19. END_MESSAGE_MAP()  
    20.   
    21.   
    22. void Ctry::OnTryTyr1()  
    23. {  
    24.     // TODO:  在此添加命令处理程序代码  
    25.   
    26.       
    27. }  
    28.   
    29. void Ctry::OnTryPath()  
    30. {  
    31.     // TODO:  在此添加命令处理程序代码      
    32.     IplImage* img = cvLoadImage("C:\\Users\\徐图之\\Desktop\\1.jpg");  
    33.   
    34.   
    35.     IplImage* g = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);  
    36.     g=getDarkChannel(img);  
    37.     double A = getA(g, img);   //大气光强A  
    38.   
    39.     IplImage* Icy = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);  
    40.     Icy = getMinIcy(g, 5);  
    41.   
    42.     //投射图t  
    43.     IplImage* t = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);  
    44.     t = getTransmission(Icy, A);  
    45.   
    46.     //获得guide image  
    47.     Mat mt = cvarrToMat(t, true);  
    48.     Mat image_src = cvarrToMat(img, true);  
    49.     Mat image_gray(image_src.size(), CV_8UC1);  
    50.     cvtColor(image_src, image_gray, CV_BGR2GRAY);  
    51.     Mat guide = getimage(image_gray);  
    52.     int r = 8;  
    53.     double eps = 0.04;  
    54.     Mat q = guidedFilter2(guide, mt, r, eps);  
    55.     IplImage* guidedt = cvCloneImage(&(IplImage)q);  
    56.   
    57.   
    58.     IplImage* dehazedImage = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);  
    59.     dehazedImage = getDehazedImage(img, guidedt, A);  
    60.   
    61.   
    62.     cvSaveImage("C:\\Users\\徐图之\\Desktop\\dark .jpg", g);  
    63.     cvSaveImage("C:\\Users\\徐图之\\Desktop\\guidedt .jpg", guidedt);  
    64.     cvSaveImage("C:\\Users\\徐图之\\Desktop\\t.jpg", t);  
    65.     cvSaveImage("C:\\Users\\徐图之\\Desktop\\dehazedImage84.jpg", dehazedImage);  
    66.       
    67. }  
    68.   
    69.   
    70. //convert image depth to CV_64F    
    71. Mat  Ctry::getimage(Mat &a)  
    72. {  
    73.     int hei = a.rows;  
    74.     int wid = a.cols;  
    75.     Mat I(hei, wid, CV_64FC1);  
    76.     //convert image depth to CV_64F    
    77.     a.convertTo(I, CV_64FC1, 1.0 / 255.0);  
    78.     return I;  
    79. }  
    80.   
    81.   
    82.   
    83. Mat  Ctry::guidedFilter2(cv::Mat I, cv::Mat p, int r, double eps)  
    84. {  
    85.     /* 
    86.     % GUIDEDFILTER   O(1) time implementation of guided filter. 
    87.     % 
    88.     %   - guidance image: I (should be a gray-scale/single channel image) 
    89.     %   - filtering input image: p (should be a gray-scale/single channel image) 
    90.     %   - local window radius: r 
    91.     %   - regularization parameter: eps 
    92.     */  
    93.   
    94.     cv::Mat _I;  
    95.     I.convertTo(_I, CV_64FC1);  
    96.     I = _I;  
    97.   
    98.     cv::Mat _p;  
    99.     p.convertTo(_p, CV_64FC1);  
    100.     p = _p;  
    101.   
    102.     //[hei, wid] = size(I);    
    103.     int hei = I.rows;  
    104.     int wid = I.cols;  
    105.   
    106.     //N = boxfilter(ones(hei, wid), r); % the size of each local patch; N=(2r+1)^2 except for boundary pixels.    
    107.     cv::Mat N;  
    108.     cv::boxFilter(cv::Mat::ones(hei, wid, I.type()), N, CV_64FC1, cv::Size(r, r));  
    109.   
    110.     //mean_I = boxfilter(I, r) ./ N;    
    111.     cv::Mat mean_I;  
    112.     cv::boxFilter(I, mean_I, CV_64FC1, cv::Size(r, r));  
    113.   
    114.     //mean_p = boxfilter(p, r) ./ N;    
    115.     cv::Mat mean_p;  
    116.     cv::boxFilter(p, mean_p, CV_64FC1, cv::Size(r, r));  
    117.   
    118.     //mean_Ip = boxfilter(I.*p, r) ./ N;    
    119.     cv::Mat mean_Ip;  
    120.     cv::boxFilter(I.mul(p), mean_Ip, CV_64FC1, cv::Size(r, r));  
    121.   
    122.     //cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch.    
    123.     cv::Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);  
    124.   
    125.     //mean_II = boxfilter(I.*I, r) ./ N;    
    126.     cv::Mat mean_II;  
    127.     cv::boxFilter(I.mul(I), mean_II, CV_64FC1, cv::Size(r, r));  
    128.   
    129.     //var_I = mean_II - mean_I .* mean_I;    
    130.     cv::Mat var_I = mean_II - mean_I.mul(mean_I);  
    131.   
    132.     //a = cov_Ip ./ (var_I + eps); % Eqn. (5) in the paper;       
    133.     cv::Mat a = cov_Ip / (var_I + eps);  
    134.   
    135.     //b = mean_p - a .* mean_I; % Eqn. (6) in the paper;    
    136.     cv::Mat b = mean_p - a.mul(mean_I);  
    137.   
    138.     //mean_a = boxfilter(a, r) ./ N;    
    139.     cv::Mat mean_a;  
    140.     cv::boxFilter(a, mean_a, CV_64FC1, cv::Size(r, r));  
    141.     mean_a = mean_a / N;  
    142.   
    143.     //mean_b = boxfilter(b, r) ./ N;    
    144.     cv::Mat mean_b;  
    145.     cv::boxFilter(b, mean_b, CV_64FC1, cv::Size(r, r));  
    146.     mean_b = mean_b / N;  
    147.   
    148.     //q = mean_a .* I + mean_b; % Eqn. (8) in the paper;    
    149.     cv::Mat q = mean_a.mul(I) + mean_b;  
    150.   
    151.     return q;  
    152. }  
    153.   
    154. IplImage* Ctry::getDarkChannel(IplImage* &src)  
    155. {  
    156.     IplImage* temp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);  
    157.     CvScalar pixel;  
    158.     double  px;  
    159.     for (int i = 0; i < src->height; i++)  
    160.     {  
    161.         for (int j = 0; j < src->width; j++)  
    162.         {  
    163.             pixel = cvGet2D(src, i, j);  
    164.             if (pixel.val[0]<pixel.val[1])  
    165.             {  
    166.                 px = pixel.val[0];  
    167.             }  
    168.             else  
    169.             {  
    170.                 px = pixel.val[1];  
    171.             }  
    172.   
    173.             if (px >pixel.val[2])  
    174.             {  
    175.                 px = pixel.val[2];  
    176.             }  
    177.             cvSetReal2D(temp, i, j, px);  
    178.         }  
    179.     }  
    180.   
    181.     return  temp;  
    182. }  
    183.   
    184. double Ctry::getA(IplImage* dark, IplImage* hazeImage)  
    185. {    
    186.     double sum=0;   //像素点符合条件A的和  
    187.     int pointNum = 0;   //满足要求的像素点数  
    188.     double A;        //大气光强A  
    189.     double pix;    //暗通道图中照亮度的前0.1%范围的像素值  
    190.     CvScalar pixel;   //按图中符合A的点,在雾图中对应的像素  
    191.   
    192.     float stretch_p[256], stretch_p1[256], stretch_num[256];  
    193.     //清空三个数组,初始化填充数组元素为0      
    194.     memset(stretch_p, 0, sizeof(stretch_p));  
    195.     memset(stretch_p1, 0, sizeof(stretch_p1));  
    196.     memset(stretch_num, 0, sizeof(stretch_num));  
    197.   
    198.     int nHeight = dark->height;  
    199.     int nWidth = dark->width;  
    200.     int i, j;  
    201.     for (i = 0; i<nHeight; i++)  
    202.     {  
    203.         for (j = 0; j<nWidth; j++)  
    204.         {  
    205.             double  pixel0 = cvGetReal2D(dark, i, j);  
    206.             int   pixel = (int)pixel0;  
    207.             stretch_num[pixel]++;  
    208.         }  
    209.     }  
    210.     //统计各个灰度级出现的概率    
    211.     for (i = 0; i<256; i++)  
    212.     {  
    213.         stretch_p[i] = stretch_num[i] / (nHeight*nWidth);  
    214.     }  
    215.   
    216.     //统计各个灰度级的概率,从暗通道图中按照亮度的大小取前0.1%的像素,pix为分界点  
    217.     for (i = 0; i<256; i++)  
    218.     {  
    219.         for (j = 0; j <= i; j++)  
    220.         {  
    221.             stretch_p1[i] += stretch_p[j];  
    222.             if (stretch_p1[i]>0.999)  
    223.             {  
    224.                 pix = (double)i;  
    225.                 i = 256;  
    226.                 break;  
    227.             }  
    228.   
    229.         }  
    230.     }  
    231.   
    232.     for (i = 0; i< hazeImage->height; i++)  
    233.     {  
    234.         for (j = 0; j < hazeImage->width; j++)  
    235.         {  
    236.             double temp = cvGetReal2D(dark, i, j);  
    237.             if (temp > pix)  
    238.             {  
    239.                 pixel = cvGet2D(hazeImage, i, j);  
    240.                 pointNum++;  
    241.                 sum += pixel.val[0];  
    242.                 sum += pixel.val[1];  
    243.                 sum += pixel.val[2];  
    244.   
    245.             }  
    246.         }  
    247.     }  
    248.     A = sum / (3 * pointNum);  
    249.     if (A > 220.0)  
    250.     {  
    251.         A = 220.0;  
    252.     }  
    253.     return A;  
    254. }  
    255.   
    256. //获取暗通道图像窗口中的最小值,用于后续计算透射率t,参数w为窗口的大小  
    257. IplImage* Ctry::getMinIcy(IplImage* dark, int w)  
    258. {  
    259.     IplImage* Icy = cvCreateImage(cvGetSize(dark), IPL_DEPTH_8U, 1);  
    260.     int hei = dark->height;  
    261.     int wid = dark->width;  
    262.     int hw = hei / w;  
    263.     int ww = wid / w;  
    264.     for (int i = w; i < (hw - 1)*w; i += w)  
    265.     {  
    266.         for (int j = w; j < (ww - 1)*w; j += w)  
    267.         {  
    268.             double p = cvGetReal2D(dark, i-1, j-1);  //得到窗口最右下角的一个像素点  
    269.             //得到窗口最小的像素值  
    270.             for (int ii = i - w; ii < i; ii++)  
    271.             {  
    272.                 for (int jj = j - w; jj < j; jj++)  
    273.                 {  
    274.                     double newp = cvGetReal2D(dark, ii, jj);  
    275.                     if (newp < p)  
    276.                     {  
    277.                         p = newp;  
    278.                     }  
    279.                 }  
    280.             }  
    281.             //设置Icy的值  
    282.             for (int ii = i - w; ii < i; ii++)  
    283.             {  
    284.                 for (int jj = j - w; jj < j; jj++)  
    285.                 {  
    286.                     cvSetReal2D(Icy, ii, jj, p);  
    287.                 }  
    288.             }  
    289.   
    290.         }  
    291.     }  
    292.   
    293.     //处理最右边一列  不包含最下一个子块  
    294.     for (int i = w; i < (hw - 1)*w; i += w)  
    295.     {  
    296.         double p = cvGetReal2D(dark, i-1, wid-1);  //得到窗口最右下角的一个像素点  
    297.         for (int ii = i - w; ii < i; ii++)  
    298.         {  
    299.   
    300.             for (int j = (ww - 1)*w; j < wid; j++)  
    301.             {  
    302.                 //得到窗口最小的像素值  
    303.                 double newp = cvGetReal2D(dark, ii, j);  
    304.                 if (newp < p)  
    305.                 {  
    306.                     p = newp;  
    307.                 }  
    308.             }  
    309.         }     
    310.   
    311.         //设置Icy的值  
    312.         for (int ii = i - w; ii < i; ii++)  
    313.         {  
    314.   
    315.             for (int j = (ww - 1)*w; j < wid; j++)  
    316.             {  
    317.                 cvSetReal2D(Icy, ii, j, p);  
    318.             }  
    319.         }  
    320.     }  
    321.   
    322.   
    323.     //处理最下一行 不包含最后一个子块  
    324.     for (int j = w; j < (ww - 1)*w; j += w)  
    325.     {  
    326.         double p = cvGetReal2D(dark, hei-1, j);  //得到窗口最右下角的一个像素点  
    327.         for (int i = (hw - 1)*w; i < hei; i++)  
    328.         {  
    329.             for (int jj = j - w; jj < j; jj++)  
    330.             {  
    331.                 //得到窗口最小的像素值  
    332.                 double newp = cvGetReal2D(dark, i, jj);  
    333.                 if (newp < p)  
    334.                 {  
    335.                     p = newp;  
    336.                 }  
    337.             }  
    338.         }  
    339.   
    340.         //设置Icy的值  
    341.         for (int i = (hw - 1)*w; i < hei; i++)  
    342.         {  
    343.   
    344.             for (int jj = j - w; jj < j; jj++)  
    345.             {  
    346.                 cvSetReal2D(Icy, i, jj, p);  
    347.             }  
    348.         }  
    349.   
    350.     }  
    351.   
    352.     //处理最右下角的一个子块  
    353.     double p = cvGetReal2D(dark, hei-1, wid-1);  //得到窗口最右下角的一个像素点  
    354.     for (int i = (hw - 1)*w; i < hei; i++)  
    355.     {  
    356.         for (int j = (ww - 1)*w; j < wid; j++)  
    357.         {  
    358.             //得到窗口最小的像素值  
    359.             double newp = cvGetReal2D(dark, i, j);  
    360.             if (newp < p)  
    361.             {  
    362.                 p = newp;  
    363.             }  
    364.   
    365.         }  
    366.     }  
    367.     for (int i = (hw - 1)*w; i < hei; i++)  
    368.     {  
    369.         for (int j = (ww - 1)*w; j < wid; j++)  
    370.         {  
    371.             cvSetReal2D(Icy, i, j, p);  
    372.   
    373.         }  
    374.     }  
    375.   
    376.     return Icy;  
    377. }  
    378.   
    379. IplImage* Ctry::getTransmission(IplImage* Icy, double Ac)  
    380. {  
    381.     IplImage* t = cvCreateImage(cvGetSize(Icy), IPL_DEPTH_8U, 1);  
    382.     for (int i = 0; i < t->height; i++)  
    383.     {  
    384.         for (int j = 0; j < t->width; j++)  
    385.         {  
    386.             double temp = cvGetReal2D(Icy, i, j);  
    387.             double tempt = 1 - 0.95*temp / Ac;  
    388.             cvSetReal2D(t, i, j, tempt*255);  
    389.         }  
    390.     }  
    391.   
    392.     return t;  
    393.   
    394. }  
    395.   
    396. IplImage* Ctry::getDehazedImage(IplImage* hazeImage, IplImage* guidedt, double Ac)  
    397. {  
    398.     IplImage* dehazedImage = cvCreateImage(cvGetSize(hazeImage), IPL_DEPTH_8U, 3);  
    399.     IplImage* r = cvCreateImage(cvGetSize(hazeImage), IPL_DEPTH_8U, 1);  
    400.     IplImage* g = cvCreateImage(cvGetSize(hazeImage), IPL_DEPTH_8U, 1);  
    401.     IplImage* b = cvCreateImage(cvGetSize(hazeImage), IPL_DEPTH_8U, 1);  
    402.   
    403.     cvSplit(hazeImage, b, g, r, NULL);  
    404.       
    405.     IplImage* dehaze_r = cvCreateImage(cvGetSize(hazeImage), IPL_DEPTH_8U, 1);  
    406.     IplImage* dehaze_g = cvCreateImage(cvGetSize(hazeImage), IPL_DEPTH_8U, 1);  
    407.     IplImage* dehaze_b = cvCreateImage(cvGetSize(hazeImage), IPL_DEPTH_8U, 1);  
    408.   
    409.     for (int i = 0; i < r->height; i++)  
    410.     {  
    411.         for (int j = 0; j < r->width; j++)  
    412.         {  
    413.             double tempt = cvGetReal2D(guidedt, i, j);  
    414.             if (tempt/255 < 0.1)  
    415.             {  
    416.                 tempt = 25.5;  
    417.             }  
    418.   
    419.             double I_r=cvGetReal2D(r, i, j);  
    420.             double de_r = 255 * (I_r - Ac) / tempt + Ac;  
    421.             cvSetReal2D(dehaze_r, i, j, de_r);  
    422.   
    423.             double I_g = cvGetReal2D(g, i, j);  
    424.             double de_g = 255 * (I_g - Ac) / tempt + Ac;  
    425.             cvSetReal2D(dehaze_g, i, j, de_g);  
    426.   
    427.             double I_b = cvGetReal2D(b, i, j);  
    428.             double de_b = 255 * (I_b - Ac) / tempt + Ac;  
    429.             cvSetReal2D(dehaze_b, i, j, de_b);  
    430.   
    431.         }  
    432.     }  
    433.   
    434.     cvMerge(dehaze_b, dehaze_g, dehaze_r, 0, dehazedImage);  
    435.   
    436.     return dehazedImage;  
    437.   
    438. }  

        代码调试后,得到的图片有点色差,边缘有2条黑色的线,我也懒得修改,欢迎各位批评指正。  

          在原文中,有这样一段话:

      Since the scene radiance is usually not as bright as the atmospheric light, the image after haze removal looks dim. So we increase the exposure of J(x) for
    display.

         意思就是说直接去雾后的图像会比原始的暗,因此在处理完后需要进行一定的曝光增强,但作者没有说明其是如何增强的, 因此,这里的图和他论文的效果

    有所不同时正常的。一般在去雾处理后再用自动色剂之类的算法增强下会获得比较满意的结果。

          去雾算法目前也有着众多其他的方式,不过我所接触的,很多都是以这个为基础,因此,先弄会这个为研究其他的去雾算法能奠定坚实的基础。

        总结:我对这种去雾算法的效果还是很满意的, 效果和速度都还比较合适。


    展开全文
  • 基于导向滤波的暗通道先验去雾算法(Python语言,可直接运行)1 编译环境2 原理介绍2.1 暗通道先验2.1.1 暗通道先验理论与去雾模型2.1.2 处理步骤2.2 导向滤波求t(x)3 代码4 处理结果4.1 第一组结果及其比较,暗通道...

    1 编译环境

    编程语言:Python
    IDE:PyCharm 2017

    2 原理介绍

    2.1 暗通道先验

    2.1.1 暗通道先验理论与去雾模型

    暗通道先验的去雾算法是由何凯明在2009年的CVPR会议上的最佳论文,译文见译文_Single Image Haze Removal Using Dark Channel Prior,何恺明的暗通道先验(dark channel prior)去雾算法是CV界去雾领域很有名的算法,关于该算法的论文"Single Image Haze Removal Using Dark Channel Prior"一举获得2009年CVPR最佳论文。作者统计了大量的无雾图像,发现一条规律:每一幅图像的RGB三个颜色通道中,总有一个通道的灰度值很低,几乎趋向于0。基于这个几乎可以视作是定理的先验知识,作者提出暗通道先验的去雾算法。
    作者首先介绍去雾模型如下:
    在这里插入图片描述
    式中I(x)为原图,待去雾图像;J(x)为要恢复的无雾图像;A是大气光成分,t(x)为图像的透光率

    2.1.2 处理步骤

    	对成像模型归一化,两边同时除以每个通道的大气光值,得到如下:
    

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    准,因此图像恢复的最终公式为:
    在这里插入图片描述

    2.2 导向滤波求t(x)

    在原文中,作者提出的为Soft Matting方法求解透射率图t(x),但该方法的致命失误在于计算效率低,速度慢。因此,在2011年,作者又发表论文提出利用导向滤波的方式来求透射率图t(x)。导向滤波步骤如下图:
    在这里插入图片描述

    3 代码

    代码如下:

    import cv2 as cv
    import numpy as np
    
    def zmMinFilterGray(src, r=5):
      '''最小值滤波,r是滤波器半径'''
      return cv.erode(src, np.ones((2 * r + 1, 2 * r + 1)))
    
    def darkchannel(Image):             #计算每个通道中的最小值,输入Image图像,输出最小值img_min
    rows,cols,channels=Image.shape
    img=np.array(Image)
    for i in range(0,rows-1):
      for j in range(0,cols-1):
        min_rgb = Image[i][j][0]
        if min_rgb  > Image[i][j][1]:
          min_rgb = Image[i][j][1]
        elif min_rgb  > Image[i][j][2]:
          min_rgb = Image[i][j][2]
        for c in range(channels):
          img[i][j][c] = min_rgb
    return img
    
    def min_filter(Image,r):                # 最小值滤波,输入最小值图像,在2*r+1的矩形窗口内寻找最小值
    rows, cols, channels = Image.shape    # 输出为暗通道图像
    img = np.array(Image)
    for i in range(0, rows):
      for j in range(0, cols):
        for c in range(0, channels):
          if i == 0 or j == 0 or i == rows - 1 or j == cols - 1:
            img[i][j][c] = Image[i][j][c]
          elif j == 0:
            img[i][j][c] = Image[i][j][c]
          else:
            min = 255
            for m in range(i - r, i + r):         # 寻找像素点(i,j)为中心的5*5窗口内的每个通道的最小值
              for n in range(j - r, j + r):
                if min > Image[m][n][c]:
                  min = Image[m][n][c]
            img[i][j][c] = min
    return img
    
    def guided_filter(Image,p,r,eps):     # 基于导向滤波进行暗通道图像的变换
    #Image归一化之后的原图,p最小值图像,r导向滤波搜索范围,eps为惩罚项,输出导向滤波后的图像
    # q = a * I + b
    mean_I = cv.blur(Image, (r, r))  # I的均值平滑
    mean_p = cv.blur(p, (r, r))  # p的均值平滑
    mean_II = cv.blur(Image*Image, (r, r))  # I*I的均值平滑
    mean_Ip = cv.blur(Image*p, (r, r))  # I*p的均值平滑
    var_I = mean_II - mean_I * mean_I  # 方差
    cov_Ip = mean_Ip - mean_I * mean_p  # 协方差
    a = cov_Ip / (var_I +eps)
    b = mean_p - a *mean_I
    mean_a = cv.blur(a, (r, r))  # 对a、b进行均值平滑
    mean_b = cv.blur(b, (r, r))
    q = mean_a*Image + mean_b
    return q
    
    def select_bright(Image,img_origin,w,t0,V):          #计算大气光A和折射图t
    #输入:Image最小值图像,img_origion原图,w是t之前的修正参数,t0阈值,V导向滤波结果
    rows,cols,channels=Image.shape
    size=rows*cols
    order = [0 for i in range(size)]
    m = 0
    for t in range(0,rows):
      for j in range(0,cols):
        order[m] = Image[t][j][0]
        m = m+1
    order.sort(reverse=True)
    index =int(size * 0.001) #从暗通道中选取亮度最大的前0.1%
    mid = order[index]
    A = 0
    img_hsv = cv.cvtColor(img_origin,cv.COLOR_RGB2HLS)
    for i in range(0,rows):
      for j in range(0,cols):
        if Image[i][j][0]>mid and img_hsv[i][j][1]>A:
          A = img_hsv[i][j][1]
    V = V * w
    t = 1 - V/A
    t = np.maximum(t,t0)
    return t,A
    
    def repair(Image,t,A):
    rows, cols, channels = Image.shape
    J = np.zeros(Image.shape)
    for i in range(0,rows):
      for j in range(0,cols):
        for c in range(0,channels):
          t[i][j][c] = t[i][j][c]-0.25 # 不知道为什么这里减掉0.25效果才比较好
          J[i][j][c] = (Image[i][j][c]-A/255.0)/t[i][j][c]+A/255.0
    return J
    img = cv.imread('deHaze\\haze.bmp')
    img_arr=np.array(img/255.0)                     #归一化
    img_min=darkchannel(img_arr)         #计算每个通道的最小值
    img_dark=min_filter(img_min,2)       #计算暗通道图像
    img_guided=guided_filter(img_arr,img_min,r=75,eps=0.001)
    t,A=select_bright(img_min,img,w=0.95,t0=0.1,V=img_guided)
    dehaze=repair(img_arr,t,A)
    cv.imshow('Origin',img)
    cv.imshow('darkchannel',img_dark)
    cv.imshow('dehaze',dehaze)
    cv.waitKey()
    cv.destroyAllWindows()

    4 处理结果

    4.1 第一组结果及其比较,暗通道图在这里插入图片描述

    暗通道图像
    在这里插入图片描述

    4.2 第二组结果及其比较,暗通道图

    在这里插入图片描述
    暗通道图
    在这里插入图片描述

    4.3 原图(自取)

    在这里插入图片描述
    在这里插入图片描述

    5 需要注意的是

    从结果来看,去雾效果不是特别好,需要调整代码中的参数不断调试,以达到最优的去雾效果。

    展开全文
  • 首先,基于暗通道原理对原始图像进行映射处理,从而得到大气光成分与透射率的估计值,并利用多维导向滤波方法对大气透射率估计值进行优化处理;然后,根据图像降质过程的逆过程,求解雾霾图像清晰化处理初始结果;最后,利用...
  • 经典去雾算法--暗通道先验去雾(DCP)

    千次阅读 2020-04-04 14:03:54
    基于暗通道先验的单幅图像去雾算法来自于何凯明博士2009年的CVPR论文:《Single Image Haze Removal Using Dark Channel Prior》,2009年的CVPR只有一篇文章被选为那年的最佳论文。这是CVPR创立25年以来首次由中国人...
  • 暗通道先验的去雾算法实现

    千次阅读 2015-11-01 18:37:00
    目前比较公认效果较好的去雾方法的编程实现,基本原理是参考何凯明的一篇会议论文,网上已经有比较成熟的代码了。这里也就是仿写一下,这里只写到求透射率的部分,导向滤波的部分写出来有些问题就没有贴出来,机子出...
  • 这篇文章简单介绍了这两种方法, 更详细的原理可以参阅《语音增强--理论与实践》[1],里面各有一章详细分析了这两种模型。假设麦克风采集到的带噪语音序列为 ,并且噪声都是加性噪声。则带噪语音序列为无噪语...
  • 何凯明先生09年CVPR会议最佳论文,Single Image Haze Removal Using Dark Channel Prior,中英文都有,并且有何恺明在CVPR会议上演讲时的ppt——基于暗通道先验的单幅图像去雾技术,并且有何凯明公开的源码guided-...
  • OpenCV—Python 暗通道图像去雾算法

    千次阅读 多人点赞 2019-07-08 14:49:04
    何恺明的暗通道先验(dark channel prior)去雾算法是CV界去雾领域很有名的算法,关于该算法的论文"Single Image Haze Removal Using Dark Channel Prior"一举获得2009年CVPR最佳论文。作者统计了大量的无雾图像,...
  • 基于暗通道先验的图像去雾原理3.算法结果4.参考文献5.Matlab代码 摘要:本文主要介绍,经典的基于暗通道的去雾算法。 1.雾天图像退化模型 在图像处理和计算机视觉领域经常使用的雾天图像退化模型,图像退化模型主要...
  • 为了提高雾天航空影像的视觉效果,提出了一种结合暗通道先验的Retinex除雾算法,以解决Reinex除雾中除雾不足和航空除雾过度增强的现象。 首先,通过Retinex理论将有雾的原始图像分解成有雾的入射光分量和有雾的反射...
  • 近几年来,去雾方法得到... Kaiming He提出了一种基于暗通道先验的方法,即在有雾图像的特定窗中至少有一个颜色分量的值是零,该算法利用最小值滤波估算出介质传播函数,然后利用软抠图原理对估算的介质传播函数进...
  • He 提出暗通道去雾方法进行了详细的描述,该方法以大气散射模型为基础,利用暗通道先验原理求出全球大气光成分A和透射率t。先使用了软抠图对透射率图进行优化,但是运算时间过长。后来使用引导滤波精细化透射率图,...
  • 图像去雾算法的原理、实现、效果

    万次阅读 多人点赞 2018-10-16 16:26:23
    说明:何凯明博士的论文中统计了5000多副图像的特征,证明了暗通道先验理论的普遍性,因此我们可以粗略的认为是一条定理。 先看什么是暗通道先验: 在绝大多数图像局部区域里,有一些像素总会有至少一个颜色通道...
  • 通过分析暗原色先验原理,得出了暗通道图像和雾的透射分布率以及雾的浓度系数的关系,提出了一种 结合峰值信噪比和暗原色优先法则的去雾方法。由实验结果分析,该方法能够更清晰的表现去雾后图 像的细节,并且一定...
  • 水下图像去雾算法C++实现

    千次阅读 2017-08-15 13:51:32
    图像去雾之何凯明暗通道先验去雾算法原理及c++代码实现 何凯明博士,2007年清华大学毕业,2011年香港中文大学博士毕业,可谓是功力深厚,感叹于国内一些所谓博士的水平,何这样的博士才可以真正叫做 Doctor。 ...
  • 去雾算法总结

    千次阅读 2018-06-14 22:46:32
    之前搞个去雾算法,原理几乎全部忘记,这里再回忆一下参考链接是:https://blog.csdn.net/songhhll/article/details/12612681论文是 Single Image Haze Removal Using Dark Channel Prior论文的核心是提出了暗通道先验:...
  • DIA实验——图像去雾

    2020-04-02 00:44:15
    天气对图像的质量有很大的影响,请利用图像分析的相关知识,实现基于暗通道先验的图像去雾算法,对有雾霾的图像进行增强。 原理说明 原理里式子推导有点多,详细步骤也可以参考这位大大的博客 以及论文n He K, Sun J...
  • share

    2020-11-19 10:59:37
    暗通道先验去雾 VIFB 可见光与红外图像融合benchmark VIFB:visible and infrared image fusion benchmark 红外热成像原理及应用 红外摄像头和红外热成像的原理有什么区别? 红外摄像机与热像仪的成像原理不一样。...
  • 水下图像增强类的论文似乎没看到过从原理上、或者说某一个数学模型、抑或是某种先验知识出发而提出的算法,都是一种没有什么特强的理论支持,而...因此,也就没有类似于去雾算法界暗通道先验那样不可逾越的黄金文章了。
  • 图像处理之天空区域识别

    千次阅读 2020-02-23 22:07:46
    近几年来,去雾方法得到... Kaiming He提出了一种基于暗通道先验的方法,即在有雾图像的特定窗中至少有一个颜色分量的值是零,该算法利用最小值滤波估算出介质传播函数,然后利用软抠图原理对估算的介质传播函数进...
  • 前些日子有一个项目要求有去雾效果,调研了一下,发现图像增强算法其实多多少少都有一些去雾的效果,调研了三种算法分别是直方图均衡,RETINEX和暗通道先验三种,选择直方图均衡这种简单又效果不错的算法出来讲讲。...

空空如也

空空如也

1 2
收藏数 28
精华内容 11
关键字:

暗通道先验原理