使用OpenCV进行图片模糊处理(高斯滤波器)

来源:互联网 发布:mac如何更新软件 编辑:程序博客网 时间:2024/05/18 04:54

本篇博客主要介绍如何使用OpenCV自带的高斯滤波器来对图片进行处理,达到模糊图片的效果。在代码中通过使用一个TrackerBar动态改变。具体的还是根据代码来进行解释吧:
先看一下效果图:
这里写图片描述这里写图片描述这里写图片描述

gif不能截取很长时间而且效果图也不是很清晰,但是可以很明显的通过拖动TrackerBar使得图片更加模糊或者清晰了,下面来看一下具体实现的代码:

#include <iostream>#include <opencv2\opencv.hpp>using namespace cv;using namespace std;const char* source_window = "source";int initial_size = 1;int x = 0;int y = 0;Mat source, result;void onSizeChange(int position) {    cout << "y = " << x;    cout << " , x = " << y;    cout << " , initial_size = " << initial_size << endl;    if (position == 0) {        position = 1;    }    if (position%2 == 0) {        position += 1;    }    initial_size = position;    try {        GaussianBlur(source, result, Size(initial_size, initial_size),x,y);        imshow(source_window, result);    }    catch (Exception e) {        std::cout << "Exception message = " << e.msg << std::endl;    }}void onXChange(int position) {    cout << "y = " << x;    cout << " , x = " << y;    cout << " , initial_size = " << initial_size << endl;    x = position;    try {        GaussianBlur(source, result, Size(initial_size, initial_size), x, y);        imshow(source_window, result);    }    catch (Exception e) {        std::cout << "Exception message = " << e.msg << std::endl;    }}void onYChange(int position) {    cout << "y = " << x;    cout << " , x = " << y;    cout << " , initial_size = " << initial_size << endl;    y = position;    try {        GaussianBlur(source, result, Size(initial_size, initial_size), x, y);        imshow(source_window, result);    }    catch (Exception e) {        std::cout << "Exception message = " << e.msg << std::endl;    }}int main(){    source = imread("fifth.jpg", IMREAD_UNCHANGED);    result.create(source.rows, source.cols, source.type());    cvNamedWindow(source_window, CV_WINDOW_AUTOSIZE);    cvCreateTrackbar("changeSize", source_window, &initial_size, 100, onSizeChange);    cvCreateTrackbar("x方向方差", source_window, &x, 100, onXChange);    cvCreateTrackbar("y方向方差", source_window, &y, 100, onYChange);    cvSetTrackbarPos("changeSize", source_window, 0);    cvSetTrackbarPos("x方向方差", source_window, 0);    cvSetTrackbarPos("y方向方差", source_window, 0);    waitKey(0);    cvDestroyAllWindows();    return 0;}

看一下相关理论方面的东西:
平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法。
平滑处理的用途有很多, 但是在本教程中我们仅仅关注它减少噪声的功用 (其他用途在以后的教程中会接触到)。
平滑处理时需要用到一个 滤波器 。 最常用的滤波器是 线性 滤波器,线性滤波处理的输出像素值 (i.e. g(i,j)) 是输入像素值 (i.e. f(i+k,j+l))的加权和 :
这里写图片描述

h(k,l) 称为 核, 它仅仅是一个加权系数。
不妨把 滤波器 想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口滑过图像。
高斯滤波器 (Gaussian Filter)
最有用的滤波器 (尽管不是最快的)。 高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。个人感觉与归一化滤波器相比就是加权系数不在是所有像素点的加权系数都相同了,而是越靠近中部加权系数越大,可以看一下图:
这里写图片描述

而且高通滤波器的速度要比归一化滤波器慢上不少,如果只是想达到图片模糊的效果,建议还是选择速度快一点的比较好!
看一下GaussianBlur的原型:

/** @brief Blurs an image using a Gaussian filter.The function convolves the source image with the specified Gaussian kernel. In-place filtering issupported.@param src input image; the image can have any number of channels, which are processedindependently, but the depth should be CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.@param dst output image of the same size and type as src.@param ksize Gaussian kernel size. ksize.width and ksize.height can differ but they both must bepositive and odd. Or, they can be zero's and then they are computed from sigma.@param sigmaX Gaussian kernel standard deviation in X direction.@param sigmaY Gaussian kernel standard deviation in Y direction; if sigmaY is zero, it is set to beequal to sigmaX, if both sigmas are zeros, they are computed from ksize.width and ksize.height,respectively (see cv::getGaussianKernel for details); to fully control the result regardless ofpossible future modifications of all this semantics, it is recommended to specify all of ksize,sigmaX, and sigmaY.@param borderType pixel extrapolation method, see cv::BorderTypes@sa  sepFilter2D, filter2D, blur, boxFilter, bilateralFilter, medianBlur */CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize,                                double sigmaX, double sigmaY = 0,                                int borderType = BORDER_DEFAULT );

src: 输入图像
dst: 输出图像
Size(w, h): 定义内核的大小(需要考虑的邻域范围)。 w 和 h 必须是正奇数,否则将使用 sigmaX和 sigmaY 参数来计算内核大小。
sigmaX: x 方向标准方差, 如果是 0 则sigmaX 使用内核大小计算得到。
sigmaY : y 方向标准方差, 如果是 0 则sigmaY 使用内核大小计算得到。

好了,函数的注解也已经提供了,不知道我理解的对不对,如果有什么不正确的地方还请大神指正,我早点改正,不胜感激!!!有兴趣的朋友可以以关注我,遇到问题大家一起讨论一下!!

这是我的微信公众号,如果可以的话,希望您可以帮忙关注一下,这将是对我最大的鼓励了,谢谢!!
这里写图片描述

代码地址:文件夹名为GaussianBlur

原创粉丝点击