zoukankan      html  css  js  c++  java
  • OpenCV学习笔记(六) 滤波器 形态学操作(腐蚀、膨胀等)

    转自:OpenCV 教程 

    另附:计算机视觉:算法与应用(2012),Learning OpenCV(2009)

    平滑图像:滤波器

    平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法。平滑处理的用途有很多, 但是在本教程中我们仅仅关注它减少噪声的功用 (其他用途在以后的教程中会接触到)。平滑处理时需要用到一个 滤波器 。最常用的滤波器是 线性 滤波器。不妨把 滤波器 想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口滑过图像。

    归一化滤波器 (Normalized Box Filter)

    最简单的滤波器,输出像素值是核窗口内像素值的 均值 ( 所有像素加权系数相等)。

    blur( src, dst, Size( i, i ), Point(-1,-1) );
    • src: 输入图像
    • dst: 输出图像
    • Size( w,h ): 定义内核大小( w 像素宽度, h 像素高度)
    • Point(-1, -1): 指定锚点位置(被平滑点), 如果是负值,取核的中心为锚点。

    高斯滤波器 (Gaussian Filter)

    最有用的滤波器 (尽管不是最快的)。 高斯滤波是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。

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

    中值滤波器 (Median Filter)

    中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替 。

    medianBlur ( src, dst, i );
    
    • src: 输入图像
    • dst: 输出图像, 必须与 src 相同类型
    • i: 内核大小 (只需一个值,因为我们使用正方形窗口),必须为奇数。

    双边滤波 (Bilateral Filter)

    目前我们了解的滤波器都是为了 平滑 图像, 问题是有些时候这些滤波器不仅仅削弱了噪声, 连带着把边缘也给磨掉了。为避免这样的情形 (至少在一定程度上 ), 我们可以使用双边滤波。类似于高斯滤波器,双边滤波器也给每一个邻域像素分配一个加权系数。 这些加权系数包含两个部分, 第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。

    详细的解释可以查看 链接

    bilateralFilter ( src, dst, i, i*2, i/2 );
    
    • src: 输入图像
    • dst: 输出图像
    • d: 像素的邻域直径
    • sigma_{Color}: 颜色空间的标准方差
    • sigma_{Space}: 坐标空间的标准方差(像素单位)

    利用掩码(kernel mask)简单滤波:filter2D

    矩阵的掩码操作很简单。其思想是:根据掩码矩阵(也称作核)重新计算图像中每个像素的值。掩码矩阵中的值表示近邻像素值(包括该像素自身的值)对新像素值有多大影响。从数学观点看,我们用自己设置的权值,对像素邻域内的值做了个加权平均。

    以下是利用filter2D函数实现Laplace filter来加强图像对比度的实例(samplescpp utorial_codecoremat_mask_operations):

    Mat kern = (Mat_<char>(3,3) <<  0, -1,  0,
                                   -1,  5, -1,
                                    0, -1,  0);
    filter2D(I, K, I.depth(), kern );

    filter2D(src, dst, ddepth , kernel, anchor, delta, BORDER_DEFAULT );
    • src: 源图像
    • dst: 目标图像
    • ddepthdst 的深度。若为负值(如 -1),则表示其深度与源图像相等。
    • kernel: 用来遍历图像的核
    • anchor: 核的锚点的相对位置,其中心点默认为 (-1, -1) 。
    • delta: 在卷积过程中,该值会加到每个像素上。默认情况下,这个值为 0 。
    • BORDER_DEFAULT: 这里我们保持其默认值,更多细节将在其他教程中详解

    形态学操作之:腐蚀膨胀(Eroding and Dilating)

    形态学操作就是基于形状的一系列图像处理操作。通过将 结构元素 作用于输入图像来产生输出图像。最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation)。 他们的运用有:

    • 消除噪声
    • 分割(isolate)独立的图像元素,以及连接(join)相邻的元素。
    • 寻找图像中的明显的极大值区域或极小值区域。

    膨胀dilate

    将图像 A 与任意形状的内核 (B),通常为正方形或圆形,进行卷积。内核 B 有一个可定义的 锚点, 通常定义为内核中心点。将内核 B 划过图像,将内核 B 覆盖区域的最大相素值提取,并代替锚点位置的相素。显然,这一最大化操作将会导致图像中的亮区开始”扩展” (因此有了术语膨胀 dilation )。

    腐蚀erode

    将内核 B 划过图像,将内核 B 覆盖区域的最小相素值提取,并代替锚点位置的相素。相应地,暗区会开始“腐蚀”。

    Mat element = getStructuringElement( dilation_type,
                                          Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                          Point( dilation_size, dilation_size ) );
    
    dilate( src, dilation_dst, element );
    erode( src, erosion_dst, element );
    

    dilate和erode参数相同:

    • src: 原图像
    • erosion_dst: 输出图像
    • element: 腐蚀操作的内核。如果不指定,默认为一个简单的 3x3 矩阵。否则,我们就要明确指定它的形状,可以使用函数getStructuringElement

    getStructuringElement的参数:

    • dilation_type = 矩形: MORPH_RECT 或者 交叉形: MORPH_CROSS  或者  椭圆形 MORPH_ELLIPSE
    • 内核大小
    • 锚点位置(若不指定,则默认为中心位置)

    更多形态学变换

    更直观的图参见此处

    开运算 (Opening)

    通过先对图像腐蚀再膨胀实现的。能够排除小团块物体(假设物体较背景明亮)。

    dst = open( src, element) = dilate( erode( src, element ) )

    闭运算(Closing)

    通过先对图像膨胀再腐蚀实现的。能够排除小型黑洞(黑色区域)。

    dst = close( src, element ) = erode( dilate( src, element ) )

    形态梯度(Morphological Gradient)

    膨胀图与腐蚀图之差,能够保留物体的边缘轮廓。

    顶帽(Top Hat)与黑帽(Black Hat)

    顶帽:原图像与开运算结果图之差

    dst = tophat( src, element ) = src - open( src, element )

    黑帽:闭运算结果图与原图像之差

    dst = blackhat( src, element ) = close( src, element ) - src

    调用函数:morphologyEx

    Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );
    
    /// 运行指定形态学操作
    morphologyEx( src, dst, operation, element );
    

    参数列表:

    • src : 原 (输入) 图像
    • dst: 输出图像
    • operation: 需要运行的形态学操作。 我们有5个选项(注意:取值范围为2~6):
      • Opening: MORPH_OPEN : 2
      • Closing: MORPH_CLOSE: 3
      • Gradient: MORPH_GRADIENT: 4
      • Top Hat: MORPH_TOPHAT: 5
      • Black Hat: MORPH_BLACKHAT: 6
    • element: 内核,可以使用函数:get_structuring_element:getStructuringElement <> 自定义。
  • 相关阅读:
    HashMap底层实现原理及面试常见问题
    Java面试题:==运算符与equals方法的区别
    SpringBoot基础,Java配置(全注解配置)取代xml配置
    实战SpringBoot Admin
    Java Object类中toString方法的重写
    java题
    1.5 安全性测试(功能)
    1.4 容量测试
    压力测试/极限测试(可靠性)
    1.2 性能测试(效率)
  • 原文地址:https://www.cnblogs.com/ericxing/p/3577250.html
Copyright © 2011-2022 走看看