精华内容
下载资源
问答
  • 常见图像滤波方式

    千次阅读 2019-05-13 18:54:16
    本文介绍五种常见的图像滤波方式:线性滤波(方框滤波、均值滤波、高斯滤波);非线性滤波(中值滤波、双边滤波)。提醒,本文主要是算法公式,没有具体完整的代码。 一、线性滤波 总的来说,这三种线性滤波原理...

    本文介绍五种常见的图像滤波方式:线性滤波(方框滤波、均值滤波、高斯滤波);非线性滤波(中值滤波、双边滤波)。提醒,本文主要是算法公式,没有具体完整的代码。

     

    一、线性滤波

    总的来说,这三种线性滤波原理:每个像素的输出值是输入像素的加权和。其处理方式都是将图像像素与相应的核进行卷积,核即是权重(下图中中间3*3大小的图就是核),其作用是将原图像素按权重进行分配。简单讲,卷积就是选取原图像与核相同大小的部分(下图左侧对照部分),然后与核对应相乘相加,所得的值赋给原图中的锚点(下图是中心点,右侧对照部分)(有关卷积的讲解可参考下图的转载链接)。

                                               卷积(图像转自https://blog.csdn.net/zouxy09/article/details/49080029,侵删)

    所以说,这三种滤波方式的区别在于卷积核的不同,下面分别叙述。

     

    1.1方框滤波和均值滤波的卷积核

    如下图,K即为方框滤波的核,可以看到无论a为何值,矩阵内的每一个元素都相等,卷积时对像素的权重都一样。均值滤波是方框滤波归一化后的特殊处理,下图中,当normalize = ture时的K为均值滤波的核。个人觉得,方框滤波和均值滤波没有实质上的区别。

     

    1.2高斯滤波的卷积核

    我们先来看一下一维高斯函数,如下图,a代表尖峰高度,b代表尖峰中心的x坐标,c是标准方差,代表尖峰的宽度。图3表示“3σ”原则,意思是,虽然定义域的范围是正无穷到负无穷,但是曲线的绝大部分都在“-3σ - 3σ”之间。

            

                             一维高斯函数(图1、2转载自https://blog.csdn.net/jorg_zhao/article/details/52687448,侵删)

    接下来我们看看二维高斯函数,其服从当ρ=0时的二维正态分布,即x、y不相关。同样,参照一维高斯函数,A是幅值,即高度;x。y。是中心点坐标;σσy是方差,代表底面的两个方向上的宽度。

                   

                           二维高斯函数(转载自https://blog.csdn.net/jorg_zhao/article/details/52687448,侵删)

    在计算高斯核时,由于在x、y两个方向上我们所需要的宽度是完全一致的,所以我们可以取σx = σy,这时公式变为

                                          A=\frac{1}{2\pi \sigma^{2}}                   G(x,y)=Aexp(-(\frac{(x-x_{0})^{2} + (y-y_{0})^{2}}{2\sigma ^{2}}))

    由上述公式,我们就可以求出高斯核,代码如下

    //******************高斯卷积核生成函数*************************
    //第一个参数Guass是存高斯卷积核的二维数组
    //第二个参数size是高斯卷积核的尺寸大小;
    //第三个参数sigma是卷积核的标准差
    //*************************************************************
    void CDisplay::GetGaussianKernel(double **Guass, const int size, const double sigma)
    {
    	const double PI = 4.0*atan(1.0); //圆周率π赋值
    	int center = size / 2;
    	double sum = 0;
    	for (int i = 0; i<size; i++)
    	{
    		for (int j = 0; j<size; j++)
    		{
    			Guass[i][j] = (1 / (2 * PI*sigma*sigma))*exp(-((i - center)*(i - center) + (j - center)*(j - center)) / (2 * sigma*sigma));
    			sum += Guass[i][j];
    		}
    	}
    	for (int i = 0; i<size; i++)	//归一化
    	{
    		for (int j = 0; j<size; j++)
    		{
    			Guass[i][j] /= sum;
    		}
    	}
    }

    sigma与size值的选取:一般其情况,size = sigma*3+1,因为“3σ”原则。

     

    二、非线性滤波

    2.1中值滤波

    基本思想:用像素点邻域灰度值的中值来代替该像素点的灰度值。

    如下图,将中心点周围被称为邻域的像素点(包括自身)进行排序,取排序后9个像素值中间值作为当前新的像素值。

                        中值滤波原理图(图片转载自https://blog.csdn.net/qq_36359022/article/details/80116137,侵删)

     

     2.2双边滤波

    基于空间分布的高斯滤波函数,其核为一个与空间距离相关的高斯函数与一个灰度距离相关的高斯函数相乘所得。简单说就是高斯滤波的加强版,在高斯滤波中,只有关于空间距离的权重,离中心点越远,权重越小,而双边滤波在此基础上添加了关于灰度距离的权重,邻域中的像素灰度值越接近中心点灰度值,权重越大。

    下面开始来讲权重的计算获取。

    空间距离:指的是当前点与中心点的欧式距离。空间域高斯函数其数学形式为:

                                                        d(i,j,k,l)=exp(-\frac{(i-k)^{2}+(j-l)^{2}}{2\sigma _{d}^{2}}) 

    (i, j)代表输出点;(k, l)代表(多个)输入点;sigma为空间域标准差。

    这也叫定义域核的表示形式,叫这个名字的原因,个人理解是:这里的权重只和平面位置距离有关,只和x、y有关。同时可以发现,这公式其实就是高斯滤波的公式。

    灰度距离:指的是当前点灰度与中心点灰度的差的绝对值。值域高斯函数其数学形式为:

                                           r(i,j,k,l)=exp(-\frac{\left \| f(i,j)^{2}-f(k,l)^{2} \right \|}{2\sigma_{r} ^{2}})

    (i, j)代表输出点;(k, l)代表(多个)输入点;sigma为值域标准差。

    同样,这也叫值域核的表示形式,理由和上面类似,其所求结果r只与灰度值有关。

    将上述两公式相乘就可以得到,依赖数据的双边滤波权重函数:

                         \omega (i,j,k,l)=exp(-\frac{(i-k)^{2}+(j-l)^{2}}{2\sigma_{d} ^{2}}-\frac{\left \| f(i,j)^{2}-f(k,l)^{2} \right \|}{2\sigma_{r} ^{2}})

    至此,即得到了双边滤波的权重,最后在将权重与像素对应相乘相加再除以权重和,即求出最后输出像素值。

                                                 g(i,j)=\frac{\sum _{k,l}f(k,l)\omega (i,j,k,l)}{\sum _{k,l}\omega (i,j,k,l)}

    再求出权重后,如果先归一化,最后这一步其实是在求卷积。个人认为,双边滤波的算法流程也是先求出一个核,只是这个核是在高斯核的基础上乘了一个代表灰度相似程度的一个权重,最后在进行类似卷积操作。

     

    以上,便是部分了。本人小白一枚,有错还请指出,欢迎探讨。

    展开全文
  • 常见的图像滤波算法

    千次阅读 2019-05-13 18:54:00
    本文介绍五种常见的图像滤波方式:线性滤波(方框滤波、均值滤波、高斯滤波);非线性滤波(中值滤波、双边滤波)。提醒,本文主要是算法公式,没有具体完整的代码。 一、线性滤波 总的来说,这三种线性滤波原理...

    本文介绍五种常见的图像滤波方式:线性滤波(方框滤波、均值滤波、高斯滤波);非线性滤波(中值滤波、双边滤波)。提醒,本文主要是算法公式,没有具体完整的代码。

     

    一、线性滤波

    总的来说,这三种线性滤波原理:每个像素的输出值是输入像素的加权和。其处理方式都是将图像像素与相应的核进行卷积,核即是权重(下图中中间3*3大小的图就是核),其作用是将原图像素按权重进行分配。简单讲,卷积就是选取原图像与核相同大小的部分(下图左侧对照部分),然后与核对应相乘相加,所得的值赋给原图中的锚点(下图是中心点,右侧对照部分)(有关卷积的讲解可参考下图的转载链接)。

    卷积(图像转自https://blog.csdn.net/zouxy09/article/details/49080029,侵删)

    所以说,这三种滤波方式的区别在于卷积核的不同,下面分别叙述。

     

    1.1方框滤波和均值滤波的卷积核

    如下图,K即为方框滤波的核,可以看到无论a为何值,矩阵内的每一个元素都相等,卷积时对像素的权重都一样。均值滤波是方框滤波归一化后的特殊处理,下图中,当normalize = ture时的K为均值滤波的核。个人觉得,方框滤波和均值滤波没有实质上的区别。

     

    1.2高斯滤波的卷积核

    我们先来看一下一维高斯函数,如下图,a代表尖峰高度,b代表尖峰中心的x坐标,c是标准方差,代表尖峰的宽度。图3表示“3σ”原则,意思是,虽然定义域的范围是正无穷到负无穷,但是曲线的绝大部分都在“-3σ - 3σ”之间。

         ​   

                             一维高斯函数(图1、2转载自https://blog.csdn.net/jorg_zhao/article/details/52687448,侵删)

    接下来我们看看二维高斯函数,其服从当ρ=0时的二维正态分布,即x、y不相关。同样,参照一维高斯函数,A是幅值,即高度;x。y。是中心点坐标;σσy是方差,代表底面的两个方向上的宽度。

              ​     

                           二维高斯函数(转载自https://blog.csdn.net/jorg_zhao/article/details/52687448,侵删)

    在计算高斯核时,由于在x、y两个方向上我们所需要的宽度是完全一致的,所以我们可以取σx = σy,这时公式变为

                                          A=\frac{1}{2\pi \sigma^{2}}                   G(x,y)=Aexp(-(\frac{(x-x_{0})^{2} + (y-y_{0})^{2}}{2\sigma ^{2}}))

    由上述公式,我们就可以求出高斯核,代码如下

    //******************高斯卷积核生成函数*************************
    //第一个参数Guass是存高斯卷积核的二维数组
    //第二个参数size是高斯卷积核的尺寸大小;
    //第三个参数sigma是卷积核的标准差
    //*************************************************************
    void CDisplay::GetGaussianKernel(double **Guass, const int size, const double sigma)
    {
        const double PI = 4.0*atan(1.0); //圆周率π赋值
        int center = size / 2;
        double sum = 0;
        for (int i = 0; i<size; i++)
        {
            for (int j = 0; j<size; j++)
            {
                Guass[i][j] = (1 / (2 * PI*sigma*sigma))*exp(-((i - center)*(i - center) + (j - center)*(j - center)) / (2 * sigma*sigma));
                sum += Guass[i][j];
            }
        }
        for (int i = 0; i<size; i++)    //归一化
        {
            for (int j = 0; j<size; j++)
            {
                Guass[i][j] /= sum;
            }
        }
    }

    sigma与size值的选取:一般其情况,size = sigma*3+1,因为“3σ”原则。

     

    二、非线性滤波

    2.1中值滤波

    基本思想:用像素点邻域灰度值的中值来代替该像素点的灰度值。

    如下图,将中心点周围被称为邻域的像素点(包括自身)进行排序,取排序后9个像素值中间值作为当前新的像素值。

                        中值滤波原理图(图片转载自https://blog.csdn.net/qq_36359022/article/details/80116137,侵删)

     

     2.2双边滤波

    基于空间分布的高斯滤波函数,其核为一个与空间距离相关的高斯函数与一个灰度距离相关的高斯函数相乘所得。简单说就是高斯滤波的加强版,在高斯滤波中,只有关于空间距离的权重,离中心点越远,权重越小,而双边滤波在此基础上添加了关于灰度距离的权重,邻域中的像素灰度值越接近中心点灰度值,权重越大。

    下面开始来讲权重的计算获取。

    空间距离:指的是当前点与中心点的欧式距离。空间域高斯函数其数学形式为:

                                                        d(i,j,k,l)=exp(-\frac{(i-k)^{2}+(j-l)^{2}}{2\sigma _{d}^{2}}) 

    (i, j)代表输出点;(k, l)代表(多个)输入点;sigma为空间域标准差。

    这也叫定义域核的表示形式,叫这个名字的原因,个人理解是:这里的权重只和平面位置距离有关,只和x、y有关。同时可以发现,这公式其实就是高斯滤波的公式。

    灰度距离:指的是当前点灰度与中心点灰度的差的绝对值。值域高斯函数其数学形式为:

                                           r(i,j,k,l)=exp(-\frac{\left \| f(i,j)^{2}-f(k,l)^{2} \right \|}{2\sigma_{r} ^{2}})

    (i, j)代表输出点;(k, l)代表(多个)输入点;sigma为值域标准差。

    同样,这也叫值域核的表示形式,理由和上面类似,其所求结果r只与灰度值有关。

    将上述两公式相乘就可以得到,依赖数据的双边滤波权重函数:

                         \omega (i,j,k,l)=exp(-\frac{(i-k)^{2}+(j-l)^{2}}{2\sigma_{d} ^{2}}-\frac{\left \| f(i,j)^{2}-f(k,l)^{2} \right \|}{2\sigma_{r} ^{2}})

    至此,即得到了双边滤波的权重,最后在将权重与像素对应相乘相加再除以权重和,即求出最后输出像素值。

                                                 g(i,j)=\frac{\sum _{k,l}f(k,l)\omega (i,j,k,l)}{\sum _{k,l}\omega (i,j,k,l)}

    再求出权重后,如果先归一化,最后这一步其实是在求卷积。个人认为,双边滤波的算法流程也是先求出一个核,只是这个核是在高斯核的基础上乘了一个代表灰度相似程度的一个权重,最后在进行类似卷积操作。

     

    以上,便是部分了。本人小白一枚,有错还请指出,欢迎探讨。

    转载于:https://www.cnblogs.com/wy1996/p/10858376.html

    展开全文
  • 今天主要总结图像的几种滤波方式,见下图 五种常见的图像滤波方式:线性滤波(方框滤波、均值滤波、高斯滤波);非线性滤波(中值滤波、双边滤波)。 图片来源于:...


    今天主要总结图像的几种滤波方式,见下图

    五种常见的图像滤波方式:线性滤波(方框滤波、均值滤波、高斯滤波);非线性滤波(中值滤波、双边滤波)。

    图形滤波
    图片来源于:https://blog.csdn.net/qq_27261889/article/details/80822270侵删

    1. 先人为的给图像加噪声

    #给图像加噪声
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    #读取图片
    im = cv2.imread('D:\pythonb\wx020.jpg')
    rows, cols, chn = im.shape  #把图像的行数返回给rows,列数返回给cols
    
    #加噪声
    for i in range(5000):
        x = np.random.randint(0, rows)
        y = np.random.randint(0, cols)
        im[x, y, :] = 0
        
    #等待显示
    cv2.imshow("noise", im)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    运行结果如下:
    加入噪声

    2.滤波处理

    2.1 均值滤波

    均值滤波:均值滤波是指任意一点的像素值,都是周围N*M个像素值的均值。核心函数为:result = cv2.blur(原始图像,核大小);核大小是以(宽度,高度)表示的元祖形式:

    2.2 高斯滤波

    高斯滤波:在图像高斯平滑中,图像中不同位置的像素与其对应核中的权重相乘,然后再求和。与均值滤波不同的是,核中的权重大小不等。

    下图是核分别为 3 * 3 和 5 * 5 的高斯滤波。
    核为3*3
    核为5*5
    图片来源于:https://blog.csdn.net/Eastmount/article/details/82216380 侵删

    核心函数为:dst = cv2.GaussianBlur(src, ksize, sigmaX)
    src:原始图像名称,ksize:核大小,sigmaX表示X方向方差。核大小(N, N)必须是奇数。

    2.3. 中值滤波

    中值滤波:选一个含有奇数点的窗口W,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。
    中值滤波对于消除孤立点和线段的干扰十分有用, 对于一些细节较多的复杂图像,可以多次使用不同的中值滤波

    核心函数为:dst = cv2.medianBlur(src, ksize)
    src: 图像名称,ksize: 核大小。核必须是大于1的奇数,如3、5、7等。

    python运行代码如下:

    #为后面标题加入中文字体支持
    from matplotlib.font_manager import FontProperties
    font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc",size = 14)
    
    #把BGR模式转换成RGB模式
    img = cv2.cvtColor(im,cv2.COLOR_BGR2RGB)
    
    # 均值滤波
    img_mean = cv2.blur(img, (5,5)) #核大小是以(宽度,高度)表示的元祖形式:(5,5)
    
    # 高斯滤波
    img_Guassian = cv2.GaussianBlur(img,(5,5),0)
    
    # 中值滤波
    img_median = cv2.medianBlur(img, 5)
    
    # 双边滤波
    img_bilater = cv2.bilateralFilter(img,9,75,75)
    
    # 展示不同的图片
    titles = ['原图','均值滤波', '高斯滤波', '中值滤波', '中值滤波']
    'bilateral']
    imgs = [img, img_mean, img_Guassian, img_median, img_bilater]
    
    for i in range(5):
        plt.subplot(2,3,i+1)  #注意,这和matlab中类似,没有0,数组下标从1开始
        plt.imshow(imgs[i])
        plt.title(titles[i], fontproperties= font)
        plt.xticks([]), plt.yticks([])
    plt.show()
    

    运行结果如下图所示:
    在这里插入图片描述
    由上图可见,中值滤波对于去除椒盐噪声的处理效果最好.

    以上文章参考博客:https://blog.csdn.net/qq_27261889/article/details/80822270

    (by:dxz 2020 03 12 )

    展开全文
  • 提出三种计算近均值规则和两种噪声判断方案,组合设计了九种滤波算法。在与均值滤波、中值滤波及部分改进滤波算法进行实验对比后,确定提出第七种滤波算法具有更好滤波效果,能适应不同类型噪声,其普适性...
  • 常见的就是第一滑窗实现,只有当离散化的窗口非常大,用滑窗计算量非常大(即使用可分离滤波器的实现)的情况下,可能会考虑基于傅里叶变化的实现方法。本次我们只讨论离散化窗口卷积。 高斯滤波原理 高斯

    认识高斯滤波

    高斯滤波也叫高斯模糊,是一种线性平滑滤波器,高斯滤波适用于去除高斯噪声,即服从正态分布的噪声,在很多图像预处理的时候经常会用到高斯滤波来消除噪声。结合前篇均值滤波的博文,高斯滤波其实就是将滤波模板换成了高斯模板。在图像处理中,高斯滤波一般有两种实现方式,一是用离散化窗口滑窗卷积,另一种通过傅里叶变换。最常见的就是第一种滑窗实现,只有当离散化的窗口非常大,用滑窗计算量非常大(即使用可分离滤波器的实现)的情况下,可能会考虑基于傅里叶变化的实现方法。本次我们只讨论离散化窗口卷积。

    高斯滤波原理

    高斯滤波也是使用模板与图像进行卷积,与全部为一的均值滤波模板不同的地方在于高斯模板是从中心开始越远离中心值越小,相比均值滤波更能更能保持图像的细节。

    二维高斯分布函数

    二维高斯分布函数如下:
    在这里插入图片描述
    (x,y)为掩码内任意一点的坐标,(u,v)是掩码中心坐标,σ是其标准差。σ代表着数据的离散程度,如果σ较小,那么生成的模板的中心系数较大,而周围的系数较小,这样对图像的平滑效果就不是很明显;反之,如果σ较大,则生成的模板的各个系数相差就不是很大,相对来说对图像的平滑效果比较明显。我们计算的时候为了减少计算量把这一项在这里插入图片描述
    省略掉,因为它是常数,最后要进行归一化,不计算也没关系。
    在这里插入图片描述
    上图是一维高斯函数的函数图,可以很容易的联想到二维的情况。由该函数计算出来的模板需要进行归一化,也就是将计算出来的每个系数的值再除以所有系数的和,归一化的好处是能够保证之后卷积得出的新像素值再0到255的范围内。

    代码实现

    #include <opencv2/opencv.hpp>
    #include<iostream>
    
    using namespace cv;
    using namespace std;
    
    //计算高斯模板
    void getGaussianMask(Mat& mask, Size ksize, double sigma)
    {
    	if (ksize.width % 2 == 0 || ksize.height % 2 == 0)
    	{
    		cout << "please input odd ksize!" << endl;
    		exit(-1);
    	}
    	mask.create(ksize, CV_64F);
    	int h = ksize.height;
    	int w = ksize.width;
    	int center_h = (ksize.height - 1) / 2;
    	int center_w = (ksize.width - 1) / 2;
    	double sum = 0;
    	double x, y;
    	for (int i = 0; i < h; i++)
    	{
    		x = pow(i - center_h, 2);
    		for (int j = 0; j < w; j++)
    		{
    			y = pow(j - center_w, 2);
    			mask.at<double>(i, j) = exp(-(x + y) / (2 * sigma*sigma));
    			sum += mask.at<double>(i, j);
    		}
    	}
    	mask = mask / sum;
    }
    
    //用二维高斯函数实现高斯滤波
    void myGaussianBlur(const Mat& src, Mat& dst, Mat mask)
    {
    	int hh = (mask.rows - 1) / 2;
    	int hw = (mask.cols - 1) / 2;
    	dst = Mat::zeros(src.size(), src.type());
    
    	//边界填充
    	Mat newsrc;
    	copyMakeBorder(src, newsrc, hh, hh, hw, hw, BORDER_DEFAULT);
    
    	//高斯滤波
    	for (int i = hh; i < src.rows + hh; i++)
    	{
    		for (int j = hw; j < src.cols + hw; j++)
    		{
    			double sum[3] = { 0 };
    			for (int r = -hh; r <= hh; r++)
    			{
    				for (int c = -hw; c <= hw; c++)
    				{
    					if (src.channels() == 1)
    					{
    						sum[0] += newsrc.at<uchar>(i + r, j + c)*mask.at<double>(r + hh, c + hw);
    					}
    					else if(src.channels() == 3)
    					{
    						sum[0] += newsrc.at<Vec3b>(i + r, j + c)[0] * mask.at<double>(r + hh, c + hw);
    						sum[1] += newsrc.at<Vec3b>(i + r, j + c)[1] * mask.at<double>(r + hh, c + hw);
    						sum[2] += newsrc.at<Vec3b>(i + r, j + c)[2] * mask.at<double>(r + hh, c + hw);
    					}
    				}
    			}
    			for (int k = 0; k < src.channels(); k++)
    			{
    				if (sum[k] < 0)sum[k] = 0;
    				else if (sum[k] > 255)sum[k] = 255;
    			}
    			if (src.channels() == 1)
    			{
    				dst.at<uchar>(i - hh, j - hw) = static_cast<uchar>(sum[0]);
    			}
    			else if (src.channels() == 3)
    			{
    				Vec3b rgb = { static_cast<uchar>(sum[0]) ,static_cast<uchar>(sum[1]) ,static_cast<uchar>(sum[2]) };
    				dst.at<Vec3b>(i - hh, j - hw) = rgb;
    			}
    		}
    	}
    }
    int main()
    {
    	Mat src = imread("C:/Users/msi-/Desktop/picture/witcher_logo.jpg");
    	imshow("原图", src);
    	Mat mask,dst;
    	getGaussianMask(mask, Size(5, 5), 0.8);
    	myGaussianBlur(src, dst, mask);
    	imshow("效果图",dst);
    	waitKey();
    	return 0;
    }
    

    分离高斯函数实现高斯滤波

    由于高斯函数的可分离性,我们还可以用一种计算量相对小的方法实现高斯滤波。首先将图像在水平(竖直)方向与一维高斯函数进行卷积;然后将卷积后的结果在竖直(水平)方向使用相同的一维高斯函数得到的模板进行卷积运算。
    假设水平方向的mask1的尺寸为1×W1,竖直方向的mask2的尺寸为H2×1,输入图片src的尺寸为H×W,第一种方法计算量大概为:(H×W)×(H2×W1)
    第二种方法的计算量大概为:
    (H×W)×(H2+W1)

    代码实现

    //用分离高斯函数实现高斯滤波
    void separateGaussianFilter(const Mat& src, Mat& dst, int ksize, double sigma)
    {
    	dst = Mat::zeros(src.size(), src.type());
    
    	//获取一维高斯滤波模板
    	Mat mask;
    	mask.create(1, ksize, CV_64F);
    	int center = (ksize - 1) / 2;
    	double sum = 0.0;
    	for (int i = 0; i < ksize; i++) 
    	{
    		mask.at<double>(0, i) = exp(-(pow(i - center, 2)) / (2 * sigma*sigma));
    		sum += mask.at<double>(0, i);
    	}
    	mask = mask / sum;
    
    	//边界填充
    	int boder = (ksize - 1) / 2;
    	Mat newsrc;
    	copyMakeBorder(src, newsrc, 0, 0, boder, boder, BORDER_DEFAULT);//边界复制
    
    	//高斯滤波--水平方向
    	for (int i = 0; i < src.rows; i++) 
    	{
    		for (int j = boder; j < src.cols + boder; j++) 
    		{
    			double sum[3] = { 0 };
    
    			for (int r = -boder; r <= boder; r++) 
    			{
    				if (src.channels() == 1) 
    				{
    					sum[0] += newsrc.at<uchar>(i, j + r) * mask.at<double>(0, r + boder); //行不变列变
    				}
    				else if (src.channels() == 3)
    				{
    					sum[0] += newsrc.at<Vec3b>(i, j + r)[0] * mask.at<double>(0, r + boder);
    					sum[1] += newsrc.at<Vec3b>(i, j + r)[1] * mask.at<double>(0, r + boder);
    					sum[2] += newsrc.at<Vec3b>(i, j + r)[2] * mask.at<double>(0, r + boder);
    				}
    			}
    			for (int k = 0; k < src.channels(); k++) 
    			{
    				if (sum[k] < 0)
    					sum[k] = 0;
    				else if (sum[k] > 255)
    					sum[k] = 255;
    			}
    			if (src.channels() == 1) 
    			{
    				dst.at<uchar>(i, j - boder) = static_cast<uchar>(sum[0]);
    			}
    			else if (src.channels() == 3) 
    			{
    				Vec3b rgb = { static_cast<uchar>(sum[0]), static_cast<uchar>(sum[1]), static_cast<uchar>(sum[2]) };
    				dst.at<Vec3b>(i, j - boder) = rgb;
    			}
    		}
    	}
    
    	//高斯滤波--垂直方向
    	//对水平方向处理后的dst边界填充
    	copyMakeBorder(dst, newsrc, boder, boder, 0, 0, BORDER_DEFAULT);//边界复制
    	for (int i = boder; i < src.rows + boder; i++)
    	{
    		for (int j = 0; j < src.cols; j++)
    		{
    			double sum[3] = { 0 };
    
    			for (int r = -boder; r <= boder; r++)
    			{
    				if (src.channels() == 1) 
    				{
    					sum[0] = sum[0] + newsrc.at<uchar>(i + r, j) * mask.at<double>(0, r + boder); 
    				}
    				else if (src.channels() == 3) 
    				{
    					Vec3b rgb = newsrc.at<Vec3b>(i + r, j);
    					sum[0] = sum[0] + rgb[0] * mask.at<double>(0, r + boder);
    					sum[1] = sum[1] + rgb[1] * mask.at<double>(0, r + boder);
    					sum[2] = sum[2] + rgb[2] * mask.at<double>(0, r + boder);
    				}
    			}
    			for (int k = 0; k < src.channels(); k++) 
    			{
    				if (sum[k] < 0)
    					sum[k] = 0;
    				else if (sum[k] > 255)
    					sum[k] = 255;
    			}
    			if (src.channels() == 1) 
    			{
    				dst.at<uchar>(i - boder, j) = static_cast<uchar>(sum[0]);
    			}
    			else if (src.channels() == 3)
    			{
    				Vec3b rgb = { static_cast<uchar>(sum[0]), static_cast<uchar>(sum[1]), static_cast<uchar>(sum[2]) };
    				dst.at<Vec3b>(i - boder, j) = rgb;
    			}
    		}
    	}
    }
    

    结果算起来确实比第一种方法快不少。

    效果图

    原图
    在这里插入图片描述
    滤波后
    在这里插入图片描述

    参考文献

    展开全文
  • 均值滤波与中值滤波是最常见的平滑的方式,尤其是中值滤波能起到强大的降噪效果。 本文内容分为部分: 1.实现添加图片的椒盐噪声 2.实现调用内置函数进行均值和中值滤波 3.自编函数深刻理解均值和中值滤波 1....
  • 下面是一些常见的滤波器错误安装方式对滤波器性能影响的实例。输入线太长许多设备的电源线进入机箱后,经过很长的导线才接到滤波器的输入端。例如,电源线从机箱后面板输入,走行到前面板的电源开关,又回到后面板...
  • 常见的辐射耦合有三种:1)一个天线发射的电磁波被另一个天线意外地接收,称为天线对天线的耦合;2)空间电磁场经导线感应而耦合,称为场对线的耦合。3)两根平等导线之间的高频信号相互感应而形成的耦合,称为线对...
  • 常见的辐射耦合有三种:1)一个天线发射的电磁波被另一个天线意外地接收,称为天线对天线的耦合;2)空间电磁场经导线感应而耦合,称为场对线的耦合。3)两根平等导线之间的高频信号相互感应而形成的耦合,称为线对...
  • 该算法首先对音频数据进行自适应分段,然后在空域部分均值化音频数据,最后在级小波变换低频系数上以抖动调制的方式实现水印信息嵌入。实验结果表明所提出算法对缩放攻击具有很好鲁棒性,并能够抵抗加噪、...
  • 当计时器经营在稳定或振荡运作方式下,这输入能用来改变或调整输出频率。 Pin 6 (重置锁定) - Pin 6重置锁定并使输出呈低态。当这个接脚电压从1/3 VCC电压以下移至2/3 VCC以上时启动这个动作。 Pin 7 (放电) ...
  • 按一次该键则显示下一个时间值,个值循环显示,当按下“确认”键时,就选定当前显示值供系统使用,按“复位”键则清除该次时间设定。 “会议电话”: 该键为召开电话会议按键。电话会议设置用户1为主叫方,...
  • 种常见的替代方案是采用开关转换器,它将能量交替存储在电感的磁场中,然后以不同的电压释放给负载。这种方案的损耗较低,是一更好的选择,可实现高效率运行。 本文介绍降压型转换器,它提供较低的输出电压。升压型...
  • 13.1.5 几常用小波 13.1.6 小波应用演示示例 13.2 小波工具箱介绍 13.2.1 小波工具箱启动 13.2.2 一维连续小波分析工具 13.2.3 一维离散小波分析工具 13.3 小波分析在图像处理中应用 13.3.1 ...
  • 13.1.5 几常用小波 13.1.6 小波应用演示示例 13.2 小波工具箱介绍 13.2.1 小波工具箱启动 13.2.2 一维连续小波分析工具 13.2.3 一维离散小波分析工具 13.3 小波分析在图像处理中应用 13.3.1 ...
  • 2.1 常见的数学函数 398 2.1.1 求整数的绝对值 398 范例2-1 求整数的绝对值 398 ∷相关函数:abs函数 2.1.2 求长整型整数的绝对值 399 范例2-2 求长整型整数的绝对值 399 ∷相关函数:labs函数 2.1.2 求...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    常见的有HOLTEK-p.htm" target="_blank" title="HOLTEK货源和PDF资料">HOLTEK MCU系列、Microchip MCU系列及8051等。 嵌入式DSP专门用来处理对离散时间信号进行极快的处理计算,提高编译效率和执行速度。在...
  • 介绍下机器学习和深度学习中常见的参数类算法和非参数类算法 随机梯度下降 神经网络训练如何解决过拟合和欠拟合 L1正则化和L2正则化区别,具体有何用途 L1正则化相比于 L2正则化为何具有稀疏解 2. C++开发...
  • C 开发金典

    2013-06-20 16:20:03
    2.1 常见的数学函数 398 2.1.1 求整数的绝对值 398 范例2-1 求整数的绝对值 398 ∷相关函数:abs函数 2.1.2 求长整型整数的绝对值 399 范例2-2 求长整型整数的绝对值 399 ∷相关函数:labs函数 2.1.2 求...
  • C语言通用范例开发金典.part2.rar

    热门讨论 2012-08-31 14:18:18
    2.1 常见的数学函数 398 2.1.1 求整数的绝对值 398 范例2-1 求整数的绝对值 398 ∷相关函数:abs函数 2.1.2 求长整型整数的绝对值 399 范例2-2 求长整型整数的绝对值 399 ∷相关函数:labs函数 2.1.2 求...
  • Proteus仿真—40个单片机初学程序.

    热门讨论 2009-04-13 13:00:56
    单片机对开关状态检测相对于单片机来说,是从单片机P3.0端口输入信号,而输入信号只有高电平和低电平两,当拨开开关K1拨上去,即输入高电平,相当开关断开,当拨动开关K1拨下去,即输入低电平,相当开关闭合...

空空如也

空空如也

1 2
收藏数 21
精华内容 8
关键字:

常见的三种滤波方式