# 滤波的分类

• 线性滤波

• 非线性滤波

## 高斯滤波

std::vector<std::vector<double> >getModel(const int& n, const double& sigmma)//求解nxn的模板系数
{
const double pi = 3.1415926;
const double weight = 1.0 /(2.0 * pi * sigmma * sigmma);//gaussion公式中的系数

double sum = 0.0;
std::vector<std::vector<double>> res(n, std::vector<double>(n, 0.0));

for(int i = 0;  i < n; ++i)
for (int j = 0; j < n; ++j)
{
res[i][j] = weight * std::exp(-((i - n / 2) * (i - n / 2) + (j - n / 2)*(j - n / 2)) / (2.0*sigmma*sigmma));//n/2为公式中都均值，即原点在图像中心
}

return res;
}

x方向

y方向

## Roberts算子

Roberts算子比较简单，使用2x2的领域

Roberts算子

Roberts算子计算

sobel算子

Robinson算子

## Kirsch算子

Kirsch算子

//二维卷积的实现
#include<cassert>
#include<vector>

void conv2(int** filter, int **mat, int** res, const int filter_rows, const int filter_cols, const int mat_rows, const int mat_cols);//指针数组版本
std::vector<std::vector<int> > conv2(std::vector<std::vector<int> > filter, std::vector<std::vector<int> > mat);//向量版本

int main(void)
{
return 0;
}//main

void conv2(int** filter, int **mat, int** res, const int filter_rows, const int filter_cols, const int mat_rows, const int mat_cols)
{
assert(filter_cols < mat_cols && filter_rows < mat_rows);
for(int i = 0; i < mat_rows - 1; ++i)
for (int j = 0; j < mat_cols - 1; ++j)
{
int tmp = 0;
for (int m = 0; m < filter_rows; ++m)
for (int n = 0; n < filter_cols; ++n)
if(0 <= i -m  && i - m < mat_rows && 0 <= j - n && j - n < mat_cols)
tmp += filter[m][n] * mat[i - m][j - n];//卷积公式

res[i][j] = tmp;
}
}

std::vector<std::vector<int> > conv2(std::vector<std::vector<int> > filter, std::vector<std::vector<int> > mat )//向量版本
{
const int filter_rows = filter.size();
const int filter_cols = filter[0].size();

const int mat_rows = mat.size();
const int mat_cols = mat[0].size();

assert(filter_cols < mat_cols && filter_rows < mat_rows);
std::vector<std::vector<int> > res(mat_rows, std::vector<int>(mat_cols, 0));

for (int i = 0; i < mat_rows - 1; ++i)
for (int j = 0; j < mat_cols - 1; ++j)
{
int tmp = 0;
for (int m = 0; m < filter_rows; ++m)
for (int n = 0; n < filter_cols; ++n)
if (0 <= i - m && i - m < mat_rows && 0 <= j - n && j - n < mat_cols)
tmp += filter[m][n] * mat[i - m][j - n];//卷积公式

res[i][j] = tmp;
}
return res;
}

void mycv::gaussianFilter(cv::Mat& src, cv::Mat& dst)
{
const int rows = src.rows;
const int cols = src.cols;
dst = cv::Mat(src.size(), src.type(), cv::Scalar::all(0));

std::vector<std::vector<double>> gauss = getModel(3);//3x3模板系数

switch (src.channels())
{
case 1://灰度图
for(int i = 0; i < rows -1; ++i)
for (int j = 0; j < cols - 1; ++j)
{
double tmp = 0.0;
for(int m = 0; m < gauss.size(); ++m)
for (int n = 0; n < gauss[0].size(); ++n)
{
if (i - m >= 0 & i - m < rows && j - n >= 0 && j - n < cols)
tmp += gauss[m][n] * static_cast<double>(src.at<uchar>(i - m, j - n));//卷积公式
}

dst.at<uchar>(i, j) = static_cast<int>(tmp);
}
break;
case 3://彩色
for (int i = 0; i < rows - 1; ++i)
for (int j = 0; j < cols - 1; ++j)
for (int k = 0; k < 3; ++k)
{
double tmp = 0.0;
for (int m = 0; m < gauss.size(); ++m)
for (int n = 0; n < gauss[0].size(); ++n)
if (i - m >= 0 & i - m < rows && j - n >= 0 && j - n < cols)
tmp += gauss[m][n] * static_cast<double>(src.at<cv::Vec3b>(i - m, j - n)[k]);//卷积公式

dst.at<cv::Vec3b>(i, j)[k] = static_cast<int>(tmp);
}
break;
default:
break;
}
}