高斯平滑滤波的实现与图像内存之间值的复制
来源:互联网 发布:有关网络防沉迷的ppt 编辑:程序博客网 时间:2024/06/05 00:50
以另外一个滤波器而言----均值滤波器, 就是说某像素的颜色, 由以其为中心的九宫格的像素平均值来决定. 在这个基础上又发展成了带权的“平均”滤波器, 这里的高斯平滑或者说滤波器就是这样一种带权(通常我们认为距离要代替的点像素的作用大一些)的“平均”滤波器. 那么这些权重如何分布呢? 我们先来看几个经典的模板例子:
尝试了使用这些滤波器对我们原来的图进行操作, 得到了这样的一组结果:
原图:
3x3 高斯滤波处理后:
5x5 高斯处理后:
单纯从效果来看, 两个模板都起到了平滑的作用, 只是程度有深浅的区分. 那么从理论上来说为什么能起到平滑的作用呢? 很显然, 像素的颜色不仅由自身决定了, 同时有其周围的像素加权决定, 客观上减小了和周围像素的差异.同时这些权重的设定满足了越近权重越大的规律. 从理论来讲, 这些权重的分布满足了著名的所谓高斯分布:
这就是1维的计算公式:
这就是2维的计算公式:
x, y表示的就是当前点到对应点的距离, 而那些具体的模板就是由这里公式中的一些特例计算而来. 需要说明的是不只有这么一些特例, 从wikipedia可以方便地找到那些复杂的模板比如像:
Sample Gaussian matrix
This is a sample matrix, produced by sampling the Gaussian filter kernel (with σ = 0.84089642) at the midpoints of each pixel and then normalising. Note that the center element (at [4, 4]) has the largest value, decreasing symmetrically as distance from the center increases.
0.000000670.000022920.000191170.000387710.000191170.000022920.000000670.000022920.000786330.006559650.013303730.006559650.000786330.000022920.000191170.006559650.054721570.110981640.054721570.006559650.000191170.000387710.013303730.110981640.225083520.110981640.013303730.000387710.000191170.006559650.054721570.110981640.054721570.006559650.000191170.000022920.000786330.006559650.013303730.006559650.000786330.000022920.000000670.000022920.000191170.000387710.000191170.000022920.00000067是不是看到就头大了?不过没关系, 对于一般的应用来说, 前面的例子已经可以完成任务了. 代码的话我们还是给一份5x5的example:
今天也尝试了图像复原算法的研究,其实图像复原算法与傅里叶变换与滤波的关系很大。下面为一部分代码
# include <opencv2/core/core.hpp>
# include <opencv2/highgui/highgui.hpp>
# include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void gaussianFilter2 (unsigned char* corrupted, unsigned char* smooth, int width, int height)
{
int templates[25] = { 1, 4, 7, 4, 1,
4, 16, 26, 16, 4,
7, 26, 41, 26, 7,
4, 16, 26, 16, 4,
1, 4, 7, 4, 1 }; //滤波器模板
//定义卷积核算子
cv::Mat kernal = (cv::Mat_<float>(3,3)<< 1,1,1,
1,1,1,
1,1,1);
memcpy ( smooth, corrupted, width*height*sizeof(unsigned char) ); //复制像素
for (int j=2;j<height-2;j++) //边缘不处理
{
for (int i=2;i<width-2;i++)
{
int sum = 0;
int index = 0;
for ( int m=j-2; m<j+3; m++)
{
for (int n=i-2; n<i+3; n++)
{
sum += corrupted [ m*width + n] * templates[index++] ;
}
}
sum /= 273;
if (sum > 255)
sum = 255;
smooth [ j*width+i ] = sum;
}
}
}
cv::Mat DFT(cv::Mat srcImage)
{
cv::Mat srcGray;
cvtColor(srcImage,srcGray,CV_RGB2GRAY);
// 将输入图像延扩到最佳的尺寸
int nRows = getOptimalDFTSize(srcImage.rows);
int nCols = getOptimalDFTSize(srcImage.cols);
cv::Mat resultImage;
// 把灰度图像放在左上角,在右边和下边扩展图像,
// 添加的像素初始化为0
copyMakeBorder(srcGray, resultImage, 0,
nRows - srcGray.rows,
0, nCols - srcGray.cols,
BORDER_CONSTANT, Scalar::all(0));
// 为傅立叶变换的结果(实部和虚部)分配存储空间
cv::Mat planes[] = { cv::Mat_<float>(resultImage),
cv::Mat::zeros(resultImage.size(), CV_32F)};
Mat completeI;
// 为延扩后的图像增添一个初始化为0的通道
merge(planes,2,completeI);
// 进行离散傅立叶变换
dft(completeI,completeI);
// 将复数转换为幅度
split(completeI,planes);
magnitude(planes[0],planes[1],planes[0]);
cv::Mat dftResultImage = planes[0];
// 对数尺度(logarithmic scale)缩放
dftResultImage += 1;
log(dftResultImage,dftResultImage);
// 剪切和重分布幅度图象限
dftResultImage= dftResultImage(Rect(0,
0,srcGray.cols,srcGray.rows));
// 归一化图像
/*normalize(dftResultImage,dftResultImage,
0,1,CV_MINMAX);*/
int cx = dftResultImage.cols/2;
int cy = dftResultImage.rows/2;
Mat tmp;
// Top-Left - 为每一个象限创建ROI
Mat q0(dftResultImage,Rect(0,0,cx,cy));
// Top-Right
Mat q1(dftResultImage,Rect(cx,0,cx,cy));
// Bottom-Left
Mat q2(dftResultImage,Rect(0,cy,cx,cy));
// Bottom-Right
Mat q3(dftResultImage,Rect(cx,cy,cx,cy));
// 交换象限 (Top-Left with Bottom-Right)
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
// 交换象限 (Top-Right with Bottom-Left)
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
return dftResultImage;
}
int main()
{
cv::Mat srcImage = imread("3.jpg");
Mat dstImage = Mat(srcImage.size(),srcImage.type(),Scalar::all(0));
uchar *dataSrc = srcImage.data;
uchar *dataDst = dstImage.data;
int nRows = srcImage.rows;
int nCols = srcImage.cols;
/*gaussianFilter2(dataSrc,dataDst,nCols,nRows);*/
memcpy(dataDst,dataSrc,sizeof(uchar)*nCols*nRows * 3); 此处为3通道图像
namedWindow("2",0);
imshow("2",dstImage);
waitKey(0);
}
- 高斯平滑滤波的实现与图像内存之间值的复制
- 图像平滑技术之盒滤波、均值滤波、中值滤波、高斯滤波、双边滤波的原理概要及OpenCV代码实现
- 图像的高斯平滑C++实现
- c#实现图像图像卷积与滤波——高斯平滑
- 数字图像处理,高斯平滑滤波的C++实现
- 【拜小白opencv】34-图像平滑处理,6种滤波总结的综合示例【盒式滤波、均值滤波、高斯滤波、中值滤波、双边滤波、导向滤波】
- 图像的高斯平滑
- 图像高斯平滑滤波分析
- 图像高斯平滑滤波分析(转)
- 图像高斯平滑滤波分析
- 图像的高斯滤波
- 图像处理常用算法GPU实现四:基于中值滤波的二值图像平滑
- 图像处理常用算法GPU实现四:基于中值滤波的二值图像平滑
- CUDA实现图像的高斯滤波(opencv实现)
- 图像高提升滤波的vc实现
- 图像高提升滤波的vc实现 .
- python+opencv实现高斯平滑滤波
- 图像高斯滤波的FPGA实现--实时高速
- maven
- sklearn文档 — 1.10. 决策树
- C++求值次序与副作用
- ARM GPU 架构简介
- 组件模块化
- 高斯平滑滤波的实现与图像内存之间值的复制
- eclipse常用快捷键
- mask R-cnn检测,分割和特征点定位全部都做了
- CAN总线为什么要有两个120Ω的终端电阻
- mamp 下安装redis扩展
- 最新linux 编程视频教程下载
- 说说使用 JavaScript 解析以及序列化 JSON 的方法
- 基础技术篇 11 —— 一文读懂MQTT协议
- FastReport.NET报表控件功能详解—数据处理