计算机视觉教程2-2:详解图像滤波算法(附Python实战)

简介: 计算机视觉教程2-2:详解图像滤波算法(附Python实战)

目录

1 分类

图像滤波按图像域可分为两种类型:


邻域滤波(Spatial Domain Filter),其本质是数字窗口上的数学运算。一般用于图像平滑、图像锐化、特征提取(如纹理测量、边缘检测)等,邻域滤波使用邻域算子——利用给定像素周围像素值以决定此像素最终输出的一种算子

频域滤波(Frequency Domain Filter),其本质是对像素频率的修改。一般用于降噪、重采样、图像压缩等。

按图像频率滤除效果主要分为两种类型:


低通滤波。滤除原图像的高频成分,即模糊图像边缘与细节。

高通滤波。滤除原图像的低频成分,即图像锐化。

导入原图和噪图

import cv2,skimage
import numpy as np
# 原图
srcImg = cv2.imread("test.jpg")
cv2.imshow("src image", srcImg)
# 给图像增加高斯噪声
noiseImg = skimage.util.random_noise(srcImg, mode='gaussian')
cv2.imshow("image with noise", noiseImg)

image.png

image.png

其中噪声可选

  • gaussian:高斯加性噪声
  • localvar:高斯加性噪声,每点具有特定局部方差
  • poisson: 泊松分布噪声
  • salt:盐噪声,随机用1替换像素
  • pepper:胡椒噪声,随机用0或-1替换像素
  • s&p:椒盐噪声,呈现出黑白杂点


2 邻域滤波

2.1 线性滤波

线性邻域滤波,指像素的输出值取决于输入区域像素的加权和,下面介绍常见的线性滤波算子。

2.1.1 方框滤波

方框滤波(Box Filter),其核函数为:

K e r    =    1 α [ 1 1 ⋯ 1 1 1 ⋯ 1 ⋮ ⋮ ⋱ ⋮ 1 1 ⋯ 1 ] Ker\,\,=\,\,\frac{1}{\alpha}\left[

11⋮111⋮1⋯⋯⋱⋯11⋮1

11⋯111⋯1⋮⋮⋱⋮11⋯1

\right]

Ker=

α

1


 


 

1

1

1


 

1

1

1


 


 

1

1

1


 



其中 α = { 1 K e r S i z e    , N o r m a l i z e    =    T r u e 1 , N o r m a l i z e    =    F a l s e \alpha =

{1KerSize,Normalize=True1,Normalize=False

{1KerSize,Normalize=True1,Normalize=False

α={

KerSize

1


,Normalize=True

1,Normalize=False



非归一化的方框滤波用于计算每个像素邻域内的积分特性,比如密集光流算法(Dense Optical Flow Algorithms)中用到的图像倒数的协方差矩阵。


归一化的方框滤波则为均值滤波(Blur),即邻域平均法——用一片图像区域各个像素的均值来代替原图像中的各个像素值。均值滤波用于图像平滑,但其在降噪的同时也破坏了图像的边缘细节,从而使图像变得模糊,降噪能力较差。


进行方框滤波

# 方框滤波
boxImg = cv2.boxFilter(noiseImg, ddepth = -1, ksize = (2, 2), normalize = False)
cv2.imshow("box Image", boxImg)
# 均值滤波
blurImg = cv2.blur(noiseImg, (6, 5))
cv2.imshow("blur image", blurImg)

image.png

image.png

若将方框滤波核设为(6,5)且归一化,则效果与均值滤波相同。

2.1.2 高斯滤波

高斯滤波(Gauss Filter)基于二维高斯核函数


G ( x , y , σ ) = 1 2 π σ 2 e − x 2 + y 2 2 σ 2 G\left( x,y,\sigma \right) =\frac{1}{2\pi \sigma ^2}e^{-\frac{x^2+y^2}{2\sigma ^2}}

G(x,y,σ)=

2πσ

2

1


e

2

x

2

+y

2



具有在保持细节的条件下进行噪声滤波的能力,因此广泛应用于图像降噪中,但其效率比均值滤波低。


高斯滤波器有两个特征量:


核大小,其决定了图像的平滑范围。理论上,高斯核函数应该无穷大,以达到最佳的平滑效果,但过大的卷积核会导致运算效率骤降。根据高斯函数 3 σ 3\sigma 3σ规则,可以取高斯核大小为 ( 6 σ + 1 ) × ( 6 σ + 1 ) \left( 6\sigma +1 \right) \times \left( 6\sigma +1 \right) (6σ+1)×(6σ+1);

离散程度 σ \sigma σ,其决定了对高频成分的抑制程度。 σ \sigma σ越大,像素加权半径越大,平滑程度越强。


image.png

# 高斯滤波
gaussImg = cv2.GaussianBlur(noiseImg, (5, 5), 0)
cv2.namedWindow("gaussain image")
cv2.imshow("gaussain image", gaussImg)

image.png

2.2 非线性滤波

虽然线性滤波器易于构造且计算效率高,但有些情况下,使用邻域像素的非线性滤波效果更好。例如,若图像具有椒盐噪声而非高斯噪声,此时对图像高斯滤波并不会去除噪声像素,只是把噪声转换为更为柔和但仍然可见的颗粒。


image.png

中值滤波(Median filter)是一种基于排序统计理论的典型非线性滤波技术,核心原理是用像素点邻域灰度值中值代替该像素点的灰度值。中值滤波对脉冲噪声、椒盐噪声尤为有效,且具有边缘保护特性。中值滤波器本质上是数字窗口内的非线性取中值运算,而非线性滤波器的加权运算,因此中值滤波没有卷积核,运算效率仅有线性滤波的1/5左右。

# 原图
srcImg = cv2.imread("test.jpg")
cv2.imshow("src image", srcImg)
# 给图像增加椒盐噪声
noiseImg = skimage.util.random_noise(srcImg, mode='s&p')
cv2.imshow("image with noise", noiseImg)
medImg = cv2.medianBlur(np.uint8(noiseImg * 255), 3)
cv2.namedWindow("median image")
cv2.imshow("median image", medImg)

image.png

image.png

中值滤波对椒盐噪声效果

3 频域滤波

通过傅里叶变换将图像变换到频域,即可在频域进行图像处理。根据傅里叶变换的对称性以及从低频到高频的排列规则,图像原始频域图像会在四角形成低频分量区,而形成高频中心。通常为了观察方便,变换算法(例如Matlab中的fftshift)会将低频分量移动到图像中心形成低频中心

image.png

图像傅里叶变换代码如下

# 傅里叶变换
dft = cv2.dft(np.float32(grayImg), flags = cv2.DFT_COMPLEX_OUTPUT)
# 将图像中的低频部分移动到图像的中心
dftShift = np.fft.fftshift(dft)
# 计算幅频特性
magnitude = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1]))
plt.subplot(121), plt.imshow(grayImg, cmap = 'gray')
plt.title('原图'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude, cmap = 'gray')
plt.title('频谱图'), plt.xticks([]), plt.yticks([])
plt.show()

3.1 低通滤波

# 定义滤波掩码
def mask(img, ftype):
    crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得图像的中心点位置
    # 低通
    if ftype == 'low':
        mask = np.zeros((img.shape[0], img.shape[1], 2), np.uint8)
        mask[crow-30:crow+30, ccol-30:ccol+30] = 1
    # 高通
    if ftype == 'high':
        mask = np.ones((img.shape[0], img.shape[1], 2), np.uint8)
        mask[crow-30:crow+30, ccol-30:ccol+30] = 0
    return mask
lowImg = dftShift * mask(grayImg, 'low')
lowImg = np.fft.ifftshift(lowImg)
lowImg = cv2.idft(lowImg)
lowImg = cv2.magnitude(lowImg[:, :, 0], lowImg[:, :, 1])

image.png

3.2 高通滤波

# 定义滤波掩码
def mask(img, ftype):
    crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得图像的中心点位置
    # 低通
    if ftype == 'low':
        mask = np.zeros((img.shape[0], img.shape[1], 2), np.uint8)
        mask[crow-30:crow+30, ccol-30:ccol+30] = 1
    # 高通
    if ftype == 'high':
        mask = np.ones((img.shape[0], img.shape[1], 2), np.uint8)
        mask[crow-30:crow+30, ccol-30:ccol+30] = 0
    return mask
highImg = dftShift * mask(grayImg, 'high')
highImg = np.fft.ifftshift(highImg)
highImg = cv2.idft(highImg)
highImg = cv2.magnitude(highImg[:, :, 0], highImg[:, :, 1])

image.png

完整代码关注下方公众号回复 CV002 获取


🚀 计算机视觉基础教程说明


章号                                    内容

 0                              色彩空间与数字成像

 1                              计算机几何基础

 2                              图像增强、滤波、金字塔

 3                              图像特征提取

 4                              图像特征描述

 5                              图像特征匹配

 6                              立体视觉

 7                              项目实战


🔥 更多精彩专栏:


《机器人原理与技术》

《ROS从入门到精通》

《计算机视觉教程》

《机器学习》

《嵌入式系统》

《数值优化方法》


目录
相关文章
|
9天前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
22 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
6天前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
21 2
|
9天前
|
算法 Python
震惊!Python 算法设计背后,时间复杂度与空间复杂度的惊天秘密大起底!
在 Python 算法设计中,理解并巧妙运用时间复杂度和空间复杂度的知识,是实现高效、优雅代码的必经之路。通过不断地实践和优化,我们能够在这两个因素之间找到最佳的平衡点,创造出性能卓越的程序。
26 4
|
11天前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
在 Python 编程中,算法的性能至关重要。本文将带您深入了解算法复杂度的概念,包括时间复杂度和空间复杂度。通过具体的例子,如冒泡排序算法 (`O(n^2)` 时间复杂度,`O(1)` 空间复杂度),我们将展示如何评估算法的性能。同时,我们还会介绍如何优化算法,例如使用 Python 的内置函数 `max` 来提高查找最大值的效率,或利用哈希表将查找时间从 `O(n)` 降至 `O(1)`。此外,还将介绍使用 `timeit` 模块等工具来评估算法性能的方法。通过不断实践,您将能更高效地优化 Python 程序。
27 4
|
9天前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
20 1
|
9天前
|
算法 计算机视觉 Python
Python并查集大揭秘:让你在算法界呼风唤雨,秒杀一切复杂场景!
在编程与算法的广袤天地中,总有一些工具如同神兵利器,能够助你一臂之力,在复杂的问题前游刃有余。今天,我们就来深入探讨这样一件神器——Python并查集(Union-Find),看看它是如何让你在算法界呼风唤雨,轻松应对各种复杂场景的。
22 2
|
9天前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
28 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
Python
PYTHON实战两数之和
1. 两数之和 难度:简单 收藏 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。
183 0
PYTHON实战两数之和
|
4天前
|
数据挖掘 索引 Python
Python数据挖掘编程基础3
字典在数学上是一个映射,类似列表但使用自定义键而非数字索引,键在整个字典中必须唯一。可以通过直接赋值、`dict`函数或`dict.fromkeys`创建字典,并通过键访问元素。集合是一种不重复且无序的数据结构,可通过花括号或`set`函数创建,支持并集、交集、差集和对称差集等运算。
14 9
|
4天前
|
存储 开发者 Python
探索Python编程的奥秘
【9月更文挑战第29天】本文将带你走进Python的世界,通过深入浅出的方式,解析Python编程的基本概念和核心特性。我们将一起探讨变量、数据类型、控制结构、函数等基础知识,并通过实际代码示例,让你更好地理解和掌握Python编程。无论你是编程新手,还是有一定基础的开发者,都能在这篇文章中找到新的启示和收获。让我们一起探索Python编程的奥秘,开启编程之旅吧!
下一篇
无影云桌面