opencv 高斯模糊

高斯模糊是一种图像模糊滤波器,它用正态分布计算图像中每个像素的变换。N 维空间正态分布方程为

在二维空间定义为

其中 r 是模糊半径 (r2 = u2 + v2),σ 是正态分布的标准偏差。在二维空间中,这个公式生成的曲面的等高线是从中心开始呈正态分布的同心圆。分布不为零的像素组成的卷积矩阵与原始图像做变换。每个像素的值都是周围相邻像素值的加权平均。原始像素的值有最大的高斯分布值,所以有最大的权重,相邻像素随着距离原始像素越来越远,其权重也越来越小。这样进行模糊处理比其它的均衡模糊滤波器更高地保留了边缘效果,参见尺度空间实现

理论上来讲,图像中每点的分布都不为零,这也就是说每个像素的计算都需要包含整幅图像。在实际应用中,在计算高斯函数的离散近似时,在大概3σ距离之外的像素都可以看作不起作用,这些像素的计算也就可以忽略。通常,图像处理程序只需要计算  的矩阵就可以保证相关像素影响。

除了圆形对称之外,高斯模糊也可以在二维图像上对两个独立的一维空间分别进行计算,这叫作线性可分。这也就是说,使用二维矩阵变换得到的效果也可以通过在水平方向进行一维高斯矩阵变换加上竖直方向的一维高斯矩阵变换得到。从计算的角度来看,这是一项有用的特性,因为这样只需要  次计算,而不可分的矩阵则需要  次计算,其中 M,N 是需要进行滤波的图像的维数,mn 是滤波器的维数。

对一幅图像进行多次连续高斯模糊的效果与一次更大的高斯模糊可以产生同样的效果,大的高斯模糊的半径是所用多个高斯模糊半径平方和的平方根。例如,使用半径分别为 6 和 8 的两次高斯模糊变换得到的效果等同于一次半径为 10 的高斯模糊效果,。根据这个关系,使用多个连续较小的高斯模糊处理不会比单个高斯较大处理时间要少。

在减小图像尺寸的场合经常使用高斯模糊。在进行欠采样的时候,通常在采样之前对图像进行低通滤波处理。这样就可以保证在采样图像中不会出现虚假的高频信息。高斯模糊有很好的特性,如没有明显的边界,这样就不会在滤波图像中形成震荡。

原文地址

实际应用中图像数据的类型可能是unsigned char ,float ,double ,因此我用自定义模板数据结构:

template<typename T>
class ImgType
{
public :
    T *data;
    int width;
    int height;
    int depth;
    int step;
    int channels;
};

我分别用x方向 y方向的高斯模糊来实现

template<typename Type>
void ImgAlgorithm<Type>::GaussianSmooth(ImgType<Type> *src,ImgType<Type> *&dst,double sigma)
{
    sigma=sigma>0?sigma:-sigma;
    //二维高斯和矩阵大小为 (6*sigma+1)*(6*sigma+1)
    //ksize为奇数
    int ksize = ((int)(sigma*3+0.5))*2+1;

    if(ksize==1)
    {
        dst=src;
        return;
    }

    //计算一维高斯核 G(r) = 1/sqrt(2*pi*sigma) * exp( -r*r/(2*sigma*sigma))
    double *kernel = new double[ksize];
    double scale = -0.5/(sigma*sigma);
    double cons = sqrt(-scale/PI);

    double sum = 0;
    int kcenter = ksize/2;
    for(int i=0;i<ksize;i++)
    {
        int x=i-kcenter;
        kernel[i]=cons*exp(x*x*scale);
        sum+=kernel[i];
    }
    //归一化,确保高斯权重在[0,1]之间
    printf("..gauss kernel:\n");
    printf("...sigma=%lf , kernelSize=%d\n",sigma,ksize);
    for(int i=0;i<ksize;i++)
    {
        kernel[i]/=sum;
        printf("...kernel[%d]=%lf\n",i,kernel[i]);
    }
    printf("kcenter %d\n",kcenter);

    dst=CreateImage(src->width,src->height,src->depth,src->channels);

    ImgType<Type> *tmp=CreateImage(src->width,src->height,src->depth,src->channels);

    Type a[3];//通道
    //x 方向一维高斯模糊
    for(int i=0;i<src->height;i++)
    {
        for(int j=0;j<src->width;j++)
        {
            a[0]=a[1]=a[2]=0;
            for(int k=0;k<src->channels;k++)
            {
                double sum=0;
                for(int d=-kcenter;d<=kcenter;d++)
                {
                    if(d+j>=0 && d+j<src->width)
                    {
                        a[k] += src->data[i*src->step+(d+j)*src->channels+k] * kernel[kcenter+d];
                        sum += kernel[kcenter+d];
                    }
                }
                tmp->data[i*src->step+j*src->channels+k]=a[k]/sum;
            }
        }
    }

    //y方向高斯模糊
    for(int i=0;i<src->height;i++)
    {
        for(int j=0;j<src->width;j++)
        {
            a[0]=a[1]=a[2]=0;
            for(int k=0;k<src->channels;k++)
            {
                double sum=0;
                for(int d=-kcenter;d<=kcenter;d++)
                {
                    if(d+i>=0 && d+i<src->height)
                    {
                        a[k] += tmp->data[(d+i)*src->step+j*src->channels+k] * kernel[kcenter+d];
                        sum += kernel[kcenter+d];
                    }
                }
                dst->data[i*src->step+j*src->channels+k]=a[k]/sum;
            }
        }
    }
    delete []kernel;
    FreeImage(tmp);
}

1x5高斯模糊矩阵值:

时间: 2024-10-09 17:40:29

opencv 高斯模糊的相关文章

OpenCV高斯模糊方法

纯粹阅读,请移步OpenCV高斯模糊方法 效果图 源码 KqwOpenCVBlurDemo 步骤 将获取到的Bitmap图片转成Mat对象 // Bitmap转为Mat Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4); Utils.bitmapToMat(bitmap, src); 调用OpenCV的高斯模糊方法 // 高斯模糊方法 Imgproc.GaussianBlur(src, src, ne

OpenCV之Python学习笔记

OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书<OpenCV Computer Vision with Python>,于是就看一遍,顺便把自己掌握的东西整合一下,写成学习笔记了.更需要的朋友参考. 阅读须知: 本文不是纯粹的译文,只是比较贴近原文的笔记:         请设法购买到出版社出版的书,支持正版. 从书名就能看出来本书是介绍在Pytho

Python下opencv使用笔记(五)(图像的平滑与滤波)

对于图形的平滑与滤波,但从滤波角度来讲,一般主要的目的都是为了实现对图像噪声的消除,增强图像的效果. 首先介绍二维卷积运算,图像的滤波可以看成是滤波模板与原始图像对应部分的的卷积运算.关于卷积运算,找到几篇相关的博客: 图像处理:基础(模板.卷积运算) 图像处理-模板.卷积的整理 对于2D图像可以进行低通或者高通滤波操作,低通滤波(LPF)有利于去噪,模糊图像,高通滤波(HPF)有利于找到图像边界. (一)统一的2D滤波器cv2.filter2D Opencv提供的一个通用的2D滤波函数为cv2

高斯模糊算法的全面优化过程分享(二)。

      相关链接: 高斯模糊算法的全面优化过程分享(一) 在高斯模糊算法的全面优化过程分享(一)一文中我们已经给出了一种相当高性能的高斯模糊过程,但是优化没有终点,经过上一个星期的发愤图强和测试,对该算法的效率提升又有了一个新的高度,这里把优化过程中的一些心得和收获用文字的形式记录下来. 第一个尝试   直接使用内联汇编替代intrinsics代码(无效) 我在某篇博客里看到说intrinsics语法虽然简化了SSE编程的难度,但是他无法直接控制XMM0-XMM7寄存器,很多指令中间都会用内

OpenCV官方文档学习记录(15)

laplace边缘检测方式 不同于sobel的一阶导数式边缘检测,laplace算子是将图像的横纵都考虑进来的一种检测,主要使用的是二阶偏导数进行离散变换: 因为laplace也是使用分析梯度的方式进行变换,所以实际上调用的是sobel的方法.在上一篇上有体现,就是在两个方向上分别使用sobel计算结果. 代码如下: 1 #include <opencv2\opencv.hpp> 2 #include <iostream> 3 #include <string> 4 5

OpenCV与EmguCV中的空间滤波

图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接响到后续图像处理和分析的有效性和可靠性.(滤波就是要去除没用的信息,保留有用的信息,可能是低频,也可能是高频) 滤波一词借用于频域处理.本意是指信号有各种频率的成分,滤掉不想要的成分,即为滤掉常说的噪声,留下想要的成分,这既是滤波的过程,也是滤波的目的. 滤波分为两种: 空间滤波与频域滤波. 空间滤波是将输入图像与滤波器模板相卷积,将最终计算结果之和作为输出的像素值. 频率域滤

基于opencv的车牌识别系统

前言 学习了很长一段时间了,需要沉淀下,而最好的办法就是做一个东西来应用学习的东西,同时也是一个学习的过程. 概述     OpenCV的全称是:Open Source Computer Vision Library.OpenCV是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS操作系统上.它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python.Ruby.MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算

opencv的实用研究--分析轮廓并寻找边界点

?      轮廓是图像处理中非常常见的.对现实中的图像进行采样.色彩变化.灰度变化之后,能够处理得到的是“轮廓”.它直接地反应你了需要分析对象的边界特征.而对轮廓的分析,实际上也就是对原图像特征的分析. 在Opencv中,已经实现了基础的轮廓算法,但是相比较于比如halcon这样的专业软件,在轮廓处理这块的功能还是比较缺乏的.这里就通过一个具体问题,说明自己的学习研究.不对之处欢迎批评. P.S这里的轮廓处理相关函数,已经包涵在GOBase中,具体可以到公告中找Github. 一.问题提出 那

opencv模拟景深效果

简介 在htc的相机应用中发现了一个叫景深的拍照场景,然后练习着用opencv来模拟实现. hcl景深场景效果 本例实现效果 实现过程 要实现本例,需要用到两方面知识:1.图像的高斯模糊. 2.在图像中去出感兴趣的圆形区域. 高斯模糊 用的是opencv函数:cvSmooth.该函数参数具体使用,看opencv官网的api介绍吧:http://docs.opencv.org/modules/refman.html #include <opencv2/core/core.hpp> #includ