高斯模糊

高斯模糊是一个两维空间的卷积模糊操作,在图像去噪方面有着非常好的效果。
一维高斯函数如下:其中x∈[-n,n],sigma代表标准方差,通常取值1。

一维高斯函数.png

步骤如下:
一、调用get2DKernalData算出高斯内核数据

代码:

#include "math.h"
using namespace std;

#define pi 3.1415926535898

float* get1DKernalData(int n,float sigma)
{
    float sigma22=2*sigma*sigma;
    float pi2=2*(float)pi;
    float sqrtSigmaPi2=(float)sqrt(pi2)*sigma;
    float* kernalData=new float[2*n+1];
    int index=0;
    for(int i=-n; i<=n; i++)
    {
        float distance=i*i;
        kernalData[index]=(float)exp((-distance)/sigma22)/sqrtSigmaPi2;
        index++;
    }
    return kernalData;
}

二维高斯函数如下:


二维高斯函数.png

代码:

float** get2DKernalData(int n,float sigma)
{
    int size = 2*n +1;
    float sigma22 = 2*sigma*sigma;
    float sigma22PI = (float)pi * sigma22;
    float** kernalData = new float*[size];
    for(int i=0; i<size; i++)
    {
        kernalData[i]=new float[size];
    }
    int row = 0;
    for(int i=-n; i<=n; i++)
    {
        int column = 0;
        for(int j=-n; j<=n; j++)
        {
            float xDistance = i*i;
            float yDistance = j*j;
            kernalData[row][column] = (float)exp(-(xDistance + yDistance)/sigma22)/sigma22PI;
            column++;
        }
        row++;
    }
    return kernalData;
}
二、将高斯内核数据传入到convolutionFilte方法中计算卷积,得出峰值和峰值比率,最后进行归一化处理得到高斯卷积图像
Mat Convolution::convolutionFilte(Mat* m_opt,Mat* m_src,Mat* m_dst,int dst_size)
{
    Mat opt=((Mat)*m_opt);
    Mat src=((Mat)*m_src);
    Mat dst=((Mat)*m_dst);

    for(int row=0; row<src.rows; row++)
    {
        for(int col=0; col<src.cols; col++)
        {
            float wSum = 0.0;
            float rSum=0,gSum=0,bSum=0;
            for(int subRow=0; subRow<opt.rows; subRow++)
            {
                for(int subCol=0; subCol<opt.cols; subCol++)
                {
                    bSum += src.at<Vec3b>(row,col)[0] * opt.at<float>(subRow,subCol);
                    gSum += src.at<Vec3b>(row,col)[1] * opt.at<float>(subRow,subCol);
                    rSum += src.at<Vec3b>(row,col)[2] * opt.at<float>(subRow,subCol); 
                    wSum += opt.at<float>(subRow ,subCol);
                }
            }
            dst.at<Vec3b>(row,col)[0] = (int)(bSum / wSum);
            dst.at<Vec3b>(row,col)[1] = (int)(gSum / wSum);
            dst.at<Vec3b>(row,col)[2] = (int)(rSum / wSum);
        }
    }

    ///计算峰值
    int srcpeak = 0;
    int dstPeak = 0;
    for(int row=0; row<src.rows; row++)
    {
        for(int col=0; col<src.cols; col++)
        {
            if(srcpeak < src.at<Vec3b>(row,col)[0])
            {
                srcpeak = src.at<Vec3b>(row,col)[0];
            }
            if(srcpeak < src.at<Vec3b>(row,col)[1])
            {
                srcpeak = src.at<Vec3b>(row,col)[1];
            }
            if(srcpeak < src.at<Vec3b>(row,col)[2])
            {
                srcpeak = src.at<Vec3b>(row,col)[2];
            }
            if(dstPeak < dst.at<Vec3b>(row,col)[0])
            {
                dstPeak = dst.at<Vec3b>(row,col)[0];
            }
            if(dstPeak < dst.at<Vec3b>(row,col)[1])
            {
                dstPeak = dst.at<Vec3b>(row,col)[1];
            }
            if(dstPeak < dst.at<Vec3b>(row,col)[2])
            {
                dstPeak = dst.at<Vec3b>(row,col)[2];
            }
        }
    }

    /// 归一化处理
    double rate = ((double) srcpeak) / ((double)dstPeak);
    for(int row=0; row<src.rows; row++)
    {
        for(int col=0; col<src.cols; col++)
        {
            dst.at<Vec3b>(row,col)[0] = (int)(rate * dst.at<Vec3b>(row,col)[0]);
            dst.at<Vec3b>(row,col)[1] = (int)(rate * dst.at<Vec3b>(row,col)[1]);
            dst.at<Vec3b>(row,col)[2] = (int)(rate * dst.at<Vec3b>(row,col)[2]);
        }
    }
    return dst;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容