基于暗通道优先的单幅图像去雾算法(Matlab/C++)

算法原理:

            参见论文:Single Image Haze Removal Using Dark Channel Prior  [1]

       ① 暗通道定义

     何恺明 通过对大量在户外拍摄的自然景物图片进行统计分析得出一个结论:在绝大多数非天空的局部区域里,某一些像素总会(至少一个颜色通道)具有很低的值。换言之,该区域光强度的最小值是个很小的数(趋于0)。

基于上述结论,我们定义暗通道,用公式描述,对于一幅图像J有如下式子:

 也就是说以像素点x为中心,分别取三个通道内窗口Ω内的最小值,然后再取三个通道的最小值作为像素点x的暗通道的值,如下图所示:

   

 Jc代表J的某一个颜色通道,而Ω(x)是以x为中心的一块方形区域。我们观察得出,除了天空方位,Jdark的强度总是很低并且趋近于0。如果J是户外的无雾图像,我们把Jdark称为J的暗原色,并且把以上观察得出的经验性规律称为暗原色先验。

②大气物理模型

要想从物理模型角度对有雾图像进行清晰化处理,就要了解有雾图像的物理成因,那么就要了解雾天的大气散射模型。

大气散射物理模型包含两部分,第一部分称为直接衰减项(Direct Attenuation)也称直接传播,第二部分称为大气光照(Airlight)

用公式表示如下:

   I是观测到的有雾图像,J是景物反射光强度(也就是清晰的无雾图像),A是全局大气光照强度,t用来描述光线通过介质透射到成像设备过程中没有被散射的部分,去雾的目标就是从I中复原J。那么也就是要通过I求A和t。


    方程右边的第一项J(x)t(x) 叫做直接衰减项,第二项A(1-t(x))则是大气光照。直接衰减项描述的是景物光线在透射媒介中经衰减后的部分,而大气光则是由前方散射引起的,会导致景物颜色的偏移。因为大气层可看成各向同性的,透射率t可表示为:

β为大气的散射系数,该式表明景物光线是随着景物深度d按指数衰减的。

③求解透射率t

在论文[1]中,作者给出了推导过程,这里就不再重复,其最后得到透射率t的公式如下:

Ic为输入的有雾图像,对其除以全局大气光照Ac后在利用暗通道定义公式进行求解暗通道。w(0<w<1)是雾的保留系数通常取0.95。

这里需要值得注意的是,求得的t是粗透射率图,并不能直接带入大气模型公式求解,所以需要进行细化后再处理。细化过程见⑤,Ac为全局大气光照,其求法见④。

④求解全局大气光照Ac

论文[1]中作者给出求解全局大气光照的过程如下:

1.首先对输入的有雾图像I求解其暗通道图像Jdark

2.选择暗通道Jdark内图像总像素点个数(N_imagesize)千分之一(N=N_imagesize/1000)个最亮的像素点,并记录这些像素点(x,y)坐标。

3.再根据这些点的坐标分别在原图像I的三个通道(r,g,b)内找到这些像素点并加和得到(sum_r,sum_g,sum_b).

4.Ac=[Ar,Ag,Ab]. 其中Ar=sum_r/N;   Ag=sum_g/N;   Ab=sum_b/N.

⑤细化透射率t

    作者在论文[1]中使用了软抠图(soft matting)的方法,详见论文如下:

A Closed-Form Solution to Natural Image Matting[2], 作者:Anat Levin

使用软抠图法对得到的粗透射率t~进行细化。由于这个方法时间和内存花费比较大,后来作者又使用指导性滤波器进行细化粗透射图。效果上指导性滤波要稍差于软抠图法,但在时间和内存花费上具有明显优势,因此这里我们使用指导性滤波器进行细化粗透射率t~。(注:Matlab代码中也附带软抠图法细化透射率的代码。内容见文件包)

关与指导性滤波的详细内容见论文:Guided Image Filtering [3] 作者:何恺明 

⑥求解最后清晰图像

现在,我们得到了A和t,那么带入大气模型公式:

这里,t0参数用来限定透射率t的下限值,其作用也就是在输入图像的浓雾区域保留一定的雾。

附录:

     

ReadMe.txt:

感谢论文Single Image Haze Removal Using Dark Channel Prior作者何凯明。
基于暗通道优先去雾算法的Matlab /C++ 源码为免费开源。只供研究学习使用,如果引用请注明原开发者,及出处。
Matlab版中指导性滤波的源码为原作者何凯明提供。
开发者:赵常凯(不包括Matlab版中 指导性滤波的源码)
时间:2013.8.19

       Matlab 源代码  下载 5.69MB

       C++ 源代码     下载 1.68MB

       说明:C++ 是基于 OpenCV2.2 + Qt 4.8.5 编写的,如果不匹配需要搭建 Qt+OpenCV开发环境。 如果只想查看核心源码文件,请查看Dehazor.cpp文件。

 /*--------------------------------------------------------------------------------*\

    This program is free software; permission is hereby granted to use, copy, modify,
and distribute this source code, or portions thereof, for any purpose, without fee,
subject to the restriction that the copyright notice may not be removed
or altered from any source or altered source distribution.
The software is released on an as-is basis and without any warranties of any kind.
In particular, the software is not guaranteed to be fault-tolerant or free from
failure. The author disclaims all warranties with regard to this software, any use,
and any consequent failure, is purely the responsibility of the user. Copyright (C) 2013-2016 Changkai Zhao, www.cnblogs.com/changkaizhao
\*-------------------------------------------------------------------------------*/
#include "dehazor.h" cv::Mat Dehazor::process(const cv::Mat &image)
{
int dimr=image.rows;
int dimc=image.cols; cv::Mat rawtemp;
cv::Mat refinedImage_temp;
cv::Mat output_b_temp(image.rows,image.cols,CV_32F);
cv::Mat output_g_temp(image.rows,image.cols,CV_32F);
cv::Mat output_r_temp(image.rows,image.cols,CV_32F);
cv::Mat output_temp(dimr,dimc,image.type());
rawImage.create(image.rows,image.cols,CV_8U);
refinedImage_temp.create(image.rows,image.cols,CV_32F);
rawtemp.create(image.rows,image.cols,CV_8U); float sumb=;float sumg=;float sumr=;
float Air_b; float Air_g; float Air_r;
cv::Point2i pt; int dimone=floor(dimr*dimc*0.001);
cv::Mat quantile;
quantile=cv::Mat::zeros(,dimone,CV_8U); int dx=floor(windowsize/);
// cv::Mat imagetemp;
// imagetemp.create(image.rows,image.cols,CV_32FC3); for(int j=;j<dimr;j++){
for(int i=;i<dimc;i++){
int min;
image.at<cv::Vec3b>(j,i)[] >= image.at<cv::Vec3b>(j,i)[]?
min=image.at<cv::Vec3b>(j,i)[]:
min=image.at<cv::Vec3b>(j,i)[];
if(min>=image.at<cv::Vec3b>(j,i)[])
min=image.at<cv::Vec3b>(j,i)[];
rawImage.at<uchar>(j,i)=min;
}
} for(int j=;j<dimr;j++){
for(int i=;i<dimc;i++){
int min=; int jlow=j-dx;int jhigh=j+dx;
int ilow=i-dx;int ihigh=i+dx; if(ilow<=)
ilow=;
if(ihigh>=dimc)
ihigh=dimc-;
if(jlow<=)
jlow=;
if(jhigh>=dimr)
jhigh=dimr-; for(int m=jlow;m<=jhigh;m++){
for(int n=ilow;n<=ihigh;n++){
if(min>=rawImage.at<uchar>(m,n))
min=rawImage.at<uchar>(m,n);
}
}
rawtemp.at<uchar>(j,i)=min;
}
} for(int i=;i<dimone;i++){
cv::minMaxLoc(rawtemp,,,,&pt);
sumb+= image.at<cv::Vec3b>(pt.y,pt.x)[];
sumg+= image.at<cv::Vec3b>(pt.y,pt.x)[];
sumr+= image.at<cv::Vec3b>(pt.y,pt.x)[];
rawtemp.at<uchar>(pt.y,pt.x)=;
}
Air_b=sumb/dimone;
Air_g=sumg/dimone;
Air_r=sumr/dimone; cv::Mat layb; cv::Mat Im_b;
cv::Mat layg; cv::Mat Im_g;
cv::Mat layr; cv::Mat Im_r; // create vector of 3 images
std::vector<cv::Mat> planes;
// split 1 3-channel image into 3 1-channel images
cv::split(image,planes); layb=planes[];
layg=planes[];
layr=planes[];
Im_b=planes[];
Im_g=planes[];
Im_r=planes[]; layb.convertTo(layb, CV_32F);
layg.convertTo(layg, CV_32F);
layr.convertTo(layr, CV_32F); Im_b.convertTo(Im_b, CV_32F);
Im_g.convertTo(Im_g, CV_32F);
Im_r.convertTo(Im_r, CV_32F); for (int j=; j<dimr; j++) {
for (int i=; i<dimc; i++) {
// process each pixel ---------------------
layb.at<float>(j,i)=layb.at<float>(j,i)/Air_b; layg.at<float>(j,i)=layg.at<float>(j,i)/Air_g; layr.at<float>(j,i)=layr.at<float>(j,i)/Air_r;
// end of pixel processing ----------------
} // end of line
} rawtemp.convertTo(rawtemp,CV_32F); for(int j=;j<dimr;j++){
for(int i=;i<dimc;i++){
float min;
layb.at<float>(j,i) >= layg.at<float>(j,i)?
min=layg.at<float>(j,i):
min=layb.at<float>(j,i);
if(min>=layr.at<float>(j,i))
min=layr.at<float>(j,i);
rawtemp.at<float>(j,i)=min;
}
}
for(int j=;j<dimr;j++){
for(int i=;i<dimc;i++){
float min=; int jlow=j-dx;int jhigh=j+dx;
int ilow=i-dx;int ihigh=i+dx; if(ilow<=)
ilow=;
if(ihigh>=dimc)
ihigh=dimc-;
if(jlow<=)
jlow=;
if(jhigh>=dimr)
jhigh=dimr-; for(int m=jlow;m<=jhigh;m++){
for(int n=ilow;n<=ihigh;n++){
if(min>=rawtemp.at<float>(m,n))
min=rawtemp.at<float>(m,n);
}
}
rawImage.at<uchar>(j,i)=(-(float)fog_reservation_factor*min)*;
}
} refinedImage_temp=guildedfilter_color(image,rawImage,localwindowsize,eps); for(int j=;j<dimr;j++){
for(int i=;i<dimc;i++){
if(refinedImage_temp.at<float>(j,i)<0.1)
refinedImage_temp.at<float>(j,i)=0.1;
}
} cv::Mat onemat(dimr,dimc,CV_32F,cv::Scalar()); cv::Mat air_bmat(dimr,dimc,CV_32F);
cv::Mat air_gmat(dimr,dimc,CV_32F);
cv::Mat air_rmat(dimr,dimc,CV_32F); cv::addWeighted(onemat,Air_b,onemat,,,air_bmat);
cv::addWeighted(onemat,Air_g,onemat,,,air_gmat);
cv::addWeighted(onemat,Air_r,onemat,,,air_rmat); output_b_temp=Im_b-air_bmat;
output_g_temp=Im_g-air_gmat;
output_r_temp=Im_r-air_rmat; output_b_temp=output_b_temp.mul(/refinedImage_temp,)+air_bmat;
output_g_temp=output_g_temp.mul(/refinedImage_temp,)+air_gmat;
output_r_temp=output_r_temp.mul(/refinedImage_temp,)+air_rmat; output_b_temp.convertTo(output_b_temp,CV_8U);
output_g_temp.convertTo(output_g_temp,CV_8U);
output_r_temp.convertTo(output_r_temp,CV_8U); for(int j=;j<dimr;j++){
for(int i=;i<dimc;i++){
output_temp.at<cv::Vec3b>(j,i)[]=output_b_temp.at<uchar>(j,i);
output_temp.at<cv::Vec3b>(j,i)[]=output_g_temp.at<uchar>(j,i);
output_temp.at<cv::Vec3b>(j,i)[]=output_r_temp.at<uchar>(j,i);
}
} cv::Mat nom_255(dimr,dimc,CV_32F,cv::Scalar()); cv::Mat ref_temp(dimr,dimc,CV_32F);
ref_temp=refinedImage_temp;
ref_temp=ref_temp.mul(nom_255,);
ref_temp.convertTo(refinedImage,CV_8U); return output_temp;
}
cv::Mat Dehazor::boxfilter(cv::Mat &im, int r)
{
//im is a CV_32F type mat [0,1] (normalized)
//output is the same size to im; int hei=im.rows;
int wid=im.cols;
cv::Mat imDst;
cv::Mat imCum; imDst=cv::Mat::zeros(hei,wid,CV_32F);
imCum.create(hei,wid,CV_32F); //cumulative sum over Y axis
for(int i=;i<wid;i++){
for(int j=;j<hei;j++){
if(j==)
imCum.at<float>(j,i)=im.at<float>(j,i);
else
imCum.at<float>(j,i)=im.at<float>(j,i)+imCum.at<float>(j-,i);
}
} //difference over Y axis
for(int j=;j<=r;j++){
for(int i=;i<wid;i++){
imDst.at<float>(j,i)=imCum.at<float>(j+r,i);
}
}
for(int j=r+;j<=hei-r-;j++){
for(int i=;i<wid;i++){
imDst.at<float>(j,i)=imCum.at<float>(j+r,i)-imCum.at<float>(j-r-,i);
}
}
for(int j=hei-r;j<hei;j++){
for(int i=;i<wid;i++){
imDst.at<float>(j,i)=imCum.at<float>(hei-,i)-imCum.at<float>(j-r-,i);
}
} //cumulative sum over X axis
for(int j=;j<hei;j++){
for(int i=;i<wid;i++){
if(i==)
imCum.at<float>(j,i)=imDst.at<float>(j,i);
else
imCum.at<float>(j,i)=imDst.at<float>(j,i)+imCum.at<float>(j,i-);
}
}
//difference over X axis
for(int j=;j<hei;j++){
for(int i=;i<=r;i++){
imDst.at<float>(j,i)=imCum.at<float>(j,i+r);
}
}
for(int j=;j<hei;j++){
for(int i=r+;i<=wid-r-;i++){
imDst.at<float>(j,i)=imCum.at<float>(j,i+r)-imCum.at<float>(j,i-r-);
}
}
for(int j=;j<hei;j++){
for(int i=wid-r;i<wid;i++){
imDst.at<float>(j,i)=imCum.at<float>(j,wid-)-imCum.at<float>(j,i-r-);
}
} return imDst;
}
cv::Mat Dehazor::guildedfilter_color(const cv::Mat &Img, cv::Mat &p, int r, float &epsi)
{ int hei=p.rows;
int wid=p.cols; cv::Mat matOne(hei,wid,CV_32F,cv::Scalar());
cv::Mat N; N=boxfilter(matOne,r); cv::Mat mean_I_b(hei,wid,CV_32F);
cv::Mat mean_I_g(hei,wid,CV_32F);
cv::Mat mean_I_r(hei,wid,CV_32F);
cv::Mat mean_p(hei,wid,CV_32F); cv::Mat Ip_b(hei,wid,CV_32F);
cv::Mat Ip_g(hei,wid,CV_32F);
cv::Mat Ip_r(hei,wid,CV_32F);
cv::Mat mean_Ip_b(hei,wid,CV_32F);
cv::Mat mean_Ip_g(hei,wid,CV_32F);
cv::Mat mean_Ip_r(hei,wid,CV_32F);
cv::Mat cov_Ip_b(hei,wid,CV_32F);
cv::Mat cov_Ip_g(hei,wid,CV_32F);
cv::Mat cov_Ip_r(hei,wid,CV_32F); cv::Mat II_bb(hei,wid,CV_32F);
cv::Mat II_gg(hei,wid,CV_32F);
cv::Mat II_rr(hei,wid,CV_32F);
cv::Mat II_bg(hei,wid,CV_32F);
cv::Mat II_br(hei,wid,CV_32F);
cv::Mat II_gr(hei,wid,CV_32F); cv::Mat var_I_bb(hei,wid,CV_32F);
cv::Mat var_I_gg(hei,wid,CV_32F);
cv::Mat var_I_rr(hei,wid,CV_32F);
cv::Mat var_I_bg(hei,wid,CV_32F);
cv::Mat var_I_br(hei,wid,CV_32F);
cv::Mat var_I_gr(hei,wid,CV_32F); cv::Mat layb;
cv::Mat layg;
cv::Mat layr;
cv::Mat P_32; // create vector of 3 images
std::vector<cv::Mat> planes;
// split 1 3-channel image into 3 1-channel images
cv::split(Img,planes); layb=planes[];
layg=planes[];
layr=planes[]; layb.convertTo(layb, CV_32F);
layg.convertTo(layg, CV_32F);
layr.convertTo(layr, CV_32F); p.convertTo(P_32,CV_32F);
cv::Mat nom_255(hei,wid,CV_32F,cv::Scalar()); layb=layb.mul(/nom_255,);
layg=layg.mul(/nom_255,);
layr=layr.mul(/nom_255,);
P_32=P_32.mul(/nom_255,); cv::Mat mean_I_b_temp=boxfilter(layb,r);
cv::Mat mean_I_g_temp=boxfilter(layg,r);
cv::Mat mean_I_r_temp=boxfilter(layr,r);
cv::Mat mean_p_temp=boxfilter(P_32,r); mean_I_b=mean_I_b_temp.mul(/N,);
mean_I_g=mean_I_g_temp.mul(/N,);
mean_I_r=mean_I_r_temp.mul(/N,);
mean_p=mean_p_temp.mul(/N,); Ip_b=layb.mul(P_32,);
Ip_g=layg.mul(P_32,);
Ip_r=layr.mul(P_32,); cv::Mat mean_Ip_b_temp=boxfilter(Ip_b,r);
cv::Mat mean_Ip_g_temp=boxfilter(Ip_g,r);
cv::Mat mean_Ip_r_temp=boxfilter(Ip_r,r); mean_Ip_b=mean_Ip_b_temp.mul(/N,);
mean_Ip_g=mean_Ip_g_temp.mul(/N,);
mean_Ip_r=mean_Ip_r_temp.mul(/N,); cov_Ip_b=mean_Ip_b-mean_I_b.mul(mean_p,);
cov_Ip_g=mean_Ip_g-mean_I_g.mul(mean_p,);
cov_Ip_r=mean_Ip_r-mean_I_r.mul(mean_p,); // variance of I in each local patch: the matrix Sigma in Eqn (14).
// Note the variance in each local patch is a 3x3 symmetric matrix:
// bb, bg, br
// Sigma = bg, gg, gr
// br, gr, rr
II_bb=layb.mul(layb,);
II_gg=layg.mul(layg,);
II_rr=layr.mul(layr,);
II_bg=layb.mul(layg,);
II_br=layb.mul(layr,);
II_gr=layg.mul(layr,); cv::Mat bb_box=boxfilter(II_bb,r);
cv::Mat gg_box=boxfilter(II_gg,r);
cv::Mat rr_box=boxfilter(II_rr,r);
cv::Mat bg_box=boxfilter(II_bg,r);
cv::Mat br_box=boxfilter(II_br,r);
cv::Mat gr_box=boxfilter(II_gr,r); var_I_bb=bb_box.mul(/N,)-mean_I_b.mul(mean_I_b);
var_I_gg=gg_box.mul(/N,)-mean_I_g.mul(mean_I_g);
var_I_rr=rr_box.mul(/N,)-mean_I_r.mul(mean_I_r);
var_I_bg=bg_box.mul(/N,)-mean_I_b.mul(mean_I_g);
var_I_br=br_box.mul(/N,)-mean_I_b.mul(mean_I_r);
var_I_gr=gr_box.mul(/N,)-mean_I_g.mul(mean_I_r); cv::Mat a_b(hei,wid,CV_32F);
cv::Mat a_g(hei,wid,CV_32F);
cv::Mat a_r(hei,wid,CV_32F); cv::Mat b(hei,wid,CV_32F);
cv::Mat sigma(,,CV_32F,cv::Scalar());
cv::Mat inv_sigma(,,CV_32F); for(int j=;j<hei;j++){
for(int i=;i<wid;i++){
sigma.at<float>(,)=var_I_rr.at<float>(j,i)+epsi;
sigma.at<float>(,)=var_I_gr.at<float>(j,i);
sigma.at<float>(,)=var_I_br.at<float>(j,i);
sigma.at<float>(,)=var_I_gr.at<float>(j,i);
sigma.at<float>(,)=var_I_br.at<float>(j,i);
sigma.at<float>(,)=var_I_gg.at<float>(j,i)+epsi;
sigma.at<float>(,)=var_I_bb.at<float>(j,i)+epsi;
sigma.at<float>(,)=var_I_bg.at<float>(j,i);
sigma.at<float>(,)=var_I_bg.at<float>(j,i);
inv_sigma=sigma.inv(cv::DECOMP_LU); a_r.at<float>(j,i)=cov_Ip_r.at<float>(j,i)*inv_sigma.at<float>(,)+
cov_Ip_g.at<float>(j,i)*inv_sigma.at<float>(,)+
cov_Ip_b.at<float>(j,i)*inv_sigma.at<float>(,);
a_g.at<float>(j,i)=cov_Ip_r.at<float>(j,i)*inv_sigma.at<float>(,)+
cov_Ip_g.at<float>(j,i)*inv_sigma.at<float>(,)+
cov_Ip_b.at<float>(j,i)*inv_sigma.at<float>(,);
a_b.at<float>(j,i)=cov_Ip_r.at<float>(j,i)*inv_sigma.at<float>(,)+
cov_Ip_g.at<float>(j,i)*inv_sigma.at<float>(,)+
cov_Ip_b.at<float>(j,i)*inv_sigma.at<float>(,); }
}
b=mean_p-a_b.mul(mean_I_b,)-a_g.mul(mean_I_g,)-a_r.mul(mean_I_r,); cv::Mat box_ab=boxfilter(a_b,r);
cv::Mat box_ag=boxfilter(a_g,r);
cv::Mat box_ar=boxfilter(a_r,r);
cv::Mat box_b=boxfilter(b,r);
cv::Mat q(hei,wid,CV_32F); q=box_ab.mul(layb,)+box_ag.mul(layg,)+box_ar.mul(layr,)+box_b;
q=q.mul(/N,); return q; }

dehazor.cpp

       截图:

  

 

 

基于暗通道优先算法的去雾应用(Matlab/C++)的更多相关文章

  1. 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果(速度可实时)

    最新的效果见 :http://video.sina.com.cn/v/b/124538950-1254492273.html 可处理视频的示例:视频去雾效果 在图像去雾这个领域,几乎没有人不知道< ...

  2. paper 105: 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他

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

  3. OpenCV导向滤波(引导滤波)实现(Guided Filter)代码,以及使用颜色先验算法去雾

    论文下载地址:http://research.microsoft.com/en-us/um/people/jiansun/papers/GuidedFilter_ECCV10.pdf 本文主要介绍导向 ...

  4. 暗通道去雾算法的python实现

    何凯明博士的去雾文章和算法实现已经漫天飞了,我今天也就不啰里啰唆,直接给出自己python实现的完整版本,全部才60多行代码,简单易懂,并有简要注释,去雾效果也很不错. 在这个python版本中,计算 ...

  5. Retinex图像增强和暗通道去雾的关系及其在hdr色调恢复上的应用

    很多人都认为retinex和暗通道去雾是八杆子都打不着的增强算法.的确,二者的理论.计算方法都完全迥异,本人直接从二者的公式入手来简单说明一下,有些部分全凭臆想,不对之处大家一起讨论. 首先,为描述方 ...

  6. paper 100:何恺明经典去雾算法

    一:由简至美的最佳论文(作者:何恺明  视觉计算组) [视觉机器人:个人感觉学习他的经典算法固然很重要,但是他的解决问题的思路也是非常值得我们学习的] 那是2009年4月24日的早上,我收到了一封不同 ...

  7. 基于clahe的图像去雾

    基于clahe的图像去雾     通过阅读一些资料,我了解到clahe算法对图像去雾有所价值,正好opencv中有了实现,拿过来看一看.   但是现在实现的效果还是有所差异 #);    clahe] ...

  8. 纯C++去雾算法

    去雾算法 前言:经过不断的改进研究,该算法最终稳定,高效的问世了. 经过研究使该算法适应大雾环境,对该算法的内存优化,可以实时的高效的执行. 一.实时视频: watermark/2/text/aHR0 ...

  9. 一种可实时处理 O(1)复杂度图像去雾算法的实现。

    在我博文的一系列的文章,有不少算法都于去雾有关,比如限制对比度自适应直方图均衡化算法原理.实现及效果.局部自适应自动色阶/对比度算法在图像增强上的应用这两个增强算法都有一定的去雾能力,而最直接的就是& ...

随机推荐

  1. WinForm与WPF下跨线程调用控件

    Winform下: public delegate void UpadataTextCallBack(string str,TextBox text); public void UpadtaText( ...

  2. HDU 1859

    #include <iostream> #include <cstdio> #include <algorithm> #include <vector> ...

  3. jaee开发起步:tomcat服务器的配置

    1.将下载下来的apache-tomcat-6.0.13.zip解压到任意文件夹. (打开tomcat官网,选择下载tomcat6.x.zip版本的tomcat不需要安装,直接解压并配置一下环境变量就 ...

  4. easyui的datagrid form(表单)提交到后台转对象的时候中文出现乱码

    在web.xml中配置如下代码 <filter> <filter-name>characterEncodingFilter</filter-name> <fi ...

  5. 疑问,关于win64无法使用debug的问题

    学习汇编语言的过程中,无法使用debug.exe,怎么办? 使用这篇文章中的解决方案 http://www.cnblogs.com/xuepeng0521/p/3661598.html 结果调试程序的 ...

  6. PV、EV、AC、BAC、EAC、ETC等计算公式含义

    PV.EV.AC.BAC.EAC.ETC等计算公式含义 PV Planned Value:计划值 应该完成多少工作, (按照计划截止目前应该花费的预算) AC Actual Cost:实际成本, 完成 ...

  7. angularJS绑定数据时自动转义html标签

    angularJS在进行数据绑定时默认是会以文本的形式输出,也就是对你数据中的html标签不进行转义照单全收,这样提高了安全性,防止了html标签中的注入攻击,但有些时候还是需要的,特别是从数据库读取 ...

  8. VMWARE修改CPUID

    在cmd shell下执行wmic cpu get ProcessorId命令,可是查看机器的cpuID,但这个命令显示的只是2组ID,实际CPUID,有4组 通过更改虚拟机配置文件.vmx可是实现任 ...

  9. 常用类string的用法

    在Java中string是我们用的很多的一种类,下面就来说说string类中经常用到的一些方法. 1.string与数组相关的方法: 比如:string str = "fsafdsafdas ...

  10. Buffer类

    输入流中可以通过缓冲区来加大读取的效率,sun公司感觉可以加快执行效率,他就为我们提供了一个类来操作缓存区. Buffer来头的类:所有缓冲流都是以Buffer开头的: 学习缓冲流的作用: Buffe ...