opencv高斯滤波原理
高斯滤波是一种线性平滑滤波器,运用此滤波器,图像中各个点的像素值由它邻域像素的加权累加值来替换。把邻域中每个像素位置对应的权重系数存放在一个矩阵中,矩阵中心的元素对应正在当前正在应用此滤波器的像素,此矩阵成为内核或者掩码,在这里高斯函数主要用于根据像素的位置坐标(可以是1维也可以是2维坐标)计算出对应的权重,得到权重矩阵(即内核)
二维高斯函数
一维高斯函数
不同sigma对应曲线,可以发现sigma越大,越接近中心点(运用滤波器的像素点)的像素权重越大。一个图像应用一个线性滤波器,相当于将内核移动到图像的每个像素上,并将每个对应像素乘以它对应的权重(这要取决于离被应用像素点的距离),这个运算成为卷积。
opencv高斯滤波示例及参数解析
cv::GaussianBlur(image, // 输入图像
result, // 输出图像
cv::Size(5, 5), // 滤波器尺寸,即选取邻域矩阵大小
3); //控制高斯曲线形状的参数sigma,sigma越小,高斯曲线越高瘦,离中心点越近的点权重越大
简单高斯滤波自定义实现(便于理解,仅作参考)
double **getGuassionArray(int size,double sigma) //得到权重矩阵
{
int i, j;
double sum = 0.0;
int center = size; //以第一个点的坐标为原点,求出中心点的坐标
double **arr = new double*[size];//建立一个size*size大小的二维数组
for (i = 0; i < size; ++i)
arr[i] = new double[size];
for (i = 0; i < size; ++i)
for (j = 0; j < size; ++j)
{
arr[i][j] = exp(-((i - center)*(i - center) + (j - center)*(j - center)) /
(sigma*sigma * 2)); //应用高斯函数
sum += arr[i][j];
}
for (i = 0; i < size; ++i)
for (j = 0; j < size; ++j)
arr[i][j] /= sum;
return arr;
}
void Gaussian(const Mat image, Mat &result)
{
if (!image.data) return;
double **arr;
Mat tmp(image.size(), image.type());
for (int i = 0; i < image.rows; ++i)
for (int j = 0; j < image.cols; ++j)
{
//边缘不进行处理
if ((i - 1) > 0 && (i + 1) < image.rows && (j - 1) > 0 && (j + 1) < image.cols)
{
arr = getGuassionArray(3, 1);//自定义得到的权值数组
tmp.at<Vec3b>(i, j)[0] = 0;
tmp.at<Vec3b>(i, j)[1] = 0;
tmp.at<Vec3b>(i, j)[2] = 0;
for (int x = 0; x < 3; ++x)
{
for (int y = 0; y < 3; ++y)
{
tmp.at<Vec3b>(i, j)[0] += arr[x][y] * image.at<Vec3b>(i + 1 - x, j + 1 - y)[0];
tmp.at<Vec3b>(i, j)[1] += arr[x][y] * image.at<Vec3b>(i + 1 - x, j + 1 - y)[1];
tmp.at<Vec3b>(i, j)[2] += arr[x][y] * image.at<Vec3b>(i + 1 - x, j + 1 - y)[2];
}
}
}
}
tmp.copyTo(result);
}