opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)

文章目录

  • 图像过滤的本质·简要——滤波
  • 实现图像模糊的opencv方法/操作
  • 平均模糊的实现(2D卷积)
    • 实现的函数参数讲解
    • 代码实例
  • 常用的模糊方法
    • 平滑模糊(也就是平均模糊)
      • 实现方法以及参数
      • 代码示例——采用cv.blur()
      • 代码实例——采用cv.boxFilter()
    • 高斯模糊
      • 实现方法以及参数
      • 代码示例
    • 中位模糊
      • 实现方法以及参数
      • 代码示例
    • 双边过滤
      • 实现方法以及参数
      • 代码示例
  • 锚点含义简要补充(为了方便理解内容引入,对于opencv中的锚点不尽相同)
  • 边缘像素处理方法可选参数(仅仅展示部分,不做过多说明)

                         QQ:3020889729                                                                                 小蔡

图像过滤的本质·简要——滤波

我们对于一维数据或者说信号,我们通常有许多的处理方法——而其中对信号滤波处理是为了数据更为理想所必要的。对于一维的信息滤波——有低通(LPF)和高通(HPF)。低通,通常用来去噪等操作。
到这里,可以顺着思路想到二维图像呢?当然啦,同样的,二维图像也是有属于自己的同一维一样的滤波形式——低通用于除去图像的噪点和实现模糊图像,而高通可以用来实现边缘查找(这个在后边介绍。)
——滤波简单介绍:用一维的信号来说吧
滤波电路——实现相应频率的输出/控制:
即只允许一定频率范围内的信号成分正常通过,而阻止另一部分频率成分通过的电路(也叫做经典滤波器)。——这样的只允许一部分满足条件的信号/数据得以展现/或者说有效,就是滤波的基本体现。

实现图像模糊的opencv方法/操作

  • 主要步骤为:
  • 1.设置内核——也就是模糊因子——一个矩阵形状的数据
  • 2.将内核与原图像作相应的运算——这个运算包含在cv. filter2D()或其它的一些函数/方法
  • (具体方法在后边对应问题列出——主要是基本方法的实现。)

平均模糊的实现(2D卷积)

cv. filter2D()——这里使用的卷积函数实际上知识直接计算——并未真的实现卷积,若是真要卷积的话需要对内核提前进行cv.flip翻转内核才行。
计算方法如下:x,y为输入图像的数据。
~kernel是内核

前往锚点含义补充
在这里插入图片描述

实现的函数参数讲解

cv. filter2D()参数如下:

  1. 输入参数:输入图像
  2. 深度:数据处理层次,一般设置-1
  3. 内核(kernel):模糊因子——及变换矩阵
  4. 内核的锚点,指示内核中已过滤点的相对位置;锚点应位于内核内;默认值(-1,-1)表示锚点位于内核中心。
  5. 插入值(一般不涉及,默认)
  6. 边缘像素推断(处理)方法(一般不涉及,默认)
  7. 边缘像素处理方法的选择有:前往边缘像素处理方法简介

代码实例

代码:

import cv2 as cv
import numpy as np


if __name__ == "__main__":
    img = cv.imread('../imag_in_save/class1.jpg')
    kernel = np.ones((5, 5), np.float32)/25
    # 注意哦,内核应该保证内核每一个值之和为1
    print("原图形:\n", img[:, :, 2], end='\n'*4)   # 输出比较处理前后的像素信息发生的变化
    dst = cv.filter2D(img, -1, kernel)
    print("处理后的图形:\n", dst[:, :, 2])

    cv.imshow('imag1', img)
    cv.imshow('imag2', dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第1张图片

常用的模糊方法

相对于采用filter2D实现根据内核变化的任意模糊(滤波)处理,我们有时更倾向于专门用来解决某一问题的方法——比如接下来这几个常用模糊方法。

平滑模糊(也就是平均模糊)

实现方法以及参数

有两种方法:
其一,也是自己用着比较习惯的(主要是方便):
cv.blur()——使用归一化框滤镜模糊图像。
参数如下:

  1. 输入参数:输入图像
  2. 内核大小——即多少乘以多少的矩阵形状
  3. 然后就是锚点,边框/边缘像素的处理方法(还是一般都不设置,默认为(-1, -1)也就是内核中心)

其二,采用boxFilter()实现平滑模糊
参数如下:依次为:输入图像,输出图像(用返回值接收,所以省略),深度(默认-1),大小(内核大小)——以及后边不常用的锚点,是否采用归一化处理数据,边缘像素的处理方法。
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第2张图片

代码示例——采用cv.blur()

import cv2 as cv
import numpy as np


# 图像平均模糊处理——blur实现内核模糊
if __name__ == "__main__":
    img = cv.imread('../imag_in_save/class1.jpg')
    dst = cv.blur(img, (5, 5)) 

    # 彩色图形——第一个维度为高——也就是行数
    # 第二个维度为宽——也就是列数
    # 第三个维度——对应像素信息参数
    cv.imshow('imag1', img)
    cv.imshow('imag2', dst)
    cv.waitKey(0)

效果:(内核越大——也就是矩阵形状越大,模糊程度越大)
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第3张图片

代码实例——采用cv.boxFilter()

与上边的blur形成对比——

import cv2 as cv
import numpy as np


# 图像平均模糊处理——boxFilter实现内核模糊
if __name__ == "__main__":
    img = cv.imread('../imag_in_save/class1.jpg')
    dst2 = cv.boxFilter(img, -1, (5, 5)) 
    dst = cv.blur(img, (5, 5))

    # 彩色图形——第一个维度为高——也就是行数
    # 第二个维度为宽——也就是列数
    # 第三个维度——对应像素信息参数
    cv.imshow('imag1', img)
    cv.imshow('imag2', dst)
    cv.imshow('imag3', dst2)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:观察可以得知,用法和效果是相同的~

高斯模糊

实现方法以及参数

采用cv.GaussianBlur()实现高斯模糊,其参数如下:

  1. 输入图像
  2. 内核大小——矩阵形状:高斯核大小。ksize.width和ksize.height可以不同,但​​它们都必须为正数和奇数。或者,它们可以为零,然后根据sigma计算得出。
  3. sigma x:x方向的偏移值(必须设值,可设为0不偏移)
  4. sigma y:y方向的偏移值(可设,可不设)
    Y方向的高斯核标准差;如果sigmaY为零,则将其设置为等于sigmaX;如果两个sigmas为零,则分别从ksize.width和ksize.height计算得出。
    为了完全控制结果,而不考虑将来可能对所有这些语义的修改,建议指定所有ksize,sigmaX和sigmaY。
  5. 边缘像素的处理方法选择(一般不选则)

代码示例

import cv2 as cv
import numpy as np


# 图像高斯模糊处理——GaussianBlur
if __name__ == "__main__":
    img = cv.imread('../imag_in_save/class1.jpg')
    dst = cv.GaussianBlur(img, (21, 21), 2, 3)

    # 彩色图形——第一个维度为高——也就是行数
    # 第二个维度为宽——也就是列数
    # 第三个维度——对应像素信息参数
    cv.imshow('imag1', img)
    cv.imshow('imag2', dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第4张图片

补充——如果有需要可以使用cv.getGaussianKernel()创建高斯内核——方法如下:
getGaussianKernel(需要的内核大小, 高斯计算需要的标准差, 滤波器数据类型)
以上参数——对应ksize,二元元组;
标准差任意值,不过若为负数,那么就根据ksize计算为sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8的值设置;
最后的数据类型可以选择:CV_32F或CV_64F——这里一般选用32,具体看图像参数运算需要吧。

中位模糊

函数cv.medianBlur()提取内核区域下所有像素的中值,并将中心元素替换为该中值。
该滤波器中,中心元素是新计算的值,该值可以是图像中的像素值或新值。但是在中位模糊中,中心元素始终被图像中的某些像素值代替。能有效降低噪音。

实现方法以及参数

采用的是cv.medianBlur()实现中位模糊,参数如下:

  1. 输入图像
  2. 孔径大小——也可以说是中位模糊滤镜下的内核大小——可是该内核仅仅是一个正奇数且>=1

代码示例

import cv2 as cv
import numpy as np


# 图像中位模糊处理——medianBlur
if __name__ == "__main__":
    img = cv.imread('../imag_in_save/class1.jpg')
    dst = cv.medianBlur(img, 7)

    # 彩色图形——第一个维度为高——也就是行数
    # 第二个维度为宽——也就是列数
    # 第三个维度——对应像素信息参数
    cv.imshow('imag1', img)
    cv.imshow('imag2', dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第5张图片
看一下其它实例的效果:(官方效果)——左为原图
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第6张图片

双边过滤

cv.bilateralFilter()在消除噪声的同时保持边缘清晰的方面非常有效。缺点:该操作速度较慢。
需要知道的是,高斯滤波器采用像素周围的邻域并找到其高斯加权平均值。且高斯滤波器是空间的函数,也就是说,滤波时会考虑附近的像素。但它不考虑像素是否具有几乎相同的强度。它不考虑像素是否是边缘像素。因此,它也模糊了边缘,这是我们不想做的。所以有了双边过滤——也就是对高斯滤波的掌控。

双边滤波的实现,是在空间中需要一个高斯滤波器,同时又有一个高斯滤波器,它是像素差异的函数——控制像素的强度差。空间的高斯函数可确保只考虑附近的像素进行模糊处理,而强度差的高斯函数可确保考虑强度与中央像素相似的像素进行模糊处理。由于边缘的像素强度变化较大,因此可以保留边缘。

实现方法以及参数

cv.bilateralFilter()的参数如下:

  1. 输入图像
  2. 计算像素空间的直径大小。如果它不是正值,则从sigmaSpace计算得出。——空间滤波直径大小,加权平均的取样点的范围
  3. sigmaColor设置过滤阈值——在色彩空间中需要过滤的sigma。该参数的值越大,表示像素邻域内的其他颜色(请参见sigmaSpace)将混合在一起的可能越大也越多,从而产生更大的半均等颜色区域。
  4. sigmaSpace:sigma像素颜色空间大小——也就是高斯计算的范围直径,且满足:d < 0时,d与sigmaSpace成比例。——像素强度的直径范围,与sigmaColor相关。
    ——这就对应着前面说到的两个高斯滤波,通过不同的滤波效果组合,实现双边过滤。
  5. 边缘像素的处理方法

代码示例

import cv2 as cv
import numpy as np


# 图像双边模糊处理——bilateralFilter
if __name__ == "__main__":
    img = cv.imread('../imag_in_save/class1.jpg')
    dst = cv.bilateralFilter(img, 20, 55, 20)

    # 彩色图形——第一个维度为高——也就是行数
    # 第二个维度为宽——也就是列数
    # 第三个维度——对应像素信息参数
    cv.imshow('imag1', img)
    cv.imshow('imag2', dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:sigmaColor为55的效果
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第7张图片
sigmaColor为100的效果——像素颜色混合范围增大,会越来越混合
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第8张图片

之后的补充内容,是为了方便一些参数的理解——不必深究,仅是为了引入理解,可能会有些描述上的问题,或者其它一些错误,如有问题,还望指出。

锚点含义简要补充(为了方便理解内容引入,对于opencv中的锚点不尽相同)

前往平均模糊的实现(2D卷积)

锚点——即定位点(这个定位点又有些特殊,由比例组成,也就是x,y均满足绝对值小于等于1)。
游轮有抛锚停靠,只要假设抛锚后,锚固定不动,,并且把船体比作一个点,那么无论长潮或者水面下降,船体与锚的相对位置不变——而对于岸边(即其它视角的位置)可能会改变哦。
即图像的排布位置取决于锚点的值——这里不需要很深的理解。
下面用一种比较一般的
图解:(这里的(-1, -1)就是锚点(0, 0),实际上在一些不同的应用环境中是不能有(-1, -1)的),只需要理解锚点的大概意思——及决定图像的相对位置即可,无需深究这个图。因为opencv中锚点值对应的不尽相同,比如在opencv中(-1, -1)代表着内核中心,相当于这里图中的(0.5, 0.5)
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第9张图片

边缘像素处理方法可选参数(仅仅展示部分,不做过多说明)

前往原参数列表位置

有兴趣可以尝试下:(就直接贴图了,具体的处理效果,可以参考以下指出的几个。

opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第10张图片
opencv 实现图像模糊的基础方法讲解(含高斯模糊的使用)_第11张图片
可前往该博客查看边框实例的效果

到这里,全部内容就结束了。或许,文中错误还是有的,如有错误还望大家能批评指出。让我能及时矫正,更改。

你可能感兴趣的:(#,Opencv学习笔记,opencv,python,计算机视觉,机器学习)