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 }
参考链接: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 }
https://blog.csdn.net/qq_34784753/article/details/70229009?locationNum=12&fps=1