真正了解了什么叫最简单的就是最美好的
真正的好文章不需要大堆公式堆积显得充实,而是最最平实的思想!
这篇文章的:原文PDF、数据集、幻灯片、视频。感兴趣的可以了解一下。
这篇文章的目的就是以最简单的思路将图像达到去雾效果。用Matlab编了一下,效果图特别好啊哈:

下面是摘录的:
CVPR的中文名是计算机视觉与模式识别会议,是计算机视觉领域最顶尖的国际 会议之一。09年的CVPR共收到约1450篇投稿,其中393篇文章被接收,接收率为26%。只有一篇文章被选为今年的最佳论文。这是CVPR创立25年 以来首次由中国人获得这个奖项。
2010年的结果也已经出来了,一共1724篇文章,CVPR2010 Paper Acceptance Rates: 78 papers were accepted for ORAL Presentation (4.5%).384 papers were accepted for POSTER Presentation (22.3%).
下面是作者的感想摘录,值得借鉴:
这篇论文研究的问题是图像的去雾技术,它可 以还原图像的颜色和能见度,同时也能利用雾的浓度来估计物体的距离,这些在计算机视觉上都有重要应用(例如三维重建,物体识别)。但是之前人们还没找到简 单有效的方法来达到这个目的。在这篇论文里,我们找到了一个非常简单的,甚至说令人惊讶统计规律,并提出了有效的去雾方法。
与之前的方法不同,我们把注意力放到了无雾图像的统计特征上。我们发 现,在无雾图像中,每一个局部区域都很有可能会有阴影,或者是纯颜色的东西,又或者是黑色的东西。因此,每一个局部区域都很有可能有至少一个颜色通道会有 很低的值。我们把这个统计规律叫做Dark Channel Prior。直观来说,Dark Channel Prior认为每一个局部区域都总有一些很暗的东西。这个规律很简单,但在我们研究的去雾问题上却是本质的基本规律。
由于雾总是灰白色的,因此一旦图像受到雾的影响,那么这些本来应该很暗 的东西就会变得灰白。不仅如此,根据物理上雾的形成公式,我们还能根据这些东西的灰白程度来判断雾的浓度。因此,我们提出的Dark Channel Prior能很有效地去除雾的影响,同时利用物的浓度来估算物体的距离。
大道之行在于简
我们这篇文章的三个审稿人都给出了最高的评分。他们认为我们的方法简单 而有效。其中一位评委说,Dark Channel Prior的想法听起来很不可思议,但我们却证明了其真实性。另一位评委认为很少有文章能够用如此简单的方法使实验结果获得如此大的提升。还有一位评委甚 至亲自实现了我们的方法并确认其可行。孙剑说阅读这样的评审结果是一件让人快乐的事情。而汤老师认为,这篇文章的成功在于三个方面。第一,方法非常简单; 第二,对于一个很困难的问题,给出了很好的结果;第三,发现了一个基本的自然规律并且应用在实际的问题中。在迈阿密的演讲结束后,观众也给予了很高的评 价。他们跟我说,这是这次CVPR上最有趣的一个演讲。
一位与会的研究员说,最好的idea,往往就是那些看起来很简单,但说 出来大家都会觉得怎么没有人想到过的idea。而我们的idea正好就符合了这一点。我们论文摘要的第一句话是这么说的,“我们提出了一个简单而有效的方 法”。或许,这就是对我们这次工作最好的概括——简单的,就是美的。
代码如下:
1.MATLAB
[html] view plain copy print ?
- %=========================================================%
- %调用规则:(有雾时调用,否则不调用)
- %实际操作时,according to experiments:
- %percent=under_50/total
- %percent<0.1%,取w=0.6
- %percent>0.1%&&percent<1%,取w=0.45
- %percenet>1%&&percent<2%,取w=0.3
- %else not use haze-free-adjust
- %有雾:绘制出的直方图<50的部分<1%
- %最后控制台还会输出原图中under_50像素点所占比例
- %=========================================================%
- close all
- clear all
- clc
- blockSize=15; %每个block为15个像素
- w0=0.6;
- t0=0.1;
- % A=200;
- I=imread('D:\毕业设计\Images\pic_loc\1870575550604291415.jpg');
- %I=imread('C:\Users\Zrq\Desktop\同济.jpg');
- h = figure;
- %set(gcf,'outerposition',get(0,'screensize'));%获得SystemScreenSize 传递给当前图像句柄gcf的outerposition属性
- subplot(321)%表示3(行数)*2(列数)的图像,1代表所画图形的序号
- imshow(I);
- title('Original Image');
-
-
- subplot(323);
- grayI=rgb2gray(I);
- imshow(grayI,[]);
- title('原图像灰度图')
-
- subplot(324);
- imhist(grayI,64);
-
- %统计<50的像素所占的比例
- %%%%%%%%%%%%%%%%%%%%%%
- [COUNT x]=imhist(grayI);
- under_50=0;
- for i=0:50
- under_50=under_50+COUNT(x==i);
- end
- under_50
- total=size(I,1)*size(I,2)*size(I,3);
- percent=under_50/total
- %%%%%%%%%%%%%%%%%%%%%%
-
- if(percent>0.02)
- error('This image need not Haze-Free-Proprocessing.');
- else if(percent<0.001)
- w=0.6;
- else if (percent>0.01)
- w=0.3;
- else
- w=0.45;
- end
- end
- end
-
- [h,w,s]=size(I);
- min_I=zeros(h,w);
-
- for i=1:h
- for j=1:w
- dark_I(i,j)=min(I(i,j,:));%取每个点的像素为RGB分量中最低的那个通道的值
- end
- end
-
- Max_dark_channel=double(max(max(dark_I)))
- dark_channel=double(dark_I);
- t=1-w0*(dark_channel/Max_dark_channel);
-
- T=uint8(t*255);
-
- t=max(t,t0);
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- I1=double(I);
- J(:,:,1) = uint8((I1(:,:,1) - (1-t)*Max_dark_channel)./t);
-
- J(:,:,2) = uint8((I1(:,:,2) - (1-t)*Max_dark_channel)./t);
-
- J(:,:,3) =uint8((I1(:,:,3) - (1-t)*Max_dark_channel)./t);
- subplot(322)
- imshow(J);
- imwrite(J,'tj2.jpg');
- title('Haze-Free Image:');
-
- subplot(325);
- grayJ=rgb2gray(J);
- imshow(grayJ,[]);
- title('去雾后灰度图')
-
- subplot(326);
- imhist(grayJ,64);
%=========================================================% %调用规则:(有雾时调用,否则不调用) %实际操作时,according to experiments: %percent=under_50/total %percent<0.1%,取w=0.6 %percent>0.1%&&percent<1%,取w=0.45 %percenet>1%&&percent<2%,取w=0.3 %else not use haze-free-adjust %有雾:绘制出的直方图<50的部分<1% %最后控制台还会输出原图中under_50像素点所占比例 %=========================================================% close all clear all clc blockSize=15; %每个block为15个像素 w0=0.6; t0=0.1; % A=200; I=imread('D:\毕业设计\Images\pic_loc\1870575550604291415.jpg'); %I=imread('C:\Users\Zrq\Desktop\同济.jpg'); h = figure; %set(gcf,'outerposition',get(0,'screensize'));%获得SystemScreenSize 传递给当前图像句柄gcf的outerposition属性 subplot(321)%表示3(行数)*2(列数)的图像,1代表所画图形的序号 imshow(I); title('Original Image'); subplot(323); grayI=rgb2gray(I); imshow(grayI,[]); title('原图像灰度图') subplot(324); imhist(grayI,64); %统计<50的像素所占的比例 %%%%%%%%%%%%%%%%%%%%%% [COUNT x]=imhist(grayI); under_50=0; for i=0:50 under_50=under_50+COUNT(x==i); end under_50 total=size(I,1)*size(I,2)*size(I,3); percent=under_50/total %%%%%%%%%%%%%%%%%%%%%% if(percent>0.02) error('This image need not Haze-Free-Proprocessing.'); else if(percent<0.001) w=0.6; else if (percent>0.01) w=0.3; else w=0.45; end end end [h,w,s]=size(I); min_I=zeros(h,w); for i=1:h for j=1:w dark_I(i,j)=min(I(i,j,:));%取每个点的像素为RGB分量中最低的那个通道的值 end end Max_dark_channel=double(max(max(dark_I))) dark_channel=double(dark_I); t=1-w0*(dark_channel/Max_dark_channel); T=uint8(t*255); t=max(t,t0); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% I1=double(I); J(:,:,1) = uint8((I1(:,:,1) - (1-t)*Max_dark_channel)./t); J(:,:,2) = uint8((I1(:,:,2) - (1-t)*Max_dark_channel)./t); J(:,:,3) =uint8((I1(:,:,3) - (1-t)*Max_dark_channel)./t); subplot(322) imshow(J); imwrite(J,'tj2.jpg'); title('Haze-Free Image:'); subplot(325); grayJ=rgb2gray(J); imshow(grayJ,[]); title('去雾后灰度图') subplot(326); imhist(grayJ,64);
2.OPENCV
[cpp] view plain copy print ?
-
-
- char tbarname1[] = "调节block";
-
- char tbarname2[] = "调节w";
-
- int block=5;
- int w1=80;
- double w;
- IplImage *dst=NULL;
-
- IplImage *quw(IplImage *src,int block,double w)
- {
-
- IplImage *dst1=NULL;
- IplImage *dst2=NULL;
- IplImage *dst3=NULL;
- IplImage *imgroi1;
-
- IplImage *imgroi2;
-
- IplImage *imgroi3;
-
- IplImage *roidark;
-
- IplImage *dark_channel=NULL;
-
- IplImage *toushelv=NULL;
-
-
-
- IplImage *j1=NULL;
- IplImage *j2=NULL;
- IplImage *j3=NULL;
-
- IplImage *dst=NULL;
-
- CvRect ROI_rect;
-
-
- dst1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
- dst2=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
- dst3=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
-
-
- imgroi1=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);
- imgroi2=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);
- imgroi3=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);
- roidark=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);
-
-
- j1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
- j2=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
- j3=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
-
-
- dark_channel=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
-
- toushelv=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
-
- dst=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,3);
-
- cvSplit(src,dst1,dst2,dst3,NULL);
-
- ROI_rect.width=block;
- ROI_rect.height=block;
- ROI_rect.x=0;
- ROI_rect.y=0;
-
-
- int i;
- int j;
- double min1=0;
- double max1=0;
- double min2=0;
- double max2=0;
- double min3=0;
- double max3=0;
- double min=0;
- CvScalar value;
- for(i=0;i<src->width/block;i++)
- { for(j=0;j<src->height/block;j++)
- {
-
- cvSetImageROI(dst1,ROI_rect);
- cvCopy(dst1,imgroi1,NULL);
- cvMinMaxLoc(imgroi1,&min1,&max1,NULL,NULL);
- cvSetImageROI(dst2,ROI_rect);
- cvCopy(dst2,imgroi2,NULL);
- cvMinMaxLoc(imgroi2,&min2,&max2,NULL,NULL);
- cvSetImageROI(dst3,ROI_rect);
- cvCopy(dst3,imgroi3,NULL);
- cvMinMaxLoc(imgroi3,&min3,&max3,NULL,NULL);
-
- if(min1<min2)
- min=min1;
- else
- min=min2;
- if(min>min3)
- min=min3;
- value=cvScalar(min,min,min,min);
-
- cvSetImageROI(dark_channel,ROI_rect);
- cvSet(roidark,value,NULL);
- cvCopy(roidark,dark_channel,NULL);
-
- cvResetImageROI(dst1);
- cvResetImageROI(dst2);
- cvResetImageROI(dst3);
- cvResetImageROI(dark_channel);
-
- ROI_rect.x=block*i;
- ROI_rect.y=block*j;
- }
- }
-
- cvSaveImage("f:/dark_channel_prior.jpg",dark_channel);
-
- double min_dark;
- double max_dark;
- CvPoint min_loc;
- CvPoint max_loc;
- cvMinMaxLoc(dark_channel,&min_dark,&max_dark,&min_loc,&max_loc,NULL);
-
- ROI_rect.x=max_loc.x;
- ROI_rect.y=max_loc.y;
- double A_dst1;
- double dst1_min;
- double A_dst2;
- double dst2_min;
- double A_dst3;
- double dst3_min;
- cvSetImageROI(dst1,ROI_rect);
-
- cvCopy(dst1,imgroi1,NULL);
- cvMinMaxLoc(imgroi1,&dst1_min,&A_dst1,NULL,NULL);
- cvSetImageROI(dst2,ROI_rect);
- cvCopy(dst2,imgroi2,NULL);
- cvMinMaxLoc(imgroi2,&dst2_min,&A_dst2,NULL,NULL);
- cvSetImageROI(dst3,ROI_rect);
- cvCopy(dst3,imgroi3,NULL);
- cvMinMaxLoc(imgroi3,&dst3_min,&A_dst3,NULL,NULL);
-
-
- int k;
- int l;
- CvScalar m;
- CvScalar n;
-
- for(k=0;k<src->height;k++)
- {
- for(l=0;l<src->width;l++)
- {
- m=cvGet2D(dark_channel,k,l);
- n=cvScalar(255-w*m.val[0]);
-
- cvSet2D(toushelv,k,l,n);
- }
- }
- cvSaveImage("f:/toushelv.jpg",toushelv);
-
-
- int p,q;
- double tx;
- double jj1,jj2,jj3;
- CvScalar ix,jx;
- for(p=0;p<src->height;p++)
- {
- for(q=0;q<src->width;q++)
- {
- tx=cvGetReal2D(toushelv,p,q);
- tx=tx/255;
- if(tx<0.1)
- tx=0.1;
- ix=cvGet2D(src,p,q);
- jj1=(ix.val[0]-A_dst1)/tx+A_dst1;
- jj2=(ix.val[1]-A_dst2)/tx+A_dst2;
- jj3=(ix.val[2]-A_dst3)/tx+A_dst3;
- jx=cvScalar(jj1,jj2,jj3,0.0);
- cvSet2D(dst,p,q,jx);
- }
- }
- cvSaveImage("f:/removed_haze.jpg",dst);
-
-
- cvReleaseImage(&dst1);
- cvReleaseImage(&dst2);
- cvReleaseImage(&dst3);
- cvReleaseImage(&imgroi1);
- cvReleaseImage(&imgroi2);
- cvReleaseImage(&imgroi3);
- cvReleaseImage(&roidark);
- cvReleaseImage(&dark_channel);
- cvReleaseImage(&toushelv);
- cvReleaseImage(&j1);
- cvReleaseImage(&j2);
- cvReleaseImage(&j3);
- return dst;
- }
-
- IplImage *source;
- void on_trackbar1(int h)
- {
- dst=quw(source,block,w);
- cvShowImage("目的图像",dst);
-
- }
- void on_trackbar2(int h)
- {
- w=(double)w1/100;
- dst=quw(source,block,w);
- cvShowImage("目的图像",dst);
-
- }
-
- void CCVMFCView::OnImageHazefree()
- {
- imageClone(workImg,&source);
-
- cvFlip(source);
-
- cvNamedWindow("目的图像",CV_WINDOW_AUTOSIZE);
- cvShowImage("目的图像",source);
- cvCreateTrackbar(tbarname1, "目的图像", &block, 15, on_trackbar1);
- cvCreateTrackbar(tbarname2, "目的图像", &w1, 100, on_trackbar2);
- cvWaitKey(0);
-
- cvReleaseImage(&source);
-
- cvDestroyWindow("目的图像");
- cvDestroyWindow("有雾图像");
- cvFlip(dst);
- m_dibFlag=imageReplace(dst,&workImg);
- Invalidate();
- }
我自己也仿照着了一个OpenCV的可以编译执行~
http://download.csdn.net/detail/sangni007/4309615