#include<iostream>
#include<opencv2\opencv.hpp>
using namespace cv;
using namespace std;
double **getGaussArr(int size,double sigma)
{
double sum = 0;
double Sigmma = 1;
//建立一个size*size的二维数组
double **Gaussian_Temp =new double *[size];
for (int i = 0; i < size; ++i)
{
Gaussian_Temp[i] = new double[size];
}
//计算高斯模板
for (int i = 0; i <size; i++)
{
for (int j = 0; j < size; j++)
{
Gaussian_Temp[i][j] = exp(-((i - size / 2)*(i - size / 2) + (j - size / 2)*(j - size / 2)) / (2.0*Sigmma*Sigmma));
sum += Gaussian_Temp[i][j];
}
}
//归一化处理
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
Gaussian_Temp[i][j] = Gaussian_Temp[i][j] / sum;
}
}
return Gaussian_Temp;
}
//自定义高斯模糊
void myGaussian(const Mat _src, Mat &_dst)
{
if (!_src.data) return;
double **arr;
Mat tmp(_src.size(), _src.type());
for (int i=0;i<_src.rows;++i)
for (int j = 0; j < _src.cols; ++j)
{
if ((i - 1) > 0 && (i + 1) < _src.rows && (j - 1) > 0 && (j + 1) < _src.cols)
{
arr = getGaussArr(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] * _src.at<Vec3b>(i + 1 - x, j + 1 - y)[0];
tmp.at<Vec3b>(i, j)[1] += arr[x][y] * _src.at<Vec3b>(i + 1 - x, j + 1 - y)[1];
tmp.at<Vec3b>(i, j)[2] += arr[x][y] * _src.at<Vec3b>(i + 1 - x, j + 1 - y)[2];
}
}
}
tmp.copyTo(_dst);
}
//椒盐化图
void salt(Mat &image, int n)
{
for (int k = 0; k < n; k++)
{
int i = rand() % image.cols;
int j = rand() % image.rows;
if (image.channels() == 1)
{
image.at<uchar>(j, i) = 255;
}
else if (image.channels() == 3)
{
image.at<Vec3b>(j, i) = 255;
}
}
}
void main()
{
Mat image = imread("D:/2015project/gaosimuban/1.jpg");
Mat salt_image;
image.copyTo(salt_image);
Mat _gaussian;
Mat image1;
salt(salt_image, 1000);
myGaussian(salt_image, _gaussian);
GaussianBlur(salt_image, image1, Size(3, 3), 0,0);
imshow("原图", image);
imshow("椒盐化图", salt_image);
imshow("自定义高斯模糊", _gaussian);
imshow("opencv自带高斯模糊", image1);
waitKey(0);
}