导向滤波实现代码以及使用颜色先验去雾算法

论文下载地址:http://research.microsoft.com/en-us/um/people/jiansun/papers/GuidedFilter_ECCV10.pdf

本文主要介绍导向滤波,这算法还能去雾,这块主要是重写了导向滤波应用于彩色图像的部分代码,希望与大家共同交流。

 

论文主要如下:

Kaiming He, Jian Sun, Xiaoou Tang. Single Image Haze Removal Using Dark Channel Prior

大致内容是提出了一个叫做暗原色先验的东西来对有雾图像进行处理,十分巧妙,有兴趣者可以看看。这里使用OpenCV实现文中的去雾算法,然而论文提到的soft matting未在本程序中实现。

 

原理如下:

 

 

 

滤波效果:

 

单通道效果:

 方法1效果:

 

 

 

 

方法2效果:

 

 

效果----为何要滤波:

 

 

 

guied filter滤波代码:使用了两种方法,代码来源后面参考文献中。我做了一些修改和比对工作。

 

 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // Guided Filter.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <iostream>  
  6. #include "opencv2/core/core.hpp"    
  7. #include "opencv2/highgui/highgui.hpp"    
  8. #include "opencv2/imgproc/imgproc.hpp"    
  9.     
  10. #pragma comment(lib,"opencv_core2410d.lib")                      
  11. #pragma comment(lib,"opencv_highgui2410d.lib")                      
  12. #pragma comment(lib,"opencv_imgproc2410d.lib")      
  13.   
  14. using namespace std;  
  15. using namespace cv;  
  16.   
  17. Mat getimage(Mat &a)  
  18. {  
  19.     int hei  =a.rows;  
  20.     int wid = a.cols;  
  21.     Mat I(hei, wid, CV_64FC1);  
  22.     //convert image depth to CV_64F  
  23.     a.convertTo(I, CV_64FC1,1.0/255.0);  
  24.     //normalize the pixel to 0~1  
  25.     /* 
  26.     for( int i = 0; i< hei; i++){ 
  27.         double *p = I.ptr<double>(i); 
  28.         for( int j = 0; j< wid; j++){ 
  29.             p[j] = p[j]/255.0;   
  30.         } 
  31.     } 
  32.     */  
  33.     return I;  
  34. }  
  35.   
  36. Mat cumsum(Mat &imSrc, int rc)  
  37. {  
  38.     if(!imSrc.data)  
  39.     {  
  40.         cout << "no data input!\n" << endl;  
  41.     }  
  42.     int hei = imSrc.rows;  
  43.     int wid = imSrc.cols;  
  44.     Mat imCum = imSrc.clone();  
  45.     if( rc == 1)  
  46.     {  
  47.         forint i =1;i < hei; i++)  
  48.         {  
  49.             forint j = 0; j< wid; j++)  
  50.             {  
  51.                 imCum.at<double>(i,j) += imCum.at<double>(i-1,j);  
  52.             }  
  53.         }  
  54.     }  
  55.   
  56.     if( rc == 2)  
  57.     {  
  58.         forint i =0;i < hei; i++)  
  59.         {  
  60.             forint j = 1; j< wid; j++)  
  61.             {  
  62.                 imCum.at<double>(i,j) += imCum.at<double>(i,j-1);  
  63.             }  
  64.         }  
  65.     }  
  66.     return imCum;  
  67. }  
  68.   
  69. Mat boxfilter(Mat &imSrc, int r)  
  70. {  
  71.     int hei = imSrc.rows;  
  72.     int wid = imSrc.cols;  
  73.     Mat imDst = Mat::zeros( hei, wid, CV_64FC1);  
  74.     //imCum = cumsum(imSrc, 1);  
  75.     Mat imCum = cumsum(imSrc,1);  
  76.     //imDst(1:r+1, :) = imCum(1+r:2*r+1, :);  
  77.     forint i = 0; i<r+1; i++)  
  78.     {  
  79.         forint j=0; j<wid; j++ )  
  80.         {  
  81.             imDst.at<double>(i,j) = imCum.at<double>(i+r,j);  
  82.         }  
  83.     }  
  84.     //imDst(r+2:hei-r, :) = imCum(2*r+2:hei, :) - imCum(1:hei-2*r-1, :);  
  85.     forint i =r+1; i<hei-r;i++)  
  86.     {  
  87.         forint j = 0; j<wid;j++)  
  88.         {  
  89.             imDst.at<double>(i,j) = imCum.at<double>(i+r,j)-imCum.at<double>(i-r-1,j);  
  90.         }  
  91.     }  
  92.     //imDst(hei-r+1:hei, :) = repmat(imCum(hei, :), [r, 1]) - imCum(hei-2*r:hei-r-1, :);  
  93.     forint i = hei-r; i< hei; i++)  
  94.     {  
  95.         forint j = 0; j< wid; j++)  
  96.         {  
  97.             imDst.at<double>(i,j) = imCum.at<double>(hei-1,j)-imCum.at<double>(i-r-1,j);  
  98.         }  
  99.     }  
  100.     imCum = cumsum(imDst, 2);  
  101.     //imDst(:, 1:r+1) = imCum(:, 1+r:2*r+1);  
  102.     forint i = 0; i<hei; i++)  
  103.     {  
  104.         forint j=0; j<r+1; j++ )  
  105.         {  
  106.             imDst.at<double>(i,j) = imCum.at<double>(i,j+r);  
  107.         }  
  108.     }  
  109.     //imDst(:, r+2:wid-r) = imCum(:, 2*r+2:wid) - imCum(:, 1:wid-2*r-1);  
  110.     forint i =0 ; i<hei;i++)  
  111.     {  
  112.         forint j = r+1; j<wid-r ;j++ )  
  113.         {  
  114.             imDst.at<double>(i,j) = imCum.at<double>(i,j+r)-imCum.at<double>(i,j-r-1);  
  115.         }  
  116.     }  
  117.     //imDst(:, wid-r+1:wid) = repmat(imCum(:, wid), [1, r]) - imCum(:, wid-2*r:wid-r-1);  
  118.     forint i = 0; i< hei; i++)  
  119.     {  
  120.         forint j = wid-r; j<wid; j++)  
  121.         {  
  122.             imDst.at<double>(i,j) = imCum.at<double>(i,wid-1)-imCum.at<double>(i,j-r-1);  
  123.         }  
  124.     }  
  125.     return imDst;  
  126. }  
  127.   
  128. Mat guidedfilter( Mat &I, Mat &p, int r, double eps )   
  129. {  
  130.     int hei = I.rows;  
  131.     int wid = I.cols;  
  132.     //N = boxfilter(ones(hei, wid), r);  
  133.     Mat one = Mat::ones(hei, wid, CV_64FC1);  
  134.     Mat N = boxfilter(one, r);  
  135.   
  136.     //mean_I = boxfilter(I, r) ./ N;  
  137.     Mat mean_I(hei, wid, CV_64FC1);  
  138.     divide(boxfilter(I, r), N, mean_I);  
  139.   
  140.     //mean_p = boxfilter(p, r) ./ N;  
  141.     Mat mean_p(hei, wid, CV_64FC1);  
  142.     divide(boxfilter(p, r), N, mean_p);  
  143.   
  144.     //mean_Ip = boxfilter(I.*p, r) ./ N;  
  145.     Mat mul_Ip(hei, wid, CV_64FC1);  
  146.     Mat mean_Ip(hei, wid, CV_64FC1);  
  147.     multiply(I,p,mul_Ip);  
  148.     divide(boxfilter(mul_Ip, r), N, mean_Ip);  
  149.   
  150.     //cov_Ip = mean_Ip - mean_I .* mean_p  
  151.     //this is the covariance of (I, p) in each local patch.  
  152.     Mat mul_mean_Ip(hei, wid, CV_64FC1);  
  153.     Mat cov_Ip(hei, wid, CV_64FC1);  
  154.     multiply(mean_I, mean_p, mul_mean_Ip);  
  155.     subtract(mean_Ip, mul_mean_Ip, cov_Ip);  
  156.   
  157.     //mean_II = boxfilter(I.*I, r) ./ N;  
  158.     Mat mul_II(hei, wid, CV_64FC1);  
  159.     Mat mean_II(hei, wid, CV_64FC1);  
  160.     multiply(I, I, mul_II);  
  161.     divide(boxfilter(mul_II, r), N, mean_II);  
  162.   
  163.     //var_I = mean_II - mean_I .* mean_I;  
  164.     Mat mul_mean_II(hei, wid, CV_64FC1);  
  165.     Mat var_I(hei, wid, CV_64FC1);  
  166.     multiply(mean_I, mean_I, mul_mean_II);  
  167.     subtract(mean_II, mul_mean_II, var_I);  
  168.   
  169.     //a = cov_Ip ./ (var_I + eps);  
  170.     Mat a(hei, wid, CV_64FC1);  
  171.     forint i = 0; i< hei; i++){  
  172.         double *p = var_I.ptr<double>(i);  
  173.         forint j = 0; j< wid; j++){  
  174.             p[j] = p[j] +eps;     
  175.         }  
  176.     }  
  177.     divide(cov_Ip, var_I, a);  
  178.   
  179.     //b = mean_p - a .* mean_I;  
  180.     Mat a_mean_I(hei ,wid, CV_64FC1);  
  181.     Mat b(hei ,wid, CV_64FC1);  
  182.     multiply(a, mean_I, a_mean_I);  
  183.     subtract(mean_p, a_mean_I, b);  
  184.   
  185.     //mean_a = boxfilter(a, r) ./ N;  
  186.     Mat mean_a(hei, wid, CV_64FC1);  
  187.     divide(boxfilter(a, r), N, mean_a);  
  188.     //mean_b = boxfilter(b, r) ./ N;  
  189.     Mat mean_b(hei, wid, CV_64FC1);  
  190.     divide(boxfilter(b, r), N, mean_b);  
  191.   
  192.     //q = mean_a .* I + mean_b;  
  193.     Mat mean_a_I(hei, wid, CV_64FC1);  
  194.     Mat q(hei, wid, CV_64FC1);  
  195.     multiply(mean_a, I, mean_a_I);  
  196.     add(mean_a_I, mean_b, q);  
  197.   
  198.     return q;  
  199. }  
  200.   
  201. /***************** 
  202.  
  203. http://research.microsoft.com/en-us/um/people/kahe/eccv10/ 
  204. 推酷上的一篇文章: 
  205. http://www.tuicool.com/articles/Mv2iiu 
  206.  
  207. ************************/  
  208. cv::Mat guidedFilter2(cv::Mat I, cv::Mat p, int r, double eps)  
  209. {  
  210.   /* 
  211.   % GUIDEDFILTER   O(1) time implementation of guided filter. 
  212.   % 
  213.   %   - guidance image: I (should be a gray-scale/single channel image) 
  214.   %   - filtering input image: p (should be a gray-scale/single channel image) 
  215.   %   - local window radius: r 
  216.   %   - regularization parameter: eps 
  217.   */  
  218.    
  219.   cv::Mat _I;  
  220.   I.convertTo(_I, CV_64FC1);  
  221.   I = _I;  
  222.    
  223.   cv::Mat _p;  
  224.   p.convertTo(_p, CV_64FC1);  
  225.   p = _p;  
  226.    
  227.   //[hei, wid] = size(I);  
  228.   int hei = I.rows;  
  229.   int wid = I.cols;  
  230.    
  231.   //N = boxfilter(ones(hei, wid), r); % the size of each local patch; N=(2r+1)^2 except for boundary pixels.  
  232.   cv::Mat N;  
  233.   cv::boxFilter(cv::Mat::ones(hei, wid, I.type()), N, CV_64FC1, cv::Size(r, r));  
  234.    
  235.   //mean_I = boxfilter(I, r) ./ N;  
  236.   cv::Mat mean_I;  
  237.   cv::boxFilter(I, mean_I, CV_64FC1, cv::Size(r, r));  
  238.     
  239.   //mean_p = boxfilter(p, r) ./ N;  
  240.   cv::Mat mean_p;  
  241.   cv::boxFilter(p, mean_p, CV_64FC1, cv::Size(r, r));  
  242.    
  243.   //mean_Ip = boxfilter(I.*p, r) ./ N;  
  244.   cv::Mat mean_Ip;  
  245.   cv::boxFilter(I.mul(p), mean_Ip, CV_64FC1, cv::Size(r, r));  
  246.    
  247.   //cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch.  
  248.   cv::Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);  
  249.    
  250.   //mean_II = boxfilter(I.*I, r) ./ N;  
  251.   cv::Mat mean_II;  
  252.   cv::boxFilter(I.mul(I), mean_II, CV_64FC1, cv::Size(r, r));  
  253.    
  254.   //var_I = mean_II - mean_I .* mean_I;  
  255.   cv::Mat var_I = mean_II - mean_I.mul(mean_I);  
  256.    
  257.   //a = cov_Ip ./ (var_I + eps); % Eqn. (5) in the paper;     
  258.   cv::Mat a = cov_Ip/(var_I + eps);  
  259.    
  260.   //b = mean_p - a .* mean_I; % Eqn. (6) in the paper;  
  261.   cv::Mat b = mean_p - a.mul(mean_I);  
  262.    
  263.   //mean_a = boxfilter(a, r) ./ N;  
  264.   cv::Mat mean_a;  
  265.   cv::boxFilter(a, mean_a, CV_64FC1, cv::Size(r, r));  
  266.   mean_a = mean_a/N;  
  267.    
  268.   //mean_b = boxfilter(b, r) ./ N;  
  269.   cv::Mat mean_b;  
  270.   cv::boxFilter(b, mean_b, CV_64FC1, cv::Size(r, r));  
  271.   mean_b = mean_b/N;  
  272.    
  273.   //q = mean_a .* I + mean_b; % Eqn. (8) in the paper;  
  274.   cv::Mat q = mean_a.mul(I) + mean_b;  
  275.    
  276.   return q;  
  277. }  
  278.   
  279.   
  280.   
  281. int _tmain(int argc, _TCHAR* argv[])  
  282. {  
  283.     int r = 4;  
  284.     double eps = 0.01;  
  285.   
  286.     string image_name ;  
  287.     cout<<"input name:"<<endl;  
  288.     cin>>image_name;  
  289.   
  290.           
  291.     /* 
  292.     CV_LOAD_IMAGE_ANYDEPTH - If set, return 16-bit/32-bit image when the input has the corresponding depth,  
  293.     otherwise convert it to 8-bit. 
  294.     CV_LOAD_IMAGE_COLOR - If set, always convert image to the color one 
  295.     CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one 
  296.     >0 Return a 3-channel color image. 
  297.  
  298. Note: 
  299.  
  300.     In the current implementation the alpha channel, if any, is stripped from the output image. 
  301.     Use negative value if you need the alpha channel. 
  302.  
  303.     =0 Return a grayscale image. 
  304.     <0 Return the loaded image as is (with alpha channel). 
  305. */  
  306.   
  307.   
  308.     Mat image_src = imread(image_name,CV_LOAD_IMAGE_COLOR);  
  309.     Mat image_gray(image_src.size(),CV_8UC1);  
  310.   
  311.     cvtColor(image_src,image_gray,CV_BGR2GRAY);  
  312.   
  313.     vector<Mat> bgr_src,bgr_dst;  
  314.     split(image_src,bgr_src);//分解每个通道  
  315.   
  316.     Mat dst_color;  
  317.       
  318.     double time;  
  319.     time = (double)getTickCount();  
  320.     for(int i=0;i<3;i++)    
  321.     {    
  322.         Mat I = getimage(bgr_src[i]);  
  323.         Mat p = I.clone();  
  324.           
  325.         Mat q = guidedfilter(I, p, r, eps);  
  326.         //string number ;  
  327.         //sprintf((char *)number.c_str(),"%d",i);  
  328.         //imshow(number,q);  
  329.   
  330.         //imshow("方法1:", q);  
  331.         bgr_dst.push_back(q);  
  332.         //cv::merge(q,dst_color);  
  333.           
  334.     }    
  335.     merge(bgr_dst,dst_color);  
  336.   
  337.     //imwrite("filtered.bmp", q*255);  
  338.     time = 1000*((double)getTickCount() - time)/getTickFrequency();    
  339.   
  340.     cout <<endl<<"Time of guided filter for  runs: " << time << " milliseconds."<< endl;   
  341.   
  342.     imshow("原图像的灰度图", image_gray);  
  343.     imshow("方法1:", dst_color);  
  344.     imwrite("result.jpg",dst_color*255);  
  345.       
  346.     double time2 = 0;  
  347.     time2 = (double)getTickCount();  
  348.   
  349.     Mat I = getimage(image_gray);  
  350.     Mat p = I.clone();  
  351.     //int r = 8;  
  352.     //double eps = 0.04;  
  353.       
  354.     //Mat q = guidedfilter(I, p, r, eps);  
  355.   
  356.     //imwrite("filtered.bmp", q*255);  
  357.     //*/  
  358.   
  359.     /*imshow("原图像的灰度图", image_gray);  
  360.     imshow("方法1:", q);*/  
  361.   
  362.     imshow("方法2:",guidedFilter2(I, p, r, eps));  
  363.     time2 = 1000*((double)getTickCount() - time2)/getTickFrequency();    
  364.   
  365.     cout <<endl<<"Time of guided filter2 for  runs: " << time2 << " milliseconds."<< endl;   
  366.     waitKey(0);  
  367.   
  368.   
  369.     return 0;  
  370. }  


 

 

下面的代码还没有真正的调试,只是找到了,先放在这里,后面有空再看看研究一下。 

 

去雾代码1:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.    
  2.   
  3.    
  4.   
  5. #include<iostream.h>  
  6.   
  7. #include<cv.h>  
  8.   
  9. #include<highgui.h>  
  10.   
  11. char tbarname1[] = "调节block";  
  12.   
  13. //定义两个滑动条,用于调节参数  
  14.   
  15. char tbarname2[] = "调节w";  
  16.   
  17. //w是为了保留一部分的雾  
  18.   
  19. int block=5;  
  20.   
  21. int w1=80;  
  22.   
  23. double w;  
  24.   
  25. IplImage *src=NULL;  
  26.   
  27. IplImage *dst=NULL;  
  28.   
  29.    
  30.   
  31. //定义去雾函数如下  
  32.   
  33. IplImage *quw(IplImage *src,int block,double w)  
  34.   
  35. {  
  36.   
  37. //图像分别有三个颜色通道  
  38.   
  39.          IplImage *dst1=NULL;  
  40.   
  41.          IplImage *dst2=NULL;  
  42.   
  43.          IplImage *dst3=NULL;  
  44.   
  45.          IplImage *imgroi1;  
  46.   
  47.          //dst1的ROI  
  48.   
  49.          IplImage *imgroi2;  
  50.   
  51.          //dst2的ROI  
  52.   
  53.          IplImage *imgroi3;  
  54.   
  55.          //dst3的ROI  
  56.   
  57.          IplImage *roidark;  
  58.   
  59.          //dark channel的ROI  
  60.   
  61.          IplImage *dark_channel=NULL;  
  62.   
  63.          //暗原色先验的指针  
  64.   
  65.          IplImage *toushelv=NULL;  
  66.   
  67.          //透射率  
  68.   
  69.    
  70.   
  71. //去雾算法运算后的三个通道  
  72.   
  73.          IplImage *j1=NULL;  
  74.   
  75.          IplImage *j2=NULL;  
  76.   
  77.          IplImage *j3=NULL;  
  78.   
  79. //去雾后的图像,三通道合并成  
  80.   
  81.          IplImage *dst=NULL;  
  82.   
  83. //源图像ROI位置以及大小  
  84.   
  85.          CvRect ROI_rect;  
  86.   
  87.    
  88.   
  89. //分离的三个通道  
  90.   
  91.          dst1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  92.   
  93.          dst2=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  94.   
  95.          dst3=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  96.   
  97.    
  98.   
  99. //为各个ROI分配内存  
  100.   
  101.          imgroi1=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);  
  102.   
  103.          imgroi2=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);  
  104.   
  105.          imgroi3=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);  
  106.   
  107.          roidark=cvCreateImage(cvSize(block,block),IPL_DEPTH_8U,1);  
  108.   
  109.    
  110.   
  111. //为j1 j2 j3分配大小  
  112.   
  113.          j1=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  114.   
  115.          j2=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  116.   
  117.          j3=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  118.   
  119.    
  120.   
  121. //为暗原色先验指针分配大小  
  122.   
  123.          dark_channel=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  124.   
  125. //为透射率指针分配大小  
  126.   
  127.          toushelv=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);  
  128.   
  129. //dst分配大小  
  130.   
  131.          dst=cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,3);  
  132.   
  133. //将原彩色图像分离成三通道  
  134.   
  135.          cvSplit(src,dst1,dst2,dst3,NULL);  
  136.   
  137. //求暗原色  
  138.   
  139.          ROI_rect.width=block;  
  140.   
  141.          ROI_rect.height=block;  
  142.   
  143.          ROI_rect.x=0;  
  144.   
  145.          ROI_rect.y=0;  
  146.   
  147.    
  148.   
  149.    
  150.   
  151.          int i;  
  152.   
  153.          int j;  
  154.   
  155.          double min1=0;  
  156.   
  157.          double max1=0;  
  158.   
  159.          double min2=0;  
  160.   
  161.          double max2=0;  
  162.   
  163.          double min3=0;  
  164.   
  165.          double max3=0;  
  166.   
  167.          double min=0;  
  168.   
  169.          CvScalar value;  
  170.   
  171.          for(i=0;i<src->width/block;i++)  
  172.   
  173.          {        for(j=0;j<src->height/block;j++)  
  174.   
  175.                    {  
  176.   
  177.                             //分别计算三个通道内ROI的最小值  
  178.   
  179.                             cvSetImageROI(dst1,ROI_rect);  
  180.   
  181.                             cvCopy(dst1,imgroi1,NULL);  
  182.   
  183.                             cvMinMaxLoc(imgroi1,&min1,&max1,NULL,NULL);  
  184.   
  185.                             cvSetImageROI(dst2,ROI_rect);  
  186.   
  187.                             cvCopy(dst2,imgroi2,NULL);  
  188.   
  189.                             cvMinMaxLoc(imgroi2,&min2,&max2,NULL,NULL);  
  190.   
  191.                             cvSetImageROI(dst3,ROI_rect);  
  192.   
  193.                             cvCopy(dst3,imgroi3,NULL);  
  194.   
  195.                             cvMinMaxLoc(imgroi3,&min3,&max3,NULL,NULL);  
  196.   
  197.                             //求三个通道内最小值的最小值  
  198.   
  199.                             if(min1<min2)  
  200.   
  201.                                      min=min1;  
  202.   
  203.                             else  
  204.   
  205.                                      min=min2;  
  206.   
  207.                             if(min>min3)  
  208.   
  209.                                      min=min3;//min为这个ROI中暗原色  
  210.   
  211.                             value=cvScalar(min,min,min,min);//min放在value中  
  212.   
  213.                             //min赋予dark_channel中相应的ROI  
  214.   
  215.                             cvSetImageROI(dark_channel,ROI_rect);  
  216.   
  217.                             cvSet(roidark,value,NULL);  
  218.   
  219.                             cvCopy(roidark,dark_channel,NULL);  
  220.   
  221.                             //释放各个ROI  
  222.   
  223.                             cvResetImageROI(dst1);  
  224.   
  225.                             cvResetImageROI(dst2);  
  226.   
  227.                             cvResetImageROI(dst3);  
  228.   
  229.                             cvResetImageROI(dark_channel);  
  230.   
  231.                             //转入下一个ROI  
  232.   
  233.                             ROI_rect.x=block*i;  
  234.   
  235.                             ROI_rect.y=block*j;  
  236.   
  237.                    }  
  238.   
  239.          }  
  240.   
  241.          //保存暗原色先验的图像  
  242.   
  243.          cvSaveImage("f:/dark_channel_prior.jpg",dark_channel);  
  244.   
  245. //利用得到的暗原色先验dark_channel_prior.jpg求大气光强  
  246.   
  247.          double min_dark;  
  248.   
  249.          double max_dark;  
  250.   
  251.          CvPoint min_loc;  
  252.   
  253.          CvPoint max_loc;//max_loc是暗原色先验最亮一小块的原坐标  
  254.   
  255.          cvMinMaxLoc(dark_channel,&min_dark,&max_dark,&min_loc,&max_loc,NULL);  
  256.   
  257.          cout<<max_loc.x<<" "<<max_loc.y<<endl;  
  258.   
  259.          ROI_rect.x=max_loc.x;  
  260.   
  261.          ROI_rect.y=max_loc.y;  
  262.   
  263.          double A_dst1;//定义大气光成分的估计值  
  264.   
  265.          double dst1_min;  
  266.   
  267.          double A_dst2;  
  268.   
  269.          double dst2_min;  
  270.   
  271.          double A_dst3;  
  272.   
  273.          double dst3_min;  
  274.   
  275.          cvSetImageROI(dst1,ROI_rect);  
  276.   
  277. //按照论文方法求大气光强估计值  
  278.   
  279.          cvCopy(dst1,imgroi1,NULL);  
  280.   
  281.          cvMinMaxLoc(imgroi1,&dst1_min,&A_dst1,NULL,NULL);  
  282.   
  283.          cvSetImageROI(dst2,ROI_rect);  
  284.   
  285.          cvCopy(dst2,imgroi2,NULL);  
  286.   
  287.          cvMinMaxLoc(imgroi2,&dst2_min,&A_dst2,NULL,NULL);  
  288.   
  289.          cvSetImageROI(dst3,ROI_rect);  
  290.   
  291.          cvCopy(dst3,imgroi3,NULL);  
  292.   
  293.          cvMinMaxLoc(imgroi3,&dst3_min,&A_dst3,NULL,NULL);  
  294.   
  295.          cout<<A_dst1<<" "<<A_dst2<<" "<<A_dst3<<endl;//这三值为大气光强度估计值  
  296.   
  297. //求透射率  
  298.   
  299.          int k;  
  300.   
  301.          int l;  
  302.   
  303.          CvScalar m;  
  304.   
  305.          CvScalar n;//暗原色先验各元素值  
  306.   
  307.    
  308.   
  309.          for(k=0;k<src->height;k++)  
  310.   
  311.          {  
  312.   
  313.                    for(l=0;l<src->width;l++)  
  314.   
  315.                    {  
  316.   
  317.                             m=cvGet2D(dark_channel,k,l);  
  318.   
  319.                             n=cvScalar(255-w*m.val[0]);  
  320.   
  321.                             //w目的是保留一部分的雾,使图像看起来真实些  
  322.   
  323.                             cvSet2D(toushelv,k,l,n);  
  324.   
  325.                    }  
  326.   
  327.          }  
  328.   
  329.          cvSaveImage("f:/toushelv.jpg",toushelv);  
  330.   
  331.    
  332.   
  333. //求无雾图像  
  334.   
  335.          int p,q;  
  336.   
  337.          double tx;  
  338.   
  339.          double jj1,jj2,jj3;  
  340.   
  341.          CvScalar ix,jx;  
  342.   
  343.          for(p=0;p<src->height;p++)  
  344.   
  345.          {  
  346.   
  347.                    for(q=0;q<src->width;q++)  
  348.   
  349.                    {  
  350.   
  351.                             tx=cvGetReal2D(toushelv,p,q);  
  352.   
  353.                             tx=tx/255;  
  354.   
  355.                             if(tx<0.1)  
  356.   
  357.                                      tx=0.1;  
  358.   
  359.                             ix=cvGet2D(src,p,q);  
  360.   
  361.                             jj1=(ix.val[0]-A_dst1)/tx+A_dst1;//根据雾产生模型运算,还原出无雾图像  
  362.   
  363.                             jj2=(ix.val[1]-A_dst2)/tx+A_dst2;  
  364.   
  365.                             jj3=(ix.val[2]-A_dst3)/tx+A_dst3;  
  366.   
  367.                             jx=cvScalar(jj1,jj2,jj3,0.0);  
  368.   
  369.                             cvSet2D(dst,p,q,jx);  
  370.   
  371.                    }  
  372.   
  373.          }  
  374.   
  375.          cvSaveImage("f:/removed_haze.jpg",dst);  
  376.   
  377.    
  378.   
  379. //释放指针  
  380.   
  381.          cvReleaseImage(&dst1);  
  382.   
  383.          cvReleaseImage(&dst2);  
  384.   
  385.          cvReleaseImage(&dst3);  
  386.   
  387.          cvReleaseImage(&imgroi1);  
  388.   
  389.          cvReleaseImage(&imgroi2);  
  390.   
  391.          cvReleaseImage(&imgroi3);  
  392.   
  393.          cvReleaseImage(&roidark);  
  394.   
  395.          cvReleaseImage(&dark_channel);  
  396.   
  397.          cvReleaseImage(&toushelv);  
  398.   
  399.          cvReleaseImage(&j1);  
  400.   
  401.          cvReleaseImage(&j2);  
  402.   
  403.          cvReleaseImage(&j3);  
  404.   
  405.          return dst;  
  406.   
  407. }  
  408.   
  409.    
  410.   
  411. void on_trackbar1(int h)  
  412.   
  413. {  
  414.   
  415.          dst=quw(src,block,w);  
  416.   
  417.          cvShowImage("目的图像",dst);  
  418.   
  419. //      cvWaitKey(0);  
  420.   
  421. }  
  422.   
  423. void on_trackbar2(int h)  
  424.   
  425. {  
  426.   
  427.    
  428.   
  429.          w=(double)w1/100;  
  430.   
  431.          dst=quw(src,block,w);  
  432.   
  433.          cvShowImage("目的图像",dst);  
  434.   
  435. //      cvWaitKey(0);  
  436.   
  437. }  
  438.   
  439. //主函数如下  
  440.   
  441. void main()  
  442.   
  443. {  
  444.   
  445.          //打开图像  
  446.   
  447.          src=cvLoadImage("8.jpg",-1);  
  448.   
  449.          //创造窗口  
  450.   
  451.          cvNamedWindow("有雾图像",CV_WINDOW_AUTOSIZE);  
  452.   
  453.          cvShowImage("有雾图像",src);  
  454.   
  455.          cvNamedWindow("目的图像",CV_WINDOW_AUTOSIZE);  
  456.   
  457.          cvCreateTrackbar(tbarname1, "目的图像", &block, 15, on_trackbar1);  
  458.   
  459.          cvCreateTrackbar(tbarname2, "目的图像", &w1, 100, on_trackbar2);  
  460.   
  461.          cvWaitKey(0);  
  462.   
  463.          cvReleaseImage(&src);  
  464.   
  465.          cvReleaseImage(&dst);  
  466.   
  467. }  


 

去雾matlab代码:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:24px;">  function q = guidedfilter(I, p, r, eps)  
  2.   %   GUIDEDFILTER   O(1) time implementation of guided filter.  
  3.   %  
  4.   %   - guidance image: I (should be a gray-scale/single channel image)  
  5.   %   - filtering input image: p (should be a gray-scale/single channel image)  
  6.   %   - local window radius: r  
  7.   %   - regularization parameter: eps  
  8.   
  9.   [hei, wid] = size(I);  
  10.   N = boxfilter(ones(hei, wid), r); % the size of each local patch; N=(2r+1)^2 except for boundary pixels.  
  11.   
  12.   % imwrite(uint8(N), 'N.jpg');  
  13.   % figure,imshow(N,[]),title('N');  
  14.     
  15.   
  16.   mean_I = boxfilter(I, r) ./ N;  
  17.   mean_p = boxfilter(p, r) ./ N;  
  18.   mean_Ip = boxfilter(I.*p, r) ./ N;  
  19.   cov_Ip = mean_Ip - mean_I .* mean_p; % this is the covariance of (I, p) in each local patch.  
  20.   
  21.   mean_II = boxfilter(I.*I, r) ./ N;  
  22.   var_I = mean_II - mean_I .* mean_I;  
  23.   
  24.   a = cov_Ip ./ (var_I + eps); % Eqn. (5) in the paper;  
  25.   b = mean_p - a .* mean_I; % Eqn. (6) in the paper;  
  26.   
  27.   mean_a = boxfilter(a, r) ./ N;  
  28.   mean_b = boxfilter(b, r) ./ N;  
  29.   
  30.   q = mean_a .* I + mean_b; % Eqn. (8) in the paper;  
  31.   end</span>  


去雾代码2:

 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "stdafx.h"  
  2. #include <opencv2\opencv.hpp>   
  3. #include "cv.h"  
  4. #include <cxcore.h>  
  5. #include "highgui.h"  
  6. #include <windows.h>  
  7. #include <math.h>  
  8. using namespace cv;  
  9. using namespace std;   
  10.   
  11. //求三个通道中最小值的最小值时调用的函数  
  12. double min(double b,double g, double r)  
  13. {  
  14.     double result = b;  
  15.     if(result>g)  
  16.         result = g;  
  17.     if(result>r)  
  18.         result = r;  
  19.     return result;  
  20. };  
  21. double max(double a,double b)  
  22. {  
  23.     double MAX;  
  24.     if (a<b)  
  25.         MAX = b;  
  26.     else  
  27.         MAX = a;  
  28.     return MAX;  
  29. };  
  30. double min2(double a,double b)//比较两个数值中的最小值并返回  
  31. {  
  32.     double MIN;  
  33.     if (a<b)  
  34.         MIN = a;  
  35.     else  
  36.         MIN = b;  
  37.     return MIN;  
  38. };  
  39. //这个函数相当于darkchannel的功能,但在padarray时。使用的是将边缘像素复制的方法,不是matlab的将边缘处镜像复制,计算出darkchannel后有计算了最大值A  
  40. double doDarkChannel(IplImage* in,int patchsize)  
  41. {  
  42.       
  43.     int height,width,step,channels;//图像的宽,高,等信息,height,width是输入图像的尺寸,也是输出图像的尺寸,step是输出图像jout的(j对应matlab代码中的darkchannel的输出图像J)  
  44.     int i,j,k;//用于循环的变量  
  45.     uchar *data2;//输出的结果图像的指针  
  46.     height = in->height;//获取输入图像的宽高等信息  
  47.     width = in->width;  
  48.     int patch = patchsize/2;//图像要延拓的边缘的宽度  
  49.     IplImage* mout=cvCreateImage(cvSize(in->width+patchsize,in->height+patchsize),in->depth,in->nChannels);   //存放图像被镜像延拓后图像的空图像  
  50.     cvCopyMakeBorder(in,mout,cvPoint(patch,patch),IPL_BORDER_REPLICATE);//这个函数相当于padarray,mout中存放padarrry后的图像  
  51.     IplImage* jout = cvCreateImage(cvSize(in->width,in->height),in->depth,1);//darkchannel 的输出结果,J  
  52.       
  53.     step = jout->widthStep/sizeof(uchar);//step是单通道输出图像jout的widthstep  
  54.     data2 = (uchar *)jout->imageData;//指向输出图像的数据头  
  55.   
  56.     for(i=0;i<height;i++)  
  57.         {  
  58.        for(j=0;j<width;j++)     
  59.           {   
  60.                 cvSetImageROI(mout, cvRect(j, i, patchsize, patchsize));//操作输入图像的(i,j)点处patchsize大小的图像块  
  61.                 IplImage*  patch_out=cvCreateImage(cvSize(patchsize,patchsize),in->depth,in->nChannels);//存储三通道图像块的临时内存区,循环体里用到的内存区域再循环体里申请,在循环体里释放  
  62.                 cvCopy(mout,patch_out);//将patchsize大小的图像块存入临时图像块patch_out  
  63.                 cvResetImageROI(mout); //释放mout  
  64.   
  65.                 //以下内容是利用cnMinMaxloc分别计算三个通道中的最小值  
  66.                 double MinValue;  
  67.                 double MaxValue;  
  68.                 double B_Min,G_Min,R_Min;  
  69.                 CvPoint MinLocation;  
  70.                 CvPoint MaxLocation;  
  71.                 cvSetImageCOI(patch_out,1);  
  72.                 cvMinMaxLoc(patch_out,& MinValue,& MaxValue,& MinLocation,& MaxLocation);  
  73.                 B_Min = MinValue;  
  74.                 cvSetImageCOI(patch_out,2);  
  75.                 cvMinMaxLoc(patch_out,& MinValue,& MaxValue,& MinLocation,& MaxLocation);  
  76.                 G_Min = MinValue;  
  77.                 cvSetImageCOI(patch_out,3);  
  78.                 cvMinMaxLoc(patch_out,& MinValue,& MaxValue,& MinLocation,& MaxLocation);  
  79.                 R_Min = MinValue;  
  80.                 int dark_point = (int)min(B_Min,G_Min,R_Min);  
  81.                 //三个通道的最小值都已经被分别提取出来了  
  82.                 data2[i*step+j] = dark_point;//step 是jout的step,是单通道的  
  83.                 cvReleaseImage(&patch_out);               
  84.             };  
  85.     };  
  86.     double MinValue;  
  87.     double MaxValue;  
  88.     double B_Min,G_Min,R_Min;  
  89.     CvPoint MinLocation;  
  90.     CvPoint MaxLocation;  
  91.     cvSetImageCOI(jout,1);  
  92.     cvMinMaxLoc(jout,& MinValue,& MaxValue,& MinLocation,& MaxLocation);  
  93.     cvReleaseImage(&mout);  
  94.     cout<<"计算暗通道函数运行成功"<<"\n";  
  95.     return MaxValue;  
  96.   
  97. };  
  98. //该函数的作用相当于matlab代码中求取三个通道中最小值,然后以最小值组成一幅灰度图  
  99. IplImage* doMinChannel(IplImage* in)  
  100. {  
  101.     IplImage* b = cvCreateImage(cvSize(in->width,in->height),in->depth,1);  
  102.     IplImage* g = cvCreateImage(cvSize(in->width,in->height),in->depth,1);  
  103.     IplImage* r = cvCreateImage(cvSize(in->width,in->height),in->depth,1);//创建保存读入图像三个通道的的内存区域  
  104.     IplImage* w = cvCreateImage(cvSize(in->width,in->height),in->depth,1);//创建保存输出图像的内存区域(三个通道中最小值组成的一幅灰度图)  
  105.     cvSetImageCOI(in,1);  
  106.     cvCopy(in,b);  
  107.     cvSetImageCOI(in,2);  
  108.     cvCopy(in,g);  
  109.     cvSetImageCOI(in,3);  
  110.     cvCopy(in,r);//将三个通道的的值分别存入r,g,b三块内存区域中  
  111.   
  112.     //cvSplit(src,dst1,dst2,dst3,NULL);  
  113.   
  114.     int height = in->height;//获取输入图像的宽高等信息  
  115.     int width = in->width;  
  116.     int i,j,k;//用于循环的变量  
  117.     uchar *data_w;  
  118.     uchar *data_b;  
  119.     uchar *data_g;  
  120.     uchar *data_r;  
  121.     int step = b->widthStep/sizeof(uchar);  
  122.     data_w = (uchar *)w->imageData;//指向输出图像的数据头  
  123.     data_b = (uchar *)b->imageData;//指向输出图像的数据头  
  124.     data_g = (uchar *)g->imageData;//指向输出图像的数据头  
  125.     data_r = (uchar *)r->imageData;//指向输出图像的数据头  
  126.     for(i=0;i<height;i++)  
  127.         {  
  128.        for(j=0;j<width;j++)     
  129.           {   
  130.               double b,g,r;  
  131.               int MIN;//b,g,r三个通道的最小值  
  132.               b = data_b[i*step+j];  
  133.               g = data_g[i*step+j];  
  134.               r = data_r[i*step+j];  
  135.               MIN = (int)min(b,g,r);  
  136.               data_w[i*step+j] = MIN;  
  137.           };  
  138.         };  
  139.     cout<<"计算三个通道最小值并组成一幅新灰度图的函数运行成功"<<"\n";//表示该函数运行成功  
  140.     return w;  
  141. }   ;  
  142. IplImage* doCalculateV(IplImage* w,IplImage* diff,IplImage* smooth)  
  143. {  
  144.     IplImage* b = cvCreateImage(cvSize(w->width,w->height),w->depth,1);  
  145.     IplImage* v = cvCreateImage(cvSize(w->width,w->height),w->depth,1);  
  146.     int height = w->height;//获取输入图像的宽高等信息  
  147.     int width = w->width;  
  148.     int i,j,k;//用于循环的变量  
  149.     uchar *data_w;  
  150.     uchar *data_diff;  
  151.     uchar *data_v;  
  152.     uchar *data_b;  
  153.     uchar *data_smooth;  
  154.     int step = w->widthStep/sizeof(uchar);  
  155.     data_w = (uchar *)w->imageData;//指向输出图像的数据头  
  156.     data_diff = (uchar *)diff->imageData;//指向输出图像的数据头  
  157.     data_v = (uchar *)v->imageData;//指向输出图像的数据头  
  158.     data_b = (uchar *)b->imageData;//指向输出图像的数据头  
  159.     data_smooth = (uchar *)smooth->imageData;  
  160.     for(i=0;i<height;i++)  
  161.         {  
  162.        for(j=0;j<width;j++)     
  163.           {   
  164.               double W;  
  165.               double DIFF;  
  166.               double B;  
  167.               double SMOOTH;  
  168.               double p = 0.78;//p = 0.78  
  169.               double MIN,MAX;  
  170.               W = data_w[i*step+j];  
  171.               DIFF = data_diff[i*step+j];  
  172.               SMOOTH = data_smooth[i*step+j];  
  173.               B = W-DIFF;  
  174.               MIN = min2(B,SMOOTH);  
  175.               MAX = max(MIN,0);  
  176.               data_v[i*step+j] = p*MAX;  
  177.           };  
  178.         };  
  179.     cout<<"计算v函数运行成功"<<"\n";//表示该函数运行成功  
  180.     return v;  
  181. };  
  182. //计算最终的去雾图像的函数  
  183. IplImage* doFinally(IplImage* in,IplImage* v,double A)  
  184. {  
  185.     IplImage* b = cvCreateImage(cvSize(in->width,in->height),in->depth,1);  
  186.     IplImage* g = cvCreateImage(cvSize(in->width,in->height),in->depth,1);  
  187.     IplImage* r = cvCreateImage(cvSize(in->width,in->height),in->depth,1);  
  188.     IplImage* result = cvCreateImage(cvSize(in->width,in->height),in->depth,3);//创建存储输出图像的内存区域  
  189.     int height = in->height;//获取输入图像的宽高等信息  
  190.     int width = in->width;  
  191.     int i,j;//用于循环的变量  
  192.     cvSetImageCOI(in,1);  
  193.     cvCopy(in,b);  
  194.     cvSetImageCOI(in,2);  
  195.     cvCopy(in,g);  
  196.     cvSetImageCOI(in,3);  
  197.     cvCopy(in,r);//将三个通道的的值分别存入r,g,b三块内存区域中  
  198.     //cvSplit(in,b,g,r,NULL);//将图像拆分为三个通道  
  199.     uchar *data_b;  
  200.     uchar *data_g;  
  201.     uchar *data_r;  
  202.     uchar *data_v;  
  203.     int step = b->widthStep/sizeof(uchar);  
  204.     //data_w = (uchar *)w->imageData;//指向输出图像的数据头  
  205.     data_b = (uchar *)b->imageData;//指向蓝色通道的数据头  
  206.     data_g = (uchar *)g->imageData;//指向绿色通道的数据头  
  207.     data_r = (uchar *)r->imageData;//指向红色通道的数据头  
  208.     data_v = (uchar *)v->imageData;  
  209.     //计算蓝色通道的去雾结果  
  210.     for(i=0;i<height;i++)  
  211.         {  
  212.        for(j=0;j<width;j++)     
  213.           {   
  214.               double B,G,R,V,VAB,VAG,VAR;  
  215.               V = data_v[i*step+j];  
  216.               B = data_b[i*step+j];  
  217.               VAB = fabs(B-V)/(fabs(1-V/A));   //会有一些值大于256,需要进行归一化  
  218.               if(VAB>255)  
  219.                   VAB = 255;  
  220.               else  
  221.                   VAB = VAB;  
  222.               data_b[i*step+j] = VAB;  
  223.               G = data_g[i*step+j];  
  224.               VAG = fabs(G-V)/(fabs(1-V/A));  
  225.               if(VAG>255)  
  226.                   VAG = 255;  
  227.               else  
  228.                   VAG = VAG;  
  229.               data_g[i*step+j] = VAG;  
  230.               R = data_r[i*step+j];  
  231.               VAR = fabs(R-V)/(fabs(1-V/A));  
  232.               if(VAR>255)  
  233.                   VAR = 255;  
  234.               else  
  235.                   VAR = VAR;  
  236.               data_r[i*step+j] = VAR;  
  237.           };  
  238.         };  
  239.     cvMerge(b,g,r,NULL,result);//这个函数可能也有问题~  
  240.     cout<<"最终去雾算法运行成功"<<"\n";//表示该函数运行成功  
  241.     return result;  
  242.   
  243. }  
  244.   
  245. int main(int argc, char** argv)  
  246. {   
  247.     cvNamedWindow("Source Image");  
  248.     cvNamedWindow("Result Image");  
  249.     IplImage* image = cvLoadImage("D:/4.bmp",1);  //input a image,0表示以灰度图形式读入图像,-1表示以图像自身真实通道数读入图像,1表示以三通道读入图像  
  250.                                                     //此处可改成自己的图片路径  
  251.     cvShowImage("Source Image",image);//显示源图像  
  252.     int patchsize = 20;  
  253.     //IplImage* out = doDarkChannel(image,patchsize);//不能直接将返回的图像数据赋给一个未指定大小的指针,  
  254.     IplImage* out = cvCreateImage(cvSize(image->width,image->height),image->depth,3);//创建存储输出图像的内存区域  
  255.     IplImage* w = cvCreateImage(cvSize(image->width,image->height),image->depth,1);//创建存储输出图像的内存区域  
  256.     //cvCopy(doDarkChannel(image,patchsize),out);//将patchsize大小的图像块存入临时图像块patch_out  
  257.     IplImage* smooth = cvCreateImage(cvSize(image->width,image->height),image->depth,1);//创建存储输出图像的内存区域  
  258.     IplImage* diff = cvCreateImage(cvSize(image->width,image->height),image->depth,1);//存储w与I_smooth差值绝对值的的内存区域  
  259.     IplImage* v = cvCreateImage(cvSize(image->width,image->height),image->depth,1);//存储w与I_smooth差值绝对值的的内存区域  
  260.     int A_MAX = doDarkChannel(image,patchsize);//求取暗通道的最大值,A_MAX相当于Matlab中的A,传入doFinally  
  261.     cvCopy(doMinChannel(image),w);//计算三个通道的最小值并以最小值组成一副灰度图,进行下一步高斯平滑  
  262.     //w计算没问题  
  263.   
  264.     cvSaveImage("D://result//w.bmp",w);  
  265.   
  266.     cvSmooth(w,smooth,CV_GAUSSIAN,39,39,4.5,4.5);//39x39;不使用相关而使用卷积进行计算,将边界点复制得到拓展边界  
  267.       
  268.     cvSaveImage("D://result//smooth.bmp",smooth);  
  269.   
  270.     cvAbsDiff(smooth,w,diff);  
  271.     //diff有问题,应该是由于smooth导致的  
  272.     cvSaveImage("D://result//diff.bmp",diff);  
  273.   
  274.     cvCopy(doCalculateV(w,diff,smooth),v);//计算v,v的含义从matlab代码中可找到,v传入doFinally进行最终的结果计算  
  275.     //v有问题;由于smooth有问题,w没问题,diff有问题,导致v有问题  
  276.     cvSaveImage("D://result//v.bmp",v);  
  277.     cvCopy(doFinally(image,v,A_MAX),out);//计算最终的去雾结果的函数的调用  
  278.     //cvSaveImage("D://v.bmp",v);//测试能否顺利产生图像v的代码  
  279.     cout<<"A_MAX="<<A_MAX<<"\n";  
  280.   
  281.     cvSaveImage("D://result//finally.bmp",out);  
  282.   
  283.     cvShowImage("Result Image",out);//imshow the result  
  284.     cvWaitKey(0);  
  285.     cvReleaseImage(&image);//release the storage space  
  286.     cvReleaseImage(&out);//release the storage space  
  287.     cvReleaseImage(&w);//release the storage space  
  288.     cvReleaseImage(&smooth);//release the storage space  
  289.     cvReleaseImage(&diff);//release the storage space  
  290.     cvReleaseImage(&v);//release the storage space  
  291.     cvDestroyWindow("Source Image");    
  292.     cvDestroyWindow("Result Image");  
  293.     //system("pause"); //避免一闪而过  
  294.     return 0;  
  295. }  


 

 

 

 

 

 

 

参考文献:

http://www.tuicool.com/articles/Mv2iiu

http://blog.csdn.net/holybang/article/details/28093305

http://www.tuicool.com/articles/MJZr2e

http://blog.sina.com.cn/s/blog_4d8730df0100m8lz.html

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于导向滤波通道去雾算法一种常用的图像去方法,它能够有效地消除图像中的霾、提高图像的清晰度和对比度。 该算法的核心理念是,影响图像霾的主要因素是图像的深度值和的密度。因此,通过计算图像在一些已知区域的最小值,可以得到图像的通道信息,根据这个信息就可以估计出图像中的的密度。接着,将这些估计值作为导向滤波器的引导图像,对原图像进行滤波,即可去除图像中的。 在MATLAB中,实现基于导向滤波通道去雾算法,主要需要进行以下步骤: 1. 读入图像。可通过imread函数读入图像文件,并使用im2double将图像转换成双精度浮点型。 2. 计算通道。使用min滤波器计算每个像素在整张图像中的最小值,得到通道信息。 3. 估计大气光。利用通道信息可以估计出大气光的值,即图像中最亮的区域的像素值。 4. 估计的密度。根据大气光的值,通过公式来估计图像中每个像素处的的密度。 5. 计算透射率。利用估计出的的密度和大气光值,可以计算出每个像素处的透射率。 6. 使用导向滤波器进行滤波。将估计出的透射率作为引导图像,利用MATLAB内置函数进行导向滤波操作。 7. 输出处理后的图像。将滤波后的结果进行输出保存,或直接显示在屏幕上。 总的来说,基于导向滤波通道去雾算法一种有效的图像处理方法,它能够较为完美地去除图像中的霾,并提高图像的清晰度和对比度,具有很高的工程应用价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值