【学习opencv】高斯滤波及其实现
来源:互联网 发布:学校网上缴费软件 编辑:程序博客网 时间:2024/05/16 07:21
高斯滤波及其实现
- 创建高斯滤波核
- 用滑动窗体进行卷积滤波
1.创建高斯滤波核
高斯滤波模板是通过二维高斯函数计算出来的:
G(x,y)=12πσ2e−x2+y22σ2
高斯模板需要知道模板大小及σ值,再通过上述高斯函数来确定模板系数。例现有3x3高斯模板如下,以模板中心为坐标原点,其高斯函数中的
模板的分类:有小数模板和整数模板
小数模板计算方法:利用高斯分布函数求得后,对其中每个元素的值除以模板系数和.
整数模板计算方法:利用高斯分布函数求得后,先归一化(左上角的元素为1),取整,再乘以模板取整后的系数和。
Note:高斯模板的大小与σ的选择:高斯核的宽度应该为方差σ的3倍,原理是因为高斯正态分布中的3σ原则。
2.用滑动窗体进行卷积滤波
Note:注意3通道的卷积运算,是分别选取该通道的进行运算。
效果
代码:
#include<opencv2/opencv.hpp>#include<iostream>#include<math.h>using namespace std;using namespace cv;/**生成高斯滤波的模板*function return 整型模板@param: windowsize 模板的大小 奇数@param: sigma 方差的大小*/vector<vector<int>> createGussInt(int windowsize,double sigma){ /*计算小数模板 *此时计算出来的小数模板不能直接用于高斯滤波,还需要进一步处理 */ vector<vector<double> > GussinDouble(windowsize, vector<double>(windowsize)); int std = windowsize / 2; for (int i = 0; i < windowsize; i++) { for (int j = 0; j < windowsize; j++) { int tem = (i - std)*(i - std) + (j - std)*(j - std); //GussinDouble[i][j] = (1 / 2.0*pi*sigma)*exp(-tem / (2.0*sigma*sigma)); GussinDouble[i][j] =exp(-tem / (2.0*sigma*sigma)); cout << GussinDouble[i][j] << " "; if (j == windowsize - 1)cout << "\n"; } } //变为整数模板:归一化,向下取整 double k = 1 / GussinDouble[0][0]; vector<vector<int>>GussinInt(windowsize, vector<int>(windowsize)); for (int i = 0; i < windowsize; i++) { for (int j = 0; j < windowsize; j++) { GussinDouble[i][j] = GussinDouble[i][j] * k; GussinInt[i][j] = floor(GussinDouble[i][j]); cout << GussinInt[i][j] << " "; if (j == windowsize - 1)cout << "\n"; } } return GussinInt;}/**高斯滤波**采用滑动模板窗口的方法滤波处理图片,图片最外层因为滤波窗口的大小会出现没有计算的情况,这里选用opencv自带的边界扩展函数@param: img 支持单通道和3通道的输入图像@param: kernel 整型滤波核*/void Guss(Mat src,Mat &dst,vector<vector<int>>kernel){ cout << "src.rows" << src.rows << endl; cout << "src.cols" << src.cols << endl; int std = kernel.size()/2; Mat tem; copyMakeBorder(src,tem,std,std,std,std, BORDER_REPLICATE); cout << "tem col:" << tem.cols << endl; cout << "tem.rows:" << tem.rows << endl; cout << "tem channels:" << tem.channels() << endl; uchar *p = tem.data; int step = tem.step[0]; int channels = tem.channels(); for (int i = std; i < tem.rows-std; i++) { for (int j = std*channels; j < (tem.rows - std)*channels; j = j + channels)//保证一列的遍历 { double sum[3] = { 0 }; for (int m = -std; m <= std; m++) { for (int n = -std; n <= std; n++) { if(channels==1)sum[0]+= p[(i + m)*step + j + n] * kernel[std + m][std + n]; if (channels == 3) { sum[0] += p[(i + m)*step + j + n*channels] * kernel[std + m][std + n]; sum[1] += p[(i + m)*step + j+1 + n*channels] * kernel[std + m][std + n]; sum[2] += p[(i + m)*step + j+2 + n*channels] * kernel[std + m][std + n]; } } } //饱和处理 /* for (int i = 0; i < 3; i++) { if (sum[i] > 255)sum[i] = 255; else if (sum[i] < 0)sum[0] = 0; }*/ //赋值 if (channels == 1)p[i*step + j] = sum[0]; if (channels == 3) { p[i*step + j] = sum[0]; p[i*step + j + 1] = sum[1]; p[i*step + j + 2] = sum[2]; } } } //range左包含右不包含 dst = tem(Range(std, tem.rows - std),Range(std, tem.cols - std));}/*主函数*/int main(){ Mat img = imread("test.jpg",1); vector<vector<int>>kernel; kernel=createGussDouble(3,0.8); Mat dst; imshow("img",img); Guss(img, dst,kernel); imshow("dst",dst); waitKey(0);}
阅读全文
0 0
- 【学习opencv】高斯滤波及其实现
- 高斯滤波 openCV实现
- 高斯滤波 openCV实现
- opencv简单学习方框滤波,均值滤波,高斯滤波
- python+opencv实现高斯平滑滤波
- opencv 高斯滤波自己实现
- Opencv学习一:高斯滤波
- Opencv学习(1):高斯滤波
- OpenCV: 高斯滤波
- opencv 高斯滤波
- 方框滤波,高斯滤波,中值滤波,双边滤波,opencv实现
- Opencv学习笔记:线性邻域滤波专场:方框滤波、均值滤波与高斯滤波
- OpenCV学习笔记(九):线性滤波:方框滤波、均值滤波、高斯滤波
- opencv实现图像邻域均值滤波、中值滤波、高斯滤波
- opencv实现图像邻域均值滤波、中值滤波、高斯滤波
- opencv实现图像邻域均值滤波、中值滤波、高斯滤波
- 基于OpenCV底层实现均值滤波,中值滤波和高斯滤波
- CUDA实现图像的高斯滤波(opencv实现)
- 关于学习生活记录的感想总结
- CSDN-markdown编辑器语法——字体、字号与颜色
- 个人知乎 ##基础三-数据库基础
- AB1601串口死机修改
- HDOJ2115 I Love This Game
- 【学习opencv】高斯滤波及其实现
- 如何用vue.js写购物车功能
- 个人知乎 ##功能一-登录注册
- 【无线安全实践入门】破解WiFi密码的多个方法
- 多维数据可视化(echart,plotly,matlab)
- idea 之远程debug调试
- Chapter 6. Hidden Markov and Maximum Entropy Models
- 个人知乎 ##功能二-问题发布
- 安卓手机分区