【opencv学习笔记1】5种图像滤波辨析:方框、均值、高斯、中值、双边

图像滤波

  1. 什么是图像滤波

    图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。

  2. 图像滤波的目的

    a、消除图像中混入的噪声

    b、为图像识别抽取出图像特征

  3. 图像滤波的要求

    a、不能损坏图像轮廓及边缘

    b、图像视觉效果应当更好

  4. 滤波器的定义

    滤波器,顾名思义,是对波进行过滤的器件。(摘自网络)

    以上的定义是针对物理器件的,但对于图像滤波而言显然也是适用的。

    大家都用过放大镜,这里就以此举一个例子:

    你将放大镜移动的过程中可以看到放大的物体,滤波器就是一个承载着加权系数的镜片,这里就是透过镜片可以看到经过平滑处理过的图像,透过镜片以及伴随着镜片的移动你可以逐渐所有的图像部分

  5. 滤波器的种类

    3种线性滤波:方框滤波、均值滤波、高斯滤波

    2种非线性滤波:中值滤波、双边滤波

  6. 方框滤波

    方框滤波所用到的核:

    当normaize为true时,方框滤波也就成了均值滤波。也就是说均值滤波是方框滤波归一化后的特殊情况。

    归一化就是要将要处理的量缩放到一定范围,比如(0, 1)。

  7. 均值滤波

    如上所说,均值滤波就是normalize为true的情况,此时就是在平均值。均值滤波在去噪的同时破坏了图像的细节部分,也使得图像变得更加模糊。

  8. 高斯滤波

    高斯滤波则不同,其能够很好的消除噪声。高斯滤波过程中,每个像素点都是由本身和领域内的其他像素值经过加权平均后得到的。

    从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积,由于正态分布也被称之为高斯分布,因此这项技术被称为高斯模糊。

    由于高斯函数的傅里叶变换是另外一个高斯函数,所以高斯模糊对图像来说就是一个低通滤波器。

    N维空间正态分布方程和二维空间正态分布分别为:

  9. 中值滤波

    中值滤波的基本思想是用像素点领域灰度值的中值来代替该像素的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时还能保留图像的细节部分。

    中值滤波花费的时间比均值滤波更久,但其在噪声的消除能力上更强。

  10. 双边滤波

    双边滤波是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空间域信息和灰度相似性,达到保留边缘且去除噪声的目的。

  11. 函数原型

a、方框滤波

    void boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor = Point(-1,-1),
bool normalize = true, int borderType = BORDER_DEFAULT)    

b、均值滤波

    void blur(Input src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT)

c、中值滤波

   void medianBlur(InputArray src, OutputArray dst, int ksize)

d、双边滤波

    void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace,
int borderType = BORDER_DEFAULT)

12.具体参数解析

InputArray src:
    输入图像(源图像),Mat类型对象,图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F、CV_64F之一。
    而对于中值滤波而言,如果ksize为3或者5时,图像深度必须是CV_8U、CV_16U、CV_32F之一,如果孔径较大,则只能是CV_8U。
OutputArray dst:
    输出图像(目标图像),和源图像的尺寸和类型均一样。
int ddepth:
    输出图像的深度,-1表示原图像深度(即src.depth())。
Size ksize:
    内核大小,用Size(w,h)来表示,w和h分别表示宽和高。
Point anchor:
    锚点,也就是被平滑的点,如果该点坐标为负值表示取核的中心,因此默认的(-1,-1)就表示锚点在核中心。
bool normalize:
    标识符,为true时表示内核被其余区域归一化(normalized)了。
int borderType:
    推断图像外部像素的某种边界模式。
double sigmaX:
    表示高斯核函数在X方向的标准偏差。
double sigmaY:
    表示高斯核函数在Y方向的标准偏差。
    当sigmaY为0时,就将其设为sigmaX;如果两者均为0,则由ksize.with和ksize.height计算出来,
    因此在高斯滤波函数中,ksize的w和h均必须是正数和奇数,或0,两者可以不同。
int ksize:
    孔径的线性空间,必须是大于1的奇数。
int d:
    过滤过程中每个像素邻域的直径,如果其值为非正数,则该值由sigmaSpace计算出来。
double sigmaColor:
    颜色空间滤波器的sigma值,这个参数的值越大,就表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
double sigmaSpace:
    坐标空间中滤波器的sigma值,坐标空间的标注方差。它的数值越大,意味着越远的像素会相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。
    当d>0时,d制定了邻域大小与sigmaSpace无关。否则,d正比于sigmaSpace。

13.示例代码

#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace std;
using namespace cv;

Mat g_srcImage;     // 全局的源图像
// 分别对应全局的方框滤波、均值滤波、高斯滤波、中值滤波、双边滤波的输出图像以及内核值/参数值
Mat g_dstImgBox, g_dstImgBlur, g_dstImgGaussian, g_dstImgMedian, g_dstImgBilateral;
int g_BoxFilterVal = 5;
int g_BlurVal = 12;
int g_GaussianBlurVal = 5;
int g_MedianBlurVal = 12;
int g_BilateralFilterVal = 12;

static void on_BoxFilter(int, void *);
static void on_Blur(int, void *);
static void on_GaussianBlur(int, void *);
static void on_MedianBlur(int, void *);
static void on_BilateralFilter(int, void*);

int main()
{
    // 读取图像到g_srcImage
    g_srcImage = imread("D:\\OpenCV\\ms2.png");
    if (!g_srcImage.data) {
        printf("读取的图片不存在…… \n");
        return false;
    }

    // 分别克隆原图到5中滤波所需的图像中,均为Mat类型
    g_dstImgBox = g_srcImage.clone();
    g_dstImgBlur = g_srcImage.clone();
    g_dstImgGaussian = g_srcImage.clone();
    g_dstImgMedian = g_srcImage.clone();
    g_dstImgBilateral = g_srcImage.clone();

    // 显示原图
    namedWindow("【原图】", 1);
    imshow("【原图】", g_srcImage);

    // 方框滤波
    namedWindow("【方框滤波】", 1);
    createTrackbar("内核值", "【方框滤波】", &g_BoxFilterVal, 30, on_BoxFilter);
    on_BoxFilter(g_BoxFilterVal, 0);

    namedWindow("【均值滤波】", 1);
    createTrackbar("内核值", "【均值滤波】", &g_BlurVal, 30, on_Blur);
    on_Blur(g_BlurVal, 0);             

    namedWindow("【高斯滤波】", 1);
    createTrackbar("内核值", "【高斯滤波】", &g_GaussianBlurVal, 30, on_GaussianBlur);
    on_GaussianBlur(g_GaussianBlurVal, 0);      

    namedWindow("【中值滤波】", 1);
    createTrackbar("内核值", "【中值滤波】", &g_MedianBlurVal, 30, on_MedianBlur);
    on_MedianBlur(g_MedianBlurVal, 0);  

    namedWindow("【双边滤波】", 1);
    createTrackbar("内核值", "【双边滤波】", &g_BilateralFilterVal, 30, on_BilateralFilter);
    on_BilateralFilter(g_BilateralFilterVal, 0);      

    cout << "按下“q”键时,程序退出……\n";
    while (char(waitKey(1)) != ‘q‘) {}   

    return 0;
}

static void on_BoxFilter(int, void *)
{
    boxFilter(g_srcImage, g_dstImgBox, -1, Size(g_BoxFilterVal + 1, g_BoxFilterVal + 1));
    imshow("【方框滤波】", g_dstImgBox);
}

static void on_Blur(int, void *)
{
    blur(g_srcImage, g_dstImgBlur, Size(g_BlurVal + 1, g_BlurVal + 1),
        Point(-1, -1));
    imshow("【均值滤波】", g_dstImgBlur);
}

static void on_GaussianBlur(int, void *)
{
    GaussianBlur(g_srcImage, g_dstImgGaussian, Size(g_GaussianBlurVal * 2 + 1,
        g_GaussianBlurVal * 2 + 1), 0, 0);
    imshow("【高斯滤波】", g_dstImgGaussian);
}

static void on_MedianBlur(int, void *)
{
    medianBlur(g_srcImage, g_dstImgMedian, g_MedianBlurVal * 2 + 1);
    imshow("【中值滤波】", g_dstImgMedian);
}

static void on_BilateralFilter(int, void*)
{
    bilateralFilter(g_srcImage, g_dstImgBilateral, g_BilateralFilterVal,
        g_BilateralFilterVal * 2, g_BilateralFilterVal / 2);
    imshow("【双边滤波】", g_dstImgBilateral);
}

14.图像滤波演示

时间: 2024-11-02 14:41:20

【opencv学习笔记1】5种图像滤波辨析:方框、均值、高斯、中值、双边的相关文章

【OpenCV】5种图像滤波辨析:方框、均值、高斯、中值、双边

图像滤波 什么是图像滤波 图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性.(摘自网络) 图像滤波的目的 1,消除图像中混入的噪声 2,为图像识别抽取出图像特征 图像滤波的要求 1,不能损坏图像轮廓及边缘 2,图像视觉效果应当更好 滤波器的定义 滤波器,顾名思义,是对波进行过滤的器件.(摘自网络) 以上的定义是针对物理器件的,但对于图像滤波而言显然也是适用的. 大家都用过放大镜,这里就

OpenCv学习笔记(四)--Mat基本图像容器Mat对象信息头,矩阵体的创建,深复制,浅复制详解

1--我们知道Mat是一个图像容器类,这个数据结构由两部分组成: 1--矩阵头--即class Mat类所实例化的类对象所开辟的空间里面存储的数据---就是这个矩阵的信息,当我们以 Mat object;这样声明类对象的时候,也仅仅是创建了一个Mat的信息头,并没有创建矩阵体,也就是说,我们并 没有给将要存储的图像开辟相应的空间 2--矩阵头--包含: 1--矩阵的尺寸----比如---class Mat这个类中的----数据成员rows,cols---就可以指定图像的尺寸 2--存储方法---

OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波

http://blog.csdn.net/chenyusiyuan/article/details/8710462 OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 2013-03-23 17:44 16963人阅读 评论(28) 收藏 举报 分类: 机器视觉(34) 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] KAZE系列笔记: OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 OpenCV学习笔记(28)KA

opencv学习笔记(03)——遍历图像(迭代器法)

1 #include <opencv2\highgui\highgui.hpp> 2 #include <opencv2\imgproc\imgproc.hpp> 3 #include <opencv2\core\core.hpp> 4 5 void colorReduce(cv::Mat& img, int div=64); 6 7 8 int main() 9 { 10 cv::Mat img_orginal = cv::imread("F:\\i

opencv学习笔记(02)——遍历图像(指针法)

#include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <iostream> void colorReduce(cv::Mat& image, int div=64) { int nr = image.rows; int nc = image.cols * image.

opencv学习笔记(01)——操作图像的像素

1 #include <opencv2\core\core.hpp> 2 #include <opencv2\highgui\highgui.hpp> 3 #include <opencv2\imgproc\imgproc.hpp> 4 #include <iostream> 5 6 7 void salt(cv::Mat& image, int n) 8 { 9 10 for(int k=0; k<n; k++) 11 { 12 13 int

Opencv学习笔记(六)SURF学习笔记

原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/7392345 本人挺菜的,肯定有非常多错误纰漏之处 ,希望大家不吝指正. 看了harris角点检測之后,開始研究SURF角点检測,发现挺复杂的,一时也仅仅了解了大概,把了解的东西总结下,以便下次深入学习. SURF角点检測算法是对SIFT的一种改进,主要体如今速度上,效率更高.它和SIFT的主要差别是图像多尺度空间的构建方法不同. 在计算视觉领域,尺度空间被象征性的表述

OpenCV 学习笔记(模板匹配)

OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够高时,就认为找到了我们的目标. 在 OpenCV 中,提供了相应的函数完成这个操作. matchTemplate 函数:在模板和输入图像之间寻找匹配,获得匹配结果图像 minMaxLoc 函数:在给定的矩阵中寻找最大和最小值,并给出它们的位置 在具体介绍这两个函数之前呢,我们还要介绍一个概念,就是如何来评价两

opencv学习笔记(七)SVM+HOG

opencv学习笔记(七)SVM+HOG 一.简介 方向梯度直方图(Histogram of Oriented Gradient,HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子.它通过计算和统计图像局部区域的梯度直方图来构成特征.Hog特征结合SVM分类器已经被广泛用于图像识别中,尤其在行人检测中获得了极大的成功.需要提醒的是,HOG+SVM进行行人检测的方法是法国研究院Dalal在2005的CVPR上提出的. 最近在做车标识别相关的研究,用到了SVM+HOG的方法进行识