计算机图形学(3)--------------------------------高斯模糊的实现

【Note1】先看看高斯模糊实现的本质:

 其中r是模糊半径,也就是你的模板中心到模板的两侧的距离,

其中m和n代表你的卷积模板的大小,利用上面的公式的到高斯卷积模板。然后对图像进行卷积,模板越大,处理速度偏慢,而且边缘得不到处理的地方就会越来越多,下面看代码的实现

#include<iostream>
using namespace std;
#include<opencv2/opencv.hpp>
using namespace cv;
double** Generalize_gauss(int size_,double sigma)
{
    //进行高斯分布的生成
    double** array = new double* [size_];
    for (int i = 0; i < size_; i++)
    {
        array[i] = new double[size_];
    }
    //开始构造高斯分布并进行归一化
    double sum = 0.0;
    double pi = 3.14159265358;
    double med = size_ / 2;
    for (int i = 0; i < size_; i++)
    {
        for (int j = 0; j < size_; j++)
        {
            array[i][j]= 2 * pi * sigma * sigma * exp(-(((i - med) * (i - med) + (j - med) *(j - med)) / (2 * sigma * sigma)));
            sum += array[i][j];
        }
    }
    //进行归一化
    for (int i = 0; i < size_; i++)
    {
        for (int j = 0; j < size_; j++)
        {
            array[i][j] = array[i][j] / sum;
        }
    }
    return array;
}
void My_Gauss(Mat &input_image, int size_, double sigma)
{
    Mat temp = input_image.clone();
    double** array_gauss = Generalize_gauss(size_, sigma);
    for (int i = 0; i < input_image.rows; i++)
    {
        for (int j = 0; j < input_image.cols; j++)
        {
            if (i > (size_ / 2) - 1 && j > (size_ / 2) - 1 && i < input_image.rows - (size_ / 2) && j < input_image.cols - (size_ / 2))
            {
                if (temp.channels() == 1)
                {
                    double sum = 0.0;
                    for (int k = 0; k < size_; k++)
                    {
                        for (int l = 0; l < size_; l++)
                        {
                            sum += input_image.ptr<uchar>(i - k + (size_ / 2))[j - l + (size_ / 2)] * array_gauss[k][l];
                        }
                    }
                    temp.ptr<uchar>(i)[j] = sum;
                }
                else
                {
                    double sum1 = 0.0;
                    double sum2 = 0.0;
                    double sum3 = 0.0;
                    int chan = temp.channels();
                    for (int k = 0; k < size_ ; k++)
                    {
                        for (int l = 0; l < size_ ; l++)
                        {
                            sum1=input_image.ptr<Vec3b>(i - k + (size_ / 2))[j - l + (size_ / 2)][0] * array_gauss[k][l];
                            sum2 = input_image.ptr<Vec3b>(i - k + (size_ / 2))[j - l + (size_ / 2)][1] * array_gauss[k][l];
                            sum3 = input_image.ptr<Vec3b>(i - k + (size_ / 2))[j - l + (size_ / 2)][2] * array_gauss[k][l];
                        }
                        temp.ptr<Vec3b>(i)[j][0] = sum1;
                        temp.ptr<Vec3b>(i)[j][1] = sum2;
                        temp.ptr<Vec3b>(i)[j][2] = sum3;
                    }
                }
            }
        }
    }
    input_image = temp.clone();

}
int main()
{
    Mat image = imread("picture7.jpg");
    double** array = Generalize_gauss(3, 1.5);
    /*gaussian(&image, array, 3);*/
    My_Gauss(image, 3, 1.5);
    imshow("处理", image);
    waitKey(0);
    return 0;
}

下面看看模板大小为3x3的时候

 下面看看模板大小为50的结果:

 对比两幅图像,明显看到第二幅图片的未处理区域有一些边缘扩大

【注】:自己的实现,用matlab速度或许会更快一些,别人说还可以用快速傅里叶做,但我不会(〒︿〒)

猜你喜欢

转载自www.cnblogs.com/dfxdd/p/12321068.html