图像快速高斯滤波实现
1、二维高斯滤波公式:(μ=0,σ)
G(x,y) = 1/2πσ2·exp(-(x2+y2)/2σ2)
G(x,y)可以分离为:G(x,y) = G(x)·G(y)= 1/2πσ2·exp(-x2/2σ2)·exp(-y2/2σ2),其中系数1/2πσ2可以不考虑,因为在归一化时又将其消掉了。
所以,二维的滤波可以分离为两个一维的滤波。
2、假设灰度图像宽高分别为W、H,二维高斯滤波模板宽高均为m_size,那么二维模板直接卷积计算复杂度为O(W*H*m_size*m_size);
同样采用两次一维(横向、纵向)卷积计算的复杂度为O(W*H*m_szie*2),显然计算复杂度降低,滤波模板阶数越高计算速度的提升越明显。
通常根据3σ原则来计算模板阶数,阶数k = 2*ceil(3σ)+1,因为高斯分布中(μ=0)±3σ几乎涵盖了所有的分布,所以可以根据此规则估算合理的模板阶数(奇数)。
3、代码实现中这里使用了自己创建的二维数组,目的是来比对两种滤波的结果,代码如下:
#include <QCoreApplication>
#include <iostream>
#include <math.h>
using namespace std;
double** CreateGaussMap(int map_size, double sigma);
double* CreateGauss(int map_size, double sigma);
void GaussFilter2(int src[9][9], double dst[9][9], double** map);
void GaussFilter(int src[9][9], double dst[9][9], double* map);
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
double** gauss2 = CreateGaussMap(3,0.33);
for (int i=0;i<3;++i) {
for (int j=0;j<3;++j) {
cout<<gauss2[i][j]<< " ";
}
cout<<endl;
}
cout<<endl;
double* gauss = CreateGauss(3,0.33);
for (int i=0;i<3;++i) {
cout<<gauss[i]<< " ";
}
cout<<endl;
int arr[9][9]={{1,1,1,1,1,1,1,1,1},{2,2,2,2,2,2,2,2,2},
{3,3,3,3,3,3,3,3,3},{4,4,4,4,4,4,4,4,4},
{5,5,5,5,5,5,5,5,5},{6,6,6,6,6,6,6,6,6},
{7,7,7,7,7,7,7,7,7},{8,8,8,8,8,8,8,8,8},
{9,9,9,9,9,9,9,9,9}};
double dst2[9][9];
double dst[9][9];
GaussFilter2(arr,dst2,gauss2);
for (int i=0;i<9;++i) {
for (int j=0;j<9;++j) {
cout<<dst2[i][j]<<" ";
}
cout<<endl;
}
GaussFilter(arr,dst,gauss);
for (int i=0;i<9;++i) {
for (int j=0;j<9;++j) {
cout<<dst[i][j]<<" ";
}
cout<<endl;
}
return a.exec();
}
double** CreateGaussMap(int map_size, double sigma){
// g(x,y) = (1/(2*pi*sigma^2))*exp(-(x^2+y^2)/(2*sigma^2))
int center = (map_size-1)/2;
//double amplitude = 1/(2*M_PI*sigma*sigma);
double sigma_sqr = 2*pow(sigma,2);
double x_sqr = 0, y_sqr = 0;
double** gauss = new double*[map_size];
double sum = 0;
// for (int i=0;i<map_size;++i) {
// }
for(int i=0;i<map_size;++i){
gauss[i] = new double[map_size];
y_sqr = pow(double(i-center),2);
for (int j=0;j<map_size;++j) {
x_sqr = pow(double(j-center),2);
sum += gauss[i][j] = exp(-(x_sqr + y_sqr)/sigma_sqr);
}
}
if(sum != 0){
for (int i=0;i<map_size;++i) {
for (int j=0;j<map_size;++j) {
gauss[i][j] /= sum;
}
}
}
return gauss;
}
double* CreateGauss(int map_size, double sigma){
// g(x,y) = (1/(2*pi*sigma^2))*exp(-(x^2+y^2)/(2*sigma^2))
int radius = (map_size-1)/2;
//double amplitude = 1/(2*M_PI*sigma*sigma);
double sigma_sqr = 2*pow(sigma,2);
double* gauss = new double [map_size];
double sum = 0;
for(int i=0;i<map_size;++i){
gauss[i] = exp(-(pow(double(i-radius),2))/sigma_sqr);
sum += gauss[i];
}
if(sum != 0){
for (int i=0;i<map_size;++i) {
gauss[i] /= sum;
}
}
return gauss;
}
void GaussFilter2(int src[9][9], double dst[9][9], double** map){
for (int i=0;i<9;++i) {
for (int j=0;j<9;++j) {
dst[i][j] = src[i][j];
}
}
int center = 1;
for (int i=0;i<9-center-1;++i) {
for (int j=0;j<9-center-1;++j) {
for (int k=0;k<3;++k) {
for (int m=0;m<3;++m) {
dst[i+center][j+center] += src[i+k][j+m]*map[k][m];
}
}
}
}
}
void GaussFilter(int src[9][9], double dst[9][9], double* map){
double tmp[9][9];
for (int i=0;i<9;++i) {
for (int j=0;j<9;++j) {
tmp[i][j] = src[i][j];
}
}
int center = 1;
int a=0;
double t=0;
for (int i=0;i<9-center-1;++i) {
for (int j=0;j<9-center-1;++j) {
tmp[i+center][j+center] = 0;
for (int k=0;k<3;++k) {
a = src[i+center][j+k];
t=map[k];
tmp[i+center][j+center] += (src[i+center][j+k])*map[k];
}
}
}
for (int i=0;i<9;++i) {
for (int j=0;j<9;++j) {
dst[i][j] = tmp[i][j];
}
}
for (int j=0;j<9-center-1;++j) {
for (int i=0;i<9-center-1;++i) {
for (int k=0;k<3;++k) {
dst[i+center][j+center] += tmp[i+k][j+center]*map[k];
}
}
}
}
4、结果中,两中方式滤波结果一致,μ=0,σ=0.33,k = 3。
二维高斯滤波模板:
9.87532e-005 0.00973996 9.87532e-005
0.00973996 0.960645 0.00973996
9.87532e-005 0.00973996 9.87532e-005
对9*9的二维数组滤波结果:
1 1 1 1 1 1 1 1 1
2 4 4 4 4 4 4 4 2
3 6 6 6 6 6 6 6 3
4 8 8 8 8 8 8 8 4
5 10 10 10 10 10 10 10 5
6 12 12 12 12 12 12 12 6
7 14 14 14 14 14 14 14 7
8 16 16 16 16 16 16 16 8
9 9 9 9 9 9 9 9 9
一维高斯滤波模板
[0.00993747 0.980125 0.00993747]
两次一维高斯滤波的结果:(注:第一次横向卷积计算后的数据进行第二次纵向卷积计算)
1 1 1 1 1 1 1 1 1
2 4 4 4 4 4 4 4 2
3 6 6 6 6 6 6 6 3
4 8 8 8 8 8 8 8 4
5 10 10 10 10 10 10 10 5
6 12 12 12 12 12 12 12 6
7 14 14 14 14 14 14 14 7
8 16 16 16 16 16 16 16 8
9 9 9 9 9 9 9 9 9
浙公网安备 33010602011771号