zoukankan      html  css  js  c++  java
  • Opencv2系列学习笔记8(图像滤波)

    一:概念:

    滤波是信号处理机图像处理中的一个基本操作。滤波去除图像中的噪声,提取感兴趣的特征,允许图像重采样。

    图像中的频域和空域:空间域指用图像的灰度值来描述一幅图像;而频域指用图像灰度值的变化来描述一幅图像。而低通滤波器和高通滤波器的概念就是在频域中产生的。

    低通滤波器指去除图像中的高频成分,而高通滤波器指去除图像中的低频成分。

    后面将介绍低通滤波器—均值和高斯滤波器;中值滤波器—非线性滤波器;高通滤波器—sobel算子(方向滤波器)和拉普拉斯变换(二阶导数)。其中利用方向滤波器和拉普拉斯变换可以对图像的边缘进行检测。

    二:低通滤波器

    <1>cv::blur函数:每个像素替换为相邻矩形内像素的平均值

    <2>cv::GaussianBlur函数:通过高斯核来进行替换

    Code:

     

    Mat result;                              // 线性平滑 滤波  每个像素替换为相邻矩形内像素的平均值
    	blur(image, result,Size(5,5));         // filter2D可以自定义核进行线性滤波
    
    	Mat gauResult;
    	GaussianBlur(image, gauResult, Size(5,5), 1.5);    // 高斯平滑 模糊  线性滤波器

    Result:

    sourceImage:

    BlurResult:


    GaussianBlur:


    低通滤波器的效果是对图像进行模糊和平滑,减弱了物体边缘可见的快速变化。它是一种线性滤波器,原理是与核进行卷积运算,此时的核内定,当我们需要指定核函数进行卷积时可以用filter2D函数,它的使用见blog:http://blog.csdn.net/lu597203933/article/details/16811851。 

    三:中值滤波器

    中值滤波器是非线性滤波器,它的原理是仅仅计算这组数的中值,并用中值替换当前的像素值。因此对于去除椒盐噪点非常有用。

    Code:

     

    Mat medianResult;
    	medianBlur(image, medianResult,5);  // 是一个非线性的滤波器,利用中值替换当前的像素值,对于去除椒盐噪点尤为有用

    Result:

     

    三:方向滤波器—sobel算子

    Sobel算子就是通过卷积操作来计算图像的一阶导数,由于边缘处图像灰度变化率较大,因此可以用sobel算子来进行边缘检测。Sobel算子的核定义为:

    y坐标轴:


    x坐标轴:


    Sobel函数:Sobel(InputArray src, OutputArray dst, int ddepth,

                             int dx, int dy, int ksize=3,

                             doublescale=1, double delta=0,

                             int borderType=BORDER_DEFAULT );

    其中ddepth为图像类型, (dx,dy) = (1,0)为x方向导数,(dx,dy) = (0,1)为y方向导数,scale和delta的作用是再保存前可以对图像进行缩放,公式为:dst =dst * scale + delta.

    Code:

     

    int main()
    {
    	Mat image = imread("F:\lena.png", 0);
    	if(!image.data)
    	{
    		cout << "Fail to load image" << endl;
    		return 0;
    	}
    	Mat sobel_x, sobel_y;
    	//Sobel(image, sobel_x, CV_8U, 1, 0, 3, 0.4, 128);
    	//Sobel(image, sobel_y, CV_8U, 0, 1, 3, 0.4, 128);
    
    	Sobel(image, sobel_x, CV_16S, 1, 0);  // 因为后面要相加 所以用16位有符号的整数来表示  另外导数肯定含有负数
    	Sobel(image, sobel_y, CV_16S, 0, 1);
    	Mat sobel;
    	sobel = abs(sobel_x) + abs(sobel_y);
    
    	double sobmin, sobmax;
    	minMaxLoc(sobel, &sobmin, &sobmax);
    	Mat sobelImage;
    	sobel.convertTo(sobelImage, CV_8U, -255.0/sobmax, 255);   // 等价于  saturate_cast(a*sobel + b)
    	
    	Mat sobelThresholded;
    	int thre = 200;
    	threshold(sobelImage, sobelThresholded, thre, 255, THRESH_BINARY);
    
    	namedWindow("sobelImage", 0);
    	imshow("sobelImage", sobelImage);
    	namedWindow("sobelThresholded", 0);
    	imshow("sobelThresholded", sobelThresholded);
    
    	waitKey(0);
    	return 0;
    }

    Result:


    当然除了sobel算子,还有其它的算子,如Scharr算子,它更精确、快。它的核为:

     

    Sobel(image, sobelX, CV_16S, 1, 0,CV_SCHARR);

    或者:

    Scharr(image, scharrX, CV_16S, 1, 0, 3);

    四:拉普拉斯变换

    拉普拉斯变化时基于图像导数的高通滤波器,计算二阶导数以衡量图像的弯曲度

    Code:

     

    int main()
    {
    	Mat image = imread("F:\lena.png", 0);
    	if(!image.data)
    	{
    		cout << "Fail to load image" << endl;
    		return 0;
    	}
    	Mat laplacian;
    	Laplacian(image, laplacian, CV_16S, 3);  // 二阶导数肯定含有负数。。  基于图像导数的高通滤波器,计算二阶导数以衡量图像的弯曲度
    	laplacian = abs(laplacian);
    	Mat laplacianImage;
    	laplacian.convertTo(laplacianImage, CV_8U);
    	namedWindow("laplacianImage");
    	imshow("laplacianImage", laplacianImage);
    	waitKey(0);
    	return 0;
    
    }

    Result:


    作者:小村长  出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流!)

  • 相关阅读:
    Codeforces Round #592 (Div. 2)C. The Football Season(暴力,循环节)
    Educational Codeforces Round 72 (Rated for Div. 2)D. Coloring Edges(想法)
    扩展KMP
    poj 1699 Best Sequence(dfs)
    KMP(思路分析)
    poj 1950 Dessert(dfs)
    poj 3278 Catch That Cow(BFS)
    素数环(回溯)
    sort与qsort
    poj 1952 buy low buy lower(DP)
  • 原文地址:https://www.cnblogs.com/riasky/p/3469005.html
Copyright © 2011-2022 走看看