单幅图像基于暗通道的图像去雾

来源:互联网 发布:linux sh 编辑:程序博客网 时间:2024/04/28 15:38

博主写的文章很好,在此保存。from:http://blog.csdn.net/wds555/article/details/22699629

该代码部分实现了何凯明博士的论文暗通道去雾Single Image Haze Removal Using Dark Channel Prior,导向滤波算法尚未实现。

基于暗通道先验的单幅图去雾算法大致如下:
雾图I,目标无雾图J,雾图形成模型I=J*t+A(1-t)。
1、暗通道,窗口。
2、大气光成分:A。
3、去雾因子:w。
4、透射图:1-w*min(min(I/A))

5、导向滤波求透射率:t。
6、还原无雾图:J=(I-A)/t+A。
涉及到的滤波技术为soft matting和guidedfilter,boxfilter。(matlab和opencv实现导向滤波)

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include "cv.h"  
  2. #include "highgui.h"   
  3. //#include "GuidedFilter.h"  
  4.   
  5. IplImage* MinFilter(IplImage *img,int y,int x)  
  6. {  
  7.     IplImage *img_dark=cvCreateImage(cvSize(img->width,img->height),img->depth,1);  
  8.     IplImage *temp=cvCreateImage(cvSize(x,y),img->depth,img->nChannels);  
  9.     IplImage *temp0=cvCreateImage(cvSize(x,y),img->depth,1);  
  10.     CvScalar scalar={0.};  
  11.     double min=0.;  
  12.     double min1=0.;  
  13.     double min2=0.;  
  14.     double min3=0.;  
  15.     CvRect rect=cvRect(0,0,x,y);  
  16.     CvRect rect0=cvRect(0,0,x,y);  
  17.     int img_h=img->height;  
  18.     int img_w=img->width;  
  19.     for(int i=0;i<=img_h/y;i++)  
  20.     {  
  21.         if(i*y+1>img_h)  
  22.             continue;  
  23.         rect.y=i*y;  
  24.         if(i*y>img_h-y)  
  25.         {  
  26.             rect.height=img_h-i*y;  
  27.             rect0.height=img_h-i*y;  
  28.         }  
  29.         rect.width=x;  
  30.         rect0.width=x;  
  31.         for(int j=0;j<=img_w/x;j++)  
  32.         {  
  33.             if(j*x+1>img_w)  
  34.                 continue;  
  35.             rect.x=j*x;  
  36.             if(j*x>img_w-x)  
  37.             {  
  38.                 rect.width=img_w-j*x;  
  39.                 rect0.width=img_w-j*x;  
  40.             }  
  41.             cvSetImageROI(img,rect);  
  42.             cvSetImageROI(temp,rect0);  
  43.             cvCopy(img,temp);  
  44.             cvResetImageROI(img);  
  45.             cvSetImageCOI(temp,1);  
  46.             cvMinMaxLoc(temp,&min1,NULL,NULL,NULL);  
  47.             cvSetImageCOI(temp,2);  
  48.             cvMinMaxLoc(temp,&min2,NULL,NULL,NULL);  
  49.             cvSetImageCOI(temp,3);  
  50.             cvMinMaxLoc(temp,&min3,NULL,NULL,NULL);  
  51.             cvSetImageCOI(temp,0);  
  52.             if(min1<min2)  
  53.                 min=min1;  
  54.             else  
  55.                 min=min2;  
  56.             if(min>min3)  
  57.                 min=min3;  
  58.             scalar=cvScalar(min,0,0,0);  
  59.             cvSet(temp0,scalar,NULL);  
  60.             cvSetImageROI(temp0,rect0);  
  61.             cvSetImageROI(img_dark,rect);  
  62.             cvCopy(temp0,img_dark);  
  63.             cvResetImageROI(temp0);  
  64.             cvResetImageROI(img_dark);  
  65.         }  
  66.     }  
  67.     cvReleaseImage(&temp);  
  68.     cvReleaseImage(&temp0);  
  69.   
  70.     return img_dark;  
  71. }  
  72.   
  73. int main()  
  74. {  
  75.     int block_y=4;  
  76.     int block_x=4;  
  77.     double w=0.98;  
  78.     IplImage *img=cvLoadImage("train.bmp",-1);//定义原始图像    
  79.     int img_h=img->height;  
  80.     int img_w=img->width;  
  81.   
  82.     IplImage *des=cvCreateImage(cvSize(img->width,img->height),img->depth,img->nChannels);  
  83.     IplImage *img_dark=cvCreateImage(cvSize(img->width,img->height),img->depth,1);  
  84.     IplImage *img_t=cvCreateImage(cvSize(img->width,img->height),img->depth,1);  
  85.     img_dark=MinFilter(img,block_y,block_x);//暗通道图  
  86.   
  87.     //计算大气光值  
  88.     CvPoint max_point;  
  89.     double a_max=0.;  
  90.     cvMinMaxLoc(img_dark,NULL,&a_max,NULL,&max_point,NULL);  
  91.     int x=(max_point.x>(img_w-block_x))?(img_w-block_x):max_point.x;  
  92.     int y=(max_point.y>(img_h-block_y))?(img_h-block_y):max_point.y;  
  93.     CvScalar a={0.};  
  94.     double a_max0=0;  
  95.     double a_max1=0;  
  96.     double a_max2=0;  
  97.     for(int i=y;i<y+block_y;i++)  
  98.     {  
  99.         for(int j=x;j<x+block_x;j++)  
  100.         {  
  101.             a=cvGet2D(img,i,j);  
  102.             if(a_max0<a.val[0])  
  103.                 a_max0=a.val[0];  
  104.             if(a_max1<a.val[1])  
  105.                 a_max1=a.val[1];  
  106.             if(a_max2<a.val[2])  
  107.                 a_max2=a.val[2];  
  108.         }  
  109.     }  
  110.   
  111.     //计算透射率  
  112.     CvScalar p={0.};  
  113.     CvScalar q={0.};   
  114.     for(int i=0;i<img->height;i++)  
  115.     {  
  116.         for(int j=0;j<img->width;j++)  
  117.         {  
  118.             p=cvGet2D(img_dark,i,j);  
  119.             //q.val[0]=1-w*p.val[0]/a_max;  
  120.             q=cvScalar(255-w*p.val[0]);  
  121.             cvSet2D(img_t,i,j,q);  
  122.         }  
  123.     }  
  124.     cvSmooth(img_t,img_t,CV_BLUR,block_y*3,block_x*3);  
  125.   
  126.     //还原图像  
  127.     CvScalar I={0.};  
  128.     CvScalar t={0.};  
  129.     CvScalar dst={0.};  
  130.     double dst0,dst1,dst2;  
  131.     for(int i=0;i<img->height;i++)  
  132.     {  
  133.         for(int j=0;j<img->width;j++)  
  134.         {  
  135.             I=cvGet2D(img,i,j);  
  136.             double t=cvGetReal2D(img_t,i,j);  
  137.             t=t/255;  
  138.             if(t<0.1)  
  139.                 t=0.1;  
  140.             //dst.val[0]=(I.val[0]-a_max0)/t+a_max0;  
  141.             //dst.val[1]=(I.val[1]-a_max1)/t+a_max1;  
  142.             //dst.val[2]=(I.val[2]-a_max2)/t+a_max2;  
  143.             dst0=(I.val[0]-a_max0)/t+a_max0;  
  144.             dst1=(I.val[1]-a_max1)/t+a_max1;  
  145.             dst2=(I.val[2]-a_max2)/t+a_max2;  
  146.             dst=cvScalar(dst0,dst1,dst2,0);  
  147.             cvSet2D(des,i,j,dst);  
  148.         }  
  149.     }  
  150.       
  151.     cvNamedWindow("原图",CV_WINDOW_AUTOSIZE);  
  152.     cvShowImage("原图",img);  
  153.     cvNamedWindow("暗通道先验图",CV_WINDOW_AUTOSIZE);  
  154.     cvShowImage("暗通道先验图",img_dark);  
  155.     cvNamedWindow("透射率图",CV_WINDOW_AUTOSIZE);  
  156.     cvShowImage("透射率图",img_t);  
  157.     cvNamedWindow("目标图",CV_WINDOW_AUTOSIZE);  
  158.     cvShowImage("目标图",des);  
  159.   
  160.     cvWaitKey(0);  
  161.     cvReleaseImage(&img);  
  162.     cvReleaseImage(&img_dark);  
  163.     cvReleaseImage(&img_t);  
  164.     cvReleaseImage(&des);  
  165.     cvDestroyWindow("原图");  
  166.     cvDestroyWindow("暗通道先验图");  
  167.     cvDestroyWindow("透射率图");  
  168.     cvDestroyWindow("目标图");  
  169.     return 0;  
  170. }  


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 百褶的衣服平了怎么办 新买的毛巾掉毛怎么办 头发毛燥蓬蓬的怎么办 头发长得太慢怎么办 空气刘海剪多了怎么办 下颌骨宽显脸大怎么办 头发干枯毛躁自然卷怎么办 剪了齐刘海好丑怎么办 刘海剪得太短了怎么办 刘海分界处秃了怎么办 短发烫内扣外翻怎么办 刚剪的刘海好丑怎么办 齐刘海剪得太短怎么办 头发烫过太卷了怎么办? 头发烫了不卷怎么办 头发烫的显老气怎么办 烫了短发显老气怎么办 才烫的头发不卷怎么办 剪了短发显老气怎么办 头发染的巨黑怎么办 染黑头发太黑了怎么办 画眼线老是晕妆怎么办 闷青色染的太绿怎么办 血氧饱和度80多怎么办 染发前洗了头发怎么办 剪了短发后悔了怎么办 短发被剪的太短怎么办 短发剪得太短怎么办 烫头发后洗头了怎么办 头发染得太黄了怎么办 烫发后一直掉发怎么办 头发染的太黄了怎么办 头发染色太浅了怎么办 怀孕60天没有胎心怎么办 染了深褐色很黑怎么办 路边停车费没交怎么办 3岁宝宝难入睡怎么办 一上火眼睛就肿怎么办 孩子上火眼睛红有眼屎怎么办 孩子眼屎多又黄怎么办 眼睛皮周围红痒怎么办