#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
//计算一维高斯的权值数组
double *getOneGuassionArray(int size, double sigma)
{
double sum = 0.0;
//定义高斯核半径
int kerR = size / 2;
//建立一个size大小的动态一维数组
double *arr = new double[size];
for (int i = 0; i < size; i++)
{
// 高斯函数前的常数可以不用计算,会在归一化的过程中给消去
arr[i] = exp(-((i - kerR)*(i - kerR)) / (2 * sigma*sigma));
sum += arr[i];//将所有的值进行相加
}
//进行归一化
for (int i = 0; i < size; i++)
{
arr[i] /= sum;
cout << arr[i] << endl;
}
return arr;
}
void MyGaussianBlur(Mat &srcImage, Mat &dst, int size)
{
CV_Assert(srcImage.channels() || srcImage.channels() == 3); // 只处理单通道或者三通道图像
int kerR = size / 2;
dst = srcImage.clone();
int channels = dst.channels();
double* arr;
arr = getOneGuassionArray(size, 1);//先求出高斯数组
//遍历图像 水平方向的卷积
for (int i = kerR; i < dst.rows - kerR; i++)
{
for (int j = kerR; j < dst.cols - kerR; j++)
{
double GuassionSum[3] = { 0 };
//滑窗搜索完成高斯核平滑
for (int k = -kerR; k <= kerR; k++)
{
if (channels == 1)//如果只是单通道
{
GuassionSum[0] += arr[kerR + k] * dst.at<uchar>(i , j + k);//行不变,列变换,先做水平方向的卷积
}
else if (channels == 3)//如果是三通道的情况
{
Vec3b bgr = dst.at<Vec3b>(i, j + k);
auto a = arr[kerR + k];
GuassionSum[0] += a*bgr[0];
GuassionSum[1] += a*bgr[1];
GuassionSum[2] += a*bgr[2];
}
}
for (int k = 0; k < channels; k++)
{
if (GuassionSum[k] < 0)
GuassionSum[k] = 0;
else if (GuassionSum[k] > 255)
GuassionSum[k] = 255;
}
if (channels == 1)
dst.at<uchar>(i, j) = static_cast<uchar>(GuassionSum[0]);
else if (channels == 3)
{
Vec3b bgr = { static_cast<uchar>(GuassionSum[0]), static_cast<uchar>(GuassionSum[1]), static_cast<uchar>(GuassionSum[2]) };
dst.at<Vec3b>(i, j) = bgr;
}
}
}
//竖直方向
for (int i = kerR; i < dst.rows - kerR; i++)
{
for (int j = kerR; j < dst.cols - kerR; j++)
{
double GuassionSum[3] = { 0 };
//滑窗搜索完成高斯核平滑
for (int k = -kerR; k <= kerR; k++)
{
if (channels == 1)//如果只是单通道
{
GuassionSum[0] += arr[kerR + k] * dst.at<uchar>(i + k, j);//行变,列不换,再做竖直方向的卷积
}
else if (channels == 3)//如果是三通道的情况
{
Vec3b bgr = dst.at<Vec3b>(i + k, j);
auto a = arr[kerR + k];
GuassionSum[0] += a*bgr[0];
GuassionSum[1] += a*bgr[1];
GuassionSum[2] += a*bgr[2];
}
}
for (int k = 0; k < channels; k++)
{
if (GuassionSum[k] < 0)
GuassionSum[k] = 0;
else if (GuassionSum[k] > 255)
GuassionSum[k] = 255;
}
if (channels == 1)
dst.at<uchar>(i, j) = static_cast<uchar>(GuassionSum[0]);
else if (channels == 3)
{
Vec3b bgr = { static_cast<uchar>(GuassionSum[0]), static_cast<uchar>(GuassionSum[1]), static_cast<uchar>(GuassionSum[2]) };
dst.at<Vec3b>(i, j) = bgr;
}
}
}
delete[] arr;
}
int main()
{
Mat srcImage = imread("flower3.jpg");
if (!srcImage.data)
{
printf("could not load image...\n");
return -1;
}
//getGuassionArray(3, 1);
Mat resMat;
MyGaussianBlur(srcImage, resMat, 3);
imshow("src", srcImage);
imshow("resMat", resMat);
waitKey(0);
return 0;
}
高斯滤波的c++代码实现
5星 · 超过95%的资源 需积分: 44 132 浏览量
2018-01-19
10:12:51
上传
评论 4
收藏 123KB RAR 举报
零钱币
- 粉丝: 243
- 资源: 10