码迷,mamicode.com
首页 > 其他好文 > 详细

OpenCV2学习笔记(五):图像滤波基础

时间:2015-02-24 23:29:34      阅读:369      评论:0      收藏:0      [点我收藏+]

标签:qt   opencv   滤波   c++   边缘检测   

一:基本概念

滤波是数字图像处理中的一个基本操作,在信号处理领域可以说无处不在。图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,通常是数字图像处理中不可缺少的操作,其处理效果的好坏将直接影响到后续运算和分析的效果。简单来说,图像滤波的根本目的是在图像中提取出人类感兴趣的特征。

当我们观察一幅图像时,有两种处理方法:
1. 观察不同的灰度(或彩色值)在图像中的分布情况,即空间分布。
2. 观察图像中的灰度(或彩色值)的变化情况,这涉及到频率方面的问题。

因此,图像滤波分为频域和空域滤波,简单来说,空域指用图像的灰度值来描述一幅图像;而频域指用图像灰度值的变化来描述一幅图像。而低通滤波器和高通滤波器的概念就是在频域中产生的。低通滤波器旨在去除图像中的高频成分,而高通滤波器则是去除了图像中的低频成分。

这里简单记录以下低通滤波器中的均值和高斯滤波器(线性滤波器)、中值滤波器(非线性滤波器);高通滤波器中的sobel算子(方向滤波器)和拉普拉斯变换(二阶导数),其中,sobel算子和拉普拉斯变换均可以对图像的边缘进行检测。

二:低通滤波器
消除图像中的噪声成分叫作图像的平滑化或低通滤波。信号或图像的能量大部分集中在幅度谱的低频和中频段是很常见的,而在较高频段,感兴趣的信息经常被噪声淹没。因此一个能降低高频成分幅度的滤波器就能够减弱噪声的影响。
图像滤波的目的有两个:一是抽出对象的特征作为图像识别的特征模式;另一个是为适应图像处理的要求,消除图像数字化时所混入的噪声。
当然,在设计低通滤波器时,要考虑到滤波对图像造成的细节丢失等问题。

平滑滤波是低频增强的空间域滤波技术。它的目的有两类:一类是图像模糊;另一类是滤除图像噪声。
空间域的平滑滤波一般采用简单平均法进行,就是求邻近像元点的平均灰度值或亮度值。邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。
关于滤波器,一种形象的比喻法是:我们可以把滤波器想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口放到图像之上,透过这个窗口来看我们得到的图像。
滤波器的种类有很多, 在OpenCV中,提供了如下几种常用的图像平滑处理操作方法及函数:
1.领域均值滤波:blur函数,将图像的每个像素替换为相邻矩形内像素的平均值(均值滤波)
2.高斯低通滤波:GaussianBlur函数
3.方框滤波:boxblur函数
4.中值滤波:medianBlur函数
5.双边滤波:bilateralFilter函数

以下是均值滤波和高斯低通滤波的简单代码(未修改):

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

int main()
{
    // Read input image
    cv::Mat image= cv::imread("../boldt.jpg",0);
    if (!image.data)
        return 0; 

    // Display the image
    cv::namedWindow("Original Image");
    cv::imshow("Original Image",image);

    // Blur the image
    cv::Mat result;
    cv::GaussianBlur(image,result,cv::Size(5,5),1.5);

    // Display the blurred image
    cv::namedWindow("Gaussian filtered Image");
    cv::imshow("Gaussian filtered Image",result);

    // Get the gaussian kernel (1.5)
    cv::Mat gauss= cv::getGaussianKernel(9,1.5,CV_32F);

    // Display kernel values
    cv::Mat_<float>::const_iterator it= gauss.begin<float>();  
    cv::Mat_<float>::const_iterator itend= gauss.end<float>();  
    std::cout << "[";
    for ( ; it!= itend; ++it) {
        std::cout << *it << " ";
    }
    std::cout << "]" << std::endl;

    // Get the gaussian kernel (0.5)
    gauss= cv::getGaussianKernel(9,0.5,CV_32F);

    // Display kernel values
    it= gauss.begin<float>();  
    itend= gauss.end<float>();  
    std::cout << "[";
    for ( ; it!= itend; ++it) {
        std::cout << *it << " ";
    }
    std::cout << "]" << std::endl;

    // Get the gaussian kernel (2.5)
    gauss= cv::getGaussianKernel(9,2.5,CV_32F);

    // Display kernel values
    it= gauss.begin<float>();  
    itend= gauss.end<float>();  
    std::cout << "[";
    for ( ; it!= itend; ++it) {
        std::cout << *it << " ";
    }
    std::cout << "]" << std::endl;

    // Get the Deriv kernel (2.5)
    cv::Mat kx, ky;
    cv::getDerivKernels(kx,ky,2,2,7,true);

    // Display kernel values
    cv::Mat_<float>::const_iterator kit= kx.begin<float>();  
    cv::Mat_<float>::const_iterator kitend= kx.end<float>();  
    std::cout << "[";
    for ( ; kit!= kitend; ++kit) {
        std::cout << *kit << " ";
    }
    std::cout << "]" << std::endl;

    // Blur the image with a mean filter
    cv::blur(image,result,cv::Size(5,5));

    // Display the blurred image
    cv::namedWindow("Mean filtered Image");
    cv::imshow("Mean filtered Image",result);

    // Read input image with salt&pepper noise
    image= cv::imread("../salted.bmp",0);
    if (!image.data)
        return 0; 

    // Display the S&P image
    cv::namedWindow("S&P Image");
    cv::imshow("S&P Image",image);

    // Blur the image with a mean filter
    cv::blur(image,result,cv::Size(5,5));

    // Display the blurred image
    cv::namedWindow("Mean filtered S&P Image");
    cv::imshow("Mean filtered S&P Image",result);

    // Applying a median filter
    cv::medianBlur(image,result,5);

    // Display the blurred image
    cv::namedWindow("Median filtered S&P Image");
    cv::imshow("Median filtered S&P Image",result);

    // Reduce by 4 the size of the image (the wrong way)
    image= cv::imread("../boldt.jpg",0);
    cv::Mat reduced(image.rows/2,image.cols/2,CV_8U);

    for (int i=0; i<reduced.rows; i++)
        for (int j=0; j<reduced.cols; j++)
            reduced.at<uchar>(i,j)= image.at<uchar>(i*2,j*2);

    // Display the reduced image
    cv::namedWindow("Badly reduced Image");
    cv::imshow("Badly reduced Image",reduced);

    cv::waitKey();
    return 0;
}

未完待续……

OpenCV2学习笔记(五):图像滤波基础

标签:qt   opencv   滤波   c++   边缘检测   

原文地址:http://blog.csdn.net/liyuefeilong/article/details/43927909

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!