学习guide滤波算法
来源:互联网 发布:基于单片机的音乐盒 编辑:程序博客网 时间:2024/05/08 19:12
前几天,老大给分陪了新的项目,开始和同事做滤波增强。开始几天看了一点相对好的算法,包括双边滤波,还有一个基于SVM学习的滤波算法(具体名字忘记了),然后就是同事推荐的导向滤波,查了下,确实感觉不错,能够良好的保持边缘特性。
基本思想大致是这样的,通过函数上的某一点与其邻近部分的点成线性关系,一个复杂的函数就可以用很多局部的线性函数来表示,当需求该函数上某一点时,只需要计算包含该店的线性函数的值并做平均即可。这种模型在表示非解析函数上非常有用,同理我们可以认为图像是一个二维函数。
函数输入输出关系(二维窗口内),满足
q=aI+b 其中q是输出像素的值,I是输入像素的值。
梯度q=a*梯度I
这个公式解释了输出具有边缘保持效果的原因。
剩下的就是求线性函数系数的回归运算,即希望拟合值与真实值P之间的差距最小
E(a,b)=sum((aI+b-p))^2 + e*a^2)
p是待滤波图像并不像I可以是任意其他的图像。
最终求得系数为:
a=(1/|w| * sum (I*P)-u*P)/(var^2+e)
b=(mean(p)-a/u)
最终的输出q=mean(a)*mean(I)+mean(b)
|w|是窗口中像素的数量 var^2:方差 u:均值 mean(p)是滤波图像P在窗口中的均值
大体上就是不断计算,zai计算,求取均值,方差协方差等等吧
应项目需求,参考大神们的足迹,也实现了算法,要学的东西很多,希望毕业前做一个,记住一个,积累吧,还得学习编码。据说是 然要有梦想 万一实现了呢,逗比一下自己。
/************************************************************************* @Author : YG* @ Date : 2015/12/30* @ Email : 1851506****@163.com* function: 引导滤波* introduc:引导滤波是最近比较好的,前沿性的滤波方法,利用了线性模型,不仅能够平滑图像,而且保留了边缘特性,通过函数上一点与其领域部分点的线性关系,一个复杂的函数就可以用很多局部的线性函数来表示,当需求该函数上某一点的值时,只计算包含该点的线性函数的值并做平均即可,这种模型在表示解析函数上非常有效。e是尺度参数,平滑参数,为全局参数,大小影响整个分量的估计结果,尤其是细节比较丰富的图像。************************************************************************/#include "stdafx.h"#include "guilt_me.h"#include <iostream>#include <windows.h>using namespace std;using namespace cv;//灰度图处理/*Mat img_do(Mat &img){if (!img.data){cout << "no data of img1" << endl;}Mat img_gray(img.size(), CV_8UC1);cvtColor(img, img_gray, CV_BGR2GRAY);return img_gray;}*//************************************************************************//*调节半径r,回调 *//************************************************************************/void on_guilt_feliter(int, void*){vector<Mat> bgr_src, bgr_dst;split(img1, bgr_src);Mat dst_color;double time;time = (double)GetTickCount();Mat q;for (int i = 0; i < 3; i++){Mat I = img_Get(bgr_src[i]);Mat p = I.clone();q = guidedfilter(p, I, r, (double)e / 100);bgr_dst.push_back(q);}merge(bgr_dst, dst_color);imwrite("filtered.JPG", q * 255);time = 1000 * ((double)getTickCount() - time) / getTickFrequency();cout << endl << "Time of guided filter for runs: " << time << " milliseconds." << endl;imshow("效果图", dst_color);imwrite("result.jpg", dst_color * 255);waitKey(0);}/************************************************************************//* 调节参数e,进行回调*//************************************************************************/void on_guilt_feliter_e(int, void*){vector<Mat> bgr_src, bgr_dst;split(img1, bgr_src);Mat dst_color;double time;time = (double)GetTickCount();Mat q;for (int i = 0; i < 3; i++){Mat I = img_Get(bgr_src[i]);Mat p = I.clone();q = guidedfilter(p, I, r, (double)e / 100);bgr_dst.push_back(q);}merge(bgr_dst, dst_color);imwrite("filtered.JPG", q * 255);time = 1000 * ((double)getTickCount() - time) / getTickFrequency();cout << endl << "Time of guided filter for runs: " << time << " milliseconds." << endl;imshow("效果图", dst_color);imwrite("result.jpg", dst_color * 255);while (char(waitKey(1) != 'o')){}}/************************************************************************//* 无模板,自身为模板*//************************************************************************/void _no_model(){img1 = imread("1.jpg", 1);namedWindow("原始图");imshow("原始图", img1);namedWindow("效果图");createTrackbar("半径r:", "效果图", &r, 30, on_guilt_feliter);createTrackbar("参数e:", "效果图", &e, 1000, on_guilt_feliter_e);on_guilt_feliter(r, 0);on_guilt_feliter_e(e, 0);}/************************************************************************//*主函数入口 *//************************************************************************/int _tmain(int argc, _TCHAR* argv[]){_no_model();cout << "the programe is over!" << endl;return 0;}引导滤波的算法在下面
#include <opencv.hpp>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>using namespace std;using namespace cv;//声明全局变量int r = 16;int e = 1;//定义显示图像Mat img1, img2;Mat o_img;//调节滑块static void on_guilt_feliter(int, void*);static void on_guilt_feliter_e(int, void*);/************************************************************************//*获取图像,定义64深度图,进行乘积运算,防止过界 *//************************************************************************/Mat img_Get(Mat &a){int h = a.rows;int w = a.cols;Mat I(h, w, CV_64FC1);a.convertTo(I, CV_64FC1);for (int i = 0; i < h; i++){double *p = I.ptr<double>(i);for (int j = 0; j < w; j++){p[j] = p[j] / 255.0;}}return I;}/************************************************************************//* 统计sum*//************************************************************************/Mat calculate_Sum(Mat &img_Src, int rc){int h = img_Src.rows;int w = img_Src.cols;Mat img_Sum = img_Src.clone();if (rc == 1){for (int i = 1; i < h; i++){for (int j = 0; j < w; j++){img_Sum.at<double>(i, j) += img_Sum.at<double>(i - 1, j);}}}if (rc == 2){for (int i = 0; i < h; i++){for (int j = 1; j < w; j++){img_Sum.at<double>(i, j) += img_Sum.at<double>(i, j - 1);}}}return img_Sum;}/************************************************************************//*方框滤波函数调用,开源代码 *//************************************************************************/Mat boxfilter(Mat &img_Src, int r){int h = img_Src.rows;int w = img_Src.cols;Mat img_dst = Mat::zeros(h, w, CV_64FC1);Mat img_Sum = calculate_Sum(img_Src, 1);for (int i = 0; i < r + 1; i++){for (int j = 0; j < w; j++){img_dst.at<double>(i, j) = img_Sum.at<double>(i + r, j);}}for (int i = r + 1; i < h - r; i++){for (int j = 0; j < w; j++){img_dst.at<double>(i, j) = img_Sum.at<double>(i + r, j) - img_Sum.at<double>(i - r - 1, j);}}for (int i = h - r; i < h; i++){for (int j = 0; j < w; j++){img_dst.at<double>(i, j) = img_Sum.at<double>(h - 1, j) - img_Sum.at<double>(i - r - 1, j);}}img_Sum = calculate_Sum(img_dst, 2);for (int i = 0; i < h; i++){for (int j = 0; j < r + 1; j++){img_dst.at<double>(i, j) = img_Sum.at<double>(i, j + r);}}for (int i = 0; i < h; i++){for (int j = r + 1; j < w - r; j++){img_dst.at<double>(i, j) = img_Sum.at<double>(i, j + r) - img_Sum.at<double>(i, j - r - 1);}}for (int i = 0; i < h; i++){for (int j = w - r; j < w; j++){img_dst.at<double>(i, j) = img_Sum.at<double>(i, w - 1) - img_Sum.at<double>(i, j - r - 1);}}return img_dst;}/************************************************************************//*引导滤波函数u,实现,参考公式,主要计算均值,方差,协方差等 *//************************************************************************/Mat guidedfilter(Mat &I, Mat &p, int r, double eps){int h = I.rows;int w = I.cols;Mat one = Mat::ones(h, w, CV_64FC1);Mat N = boxfilter(one, r);Mat mean_I(h, w, CV_64FC1);divide(boxfilter(I, r), N, mean_I);Mat mean_p(h, w, CV_64FC1);divide(boxfilter(p, r), N, mean_p);Mat mul_Ip(h, w, CV_64FC1);Mat mean_Ip(h, w, CV_64FC1);multiply(I, p, mul_Ip);divide(boxfilter(mul_Ip, r), N, mean_Ip);Mat mul_mean_Ip(h, w, CV_64FC1);Mat cov_Ip(h, w, CV_64FC1);multiply(mean_I, mean_p, mul_mean_Ip);subtract(mean_Ip, mul_mean_Ip, cov_Ip);Mat mul_II(h, w, CV_64FC1);Mat mean_II(h, w, CV_64FC1);multiply(I, I, mul_II);divide(boxfilter(mul_II, r), N, mean_II);Mat mul_mean_II(h, w, CV_64FC1);Mat var_I(h, w, CV_64FC1);multiply(mean_I, mean_I, mul_mean_II);subtract(mean_II, mul_mean_II, var_I);Mat a(h, w, CV_64FC1);for (int i = 0; i < h; i++){double *p = var_I.ptr<double>(i);for (int j = 0; j < w; j++){p[j] = p[j] + eps;}}divide(cov_Ip, var_I, a);Mat a_mean_I(h, w, CV_64FC1);Mat b(h, w, CV_64FC1);multiply(a, mean_I, a_mean_I);subtract(mean_p, a_mean_I, b);Mat mean_a(h, w, CV_64FC1);divide(boxfilter(a, r), N, mean_a);Mat mean_b(h, w, CV_64FC1);divide(boxfilter(b, r), N, mean_b);Mat mean_a_I(h, w, CV_64FC1);Mat q(h, w, CV_64FC1);multiply(mean_a, I, mean_a_I);add(mean_a_I, mean_b, q);return q;}
- 学习guide滤波算法
- 图像滤波算法之guide filter导向滤波
- gmapping算法学习=粒子滤波+卡尔曼滤波
- 算法学习笔记之均值滤波法
- 卡尔曼滤波算法的学习
- 滤波算法
- 滤波算法
- 滤波算法
- 滤波算法
- 滤波算法
- 滤波算法
- 算法学习笔记之滑动平均滤波算法
- 算法学习笔记之一阶低通滤波算法
- 算法学习笔记之卡尔曼滤波算法理解
- 算法学习笔记之滑动平均滤波算法
- 自适应滤波算法的回音消除的学习
- OpenCV2学习笔记(十九):Kalman滤波算法
- 学习Opencv2——粒子滤波Condensation算法
- JAVA随堂笔记课【九】:多态、抽象
- leetcode第7题——*Reverse Integer
- 【剑指offer】2.4.2递归和循环——面试题9:斐波那契数列
- 比较两大虚拟桌面厂商的系统镜像管理
- Ajax
- 学习guide滤波算法
- Java的前期绑定和后期绑定[新]
- 内中断、int指令、端口 x86汇编
- View和XenDesktop到底谁更简单 Part II
- 使用iostat命令确认磁盘IO很差
- nodejs 使用inspector 调试
- 2015年末小结
- git 使用学习笔记
- libcurl的使用