OpenCV学习笔记(六) 滤波器 形态学操作(腐蚀、膨胀等)

时间:2022-05-06 20:32:30

转自: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): 定义内核的大小(需要考虑的邻域范围)。 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 和 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 必须是正奇数,否则将使用 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 和 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 参数来计算内核大小。
  • OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等): x 方向标准方差, 如果是 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 则 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 使用内核大小计算得到。
  • OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等): y 方向标准方差, 如果是 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 则 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 使用内核大小计算得到。.

中值滤波器 (Median Filter)

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

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

双边滤波 (Bilateral Filter)

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

详细的解释可以查看 链接

bilateralFilter ( src, dst, i, i*2, i/2 );
  • src: 输入图像
  • dst: 输出图像
  • d: 像素的邻域直径
  • OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等): 颜色空间的标准方差
  • OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等): 坐标空间的标准方差(像素单位)

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

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

以下是利用filter2D函数实现Laplace filter来加强图像对比度的实例(samples\cpp\tutorial_code\core\mat_mask_operations):

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

OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等)

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

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

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

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

膨胀dilate

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

腐蚀erode

将内核 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 划过图像,将内核 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 覆盖区域的最小相素值提取,并代替锚点位置的相素。相应地,暗区会开始“腐蚀”。

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: 腐蚀操作的内核。如果不指定,默认为一个简单的 OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等) 矩阵。否则,我们就要明确指定它的形状,可以使用函数getStructuringElement

getStructuringElement的参数:

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

OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等)

更多形态学变换

更直观的图参见此处

开运算 (Opening)

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

OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等)

闭运算(Closing)

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

OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等)

形态梯度(Morphological Gradient)

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

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

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

OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等)

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

OpenCV学习笔记(六) 滤波器  形态学操作(腐蚀、膨胀等)

调用函数: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 <> 自定义。