4.5.实例应用

4.5.1 导向滤波

导向滤波能实现:双边滤波的边缘平滑;在检测到边缘附近

应用:图像增强、HDR压缩、图像抠图以及图像去雾等

 1 #include <iostream>  
 2 #include "opencv2/core/core.hpp"    
 3 #include "opencv2/highgui/highgui.hpp"    
 4 #include "opencv2/imgproc/imgproc.hpp"      
 5 using namespace std;  
 6 using namespace cv;   
 7 // 导向滤波器 
 8 cv::Mat guidedfilter( Mat &srcImage, Mat &srcClone, int r, double eps )   
 9 {  
10   // 转换源图像信息
11   srcImage.convertTo(srcImage, CV_64FC1);      
12   srcClone.convertTo(srcClone, CV_64FC1);   
13   int nRows = srcImage.rows;  
14   int nCols = srcImage.cols;   
15   cv::Mat boxResult; 
16   // 步骤一: 计算均值
17   cv::boxFilter(cv::Mat::ones(nRows, nCols, srcImage.type()),
18       boxResult, CV_64FC1, cv::Size(r, r));  
19   // 生成导向均值mean_I    
20   cv::Mat mean_I;  
21   cv::boxFilter(srcImage, mean_I, CV_64FC1, cv::Size(r, r));   
22   // 生成原始均值mean_p   
23   cv::Mat mean_p;  
24   cv::boxFilter(srcClone, mean_p, CV_64FC1, cv::Size(r, r)); 
25   // 生成互相关均值mean_Ip 
26   cv::Mat mean_Ip;  
27   cv::boxFilter(srcImage.mul(srcClone), mean_Ip, 
28       CV_64FC1, cv::Size(r, r));   
29   cv::Mat cov_Ip = mean_Ip - mean_I.mul(mean_p); 
30   // 生成自相关均值mean_II 
31   cv::Mat mean_II;  
32   cv::boxFilter(srcImage.mul(srcImage), mean_II, CV_64FC1, cv::Size(r, r)); 
33   // 步骤二:计算相关系数   
34   cv::Mat var_I = mean_II - mean_I.mul(mean_I); 
35   cv::Mat var_Ip = mean_Ip - mean_I.mul(mean_p); 
36   // 步骤三:计算参数系数a,b 
37   cv::Mat a = cov_Ip/(var_I + eps);    
38   cv::Mat b = mean_p - a.mul(mean_I);  
39   // 步骤四:计算系数a,b均值    
40   cv::Mat mean_a;  
41   cv::boxFilter(a, mean_a, CV_64FC1, cv::Size(r, r));  
42   mean_a = mean_a / boxResult;     
43   cv::Mat mean_b;  
44   cv::boxFilter(b, mean_b, CV_64FC1, cv::Size(r, r));  
45   mean_b = mean_b / boxResult;   
46   //步骤五:生成输出矩阵 
47   cv::Mat resultMat = mean_a.mul(srcImage) + mean_b;  
48   return resultMat;  
49 }    
50 int main()  
51 {    
52     cv::Mat srcImage = cv::imread("..\\images\\flower3.jpg");
53     if(srcImage.empty())
54           return-1;
55     cv::Mat srcGray(srcImage.size(),CV_8UC1);  
56     cvtColor(srcImage,srcGray,CV_BGR2GRAY); 
57     // 通道分离 
58     vector<Mat> vSrcImage, vResultImage;  
59     split(srcImage,vSrcImage);
60     Mat resultMat;      
61     for(int i=0; i < 3; i++)    
62     {    
63         // 分通道转换成浮点型数据
64         Mat tempImage ; 
65         vSrcImage[i].convertTo(tempImage, CV_64FC1,1.0/255.0);  
66         Mat p = tempImage.clone();
67         // 分别进行导向滤波       
68         Mat resultImage = guidedfilter(tempImage, p, 4, 0.01);  
69         vResultImage.push_back(resultImage);        
70     } 
71     // 通道结果合并   
72     merge(vResultImage,resultMat);  
73     cv::imshow("srcImage", srcImage);  
74     cv::imshow("resultMat", resultMat);  
75     cv::waitKey(0);    
76     return 0;  
77 }
View Code

参考链接:https://blog.csdn.net/gone_huilin/article/details/53223488

 1 //////https://blog.csdn.net/qq_34784753/article/details/70229009?locationNum=12&fps=1
 2 #include <iostream>
 3 #include <opencv2\core\core.hpp>
 4 #include <opencv2\highgui\highgui.hpp>
 5 #include <opencv2\imgproc\imgproc.hpp>
 6 
 7 using namespace cv;
 8 using namespace std;
 9 
10 //导向滤波器
11 Mat guidedfilter(Mat &srcImage, Mat &srcClone, int r, double eps);
12 
13 int main()
14 {
15     Mat srcImage = imread("D:\\小狗狗.jpg");
16     if (srcImage.empty())
17     {
18         cout << "读入图片错误!" << endl;
19         system("pause");
20         return -1;
21     }
22     //进行通道分离
23     //vector<Mat>vSrcImage, vResultImage;
24     Mat vSrcImage[3];
25     Mat vResultImage[3];
26     split(srcImage, vSrcImage);
27     Mat resultMat;
28     for (int i = 0; i < 3; i++)
29     {
30         //分通道转换成浮点型数据
31         Mat tempImage;
32         vSrcImage[i].convertTo(tempImage, CV_64FC1, 1.0 / 255.0);
33         Mat p = tempImage.clone();
34         //分别进行导向滤波
35         Mat resultImage = guidedfilter(tempImage, p, 4, 0.01);
36         //vResultImage.push_back(resultImage);
37         vResultImage[i] = resultImage.clone();
38     }
39     //通道结果合并
40     //merge(vResultImage, resultMat);
41     merge(vResultImage, 3, resultMat);
42     imshow("原图像", srcImage);
43     imshow("导向滤波后图像", resultMat);
44     waitKey(0);
45     return 0;
46 }
47 
48 Mat guidedfilter(Mat &srcImage, Mat &srcClone, int r, double eps)
49 {
50     //转换源图像信息
51     srcImage.convertTo(srcImage, CV_64FC1);
52     srcClone.convertTo(srcClone, CV_64FC1);
53     int NumRows = srcImage.rows;
54     int NumCols = srcImage.cols;
55     Mat boxResult;
56 
57     //下面按照步骤进行导向滤波操作
58     /////////////////////////////////////////////////////////////
59     //步骤一:计算均值
60     boxFilter(Mat::ones(NumRows, NumCols, srcImage.type()),
61         boxResult, CV_64FC1, Size(r, r));
62     //生成导向均值mean_I
63     Mat mean_I;
64     boxFilter(srcImage, mean_I, CV_64FC1, Size(r, r));
65     //生成原始均值mean_P
66     Mat mean_P;
67     boxFilter(srcClone, mean_P, CV_64FC1, Size(r, r));
68     //生成互相关均值mean_IP
69     Mat mean_IP;
70     boxFilter(srcImage.mul(srcClone), mean_IP,
71         CV_64FC1, Size(r, r));
72     Mat cov_IP = mean_IP - mean_I.mul(mean_P);
73     //生成自相关均值mean_II
74     Mat mean_II;
75     //应用盒滤波计算相关均值
76     boxFilter(srcImage.mul(srcImage), mean_II, CV_64FC1, Size(r, r));
77     //步骤二:计算相关系数
78     Mat var_I = mean_II - mean_I.mul(mean_I);
79     Mat var_IP = mean_IP - mean_I.mul(mean_P);
80     //步骤三:计算参数系数a,b
81     Mat a = cov_IP / (var_I + eps);
82     Mat b = mean_P = a.mul(mean_I);
83     //步骤四:计算系数a,b的均值
84     Mat mean_a;
85     boxFilter(a, mean_a, CV_64FC1, Size(r, r));
86     mean_a = mean_a / boxResult;
87     Mat mean_b;
88     boxFilter(b, mean_b, CV_64FC1, Size(r, r));
89     mean_b = mean_b / boxResult;
90     //步骤五:生成输出矩阵
91     Mat resultMat = mean_a.mul(srcImage) + mean_b;
92     return resultMat;
93 }
View Code

https://blog.csdn.net/qq_34784753/article/details/70229009?locationNum=12&fps=1

猜你喜欢

转载自www.cnblogs.com/thebreakofdawn/p/9502715.html
4.5