传统计算机视觉之均值滤波初探

本文为合集收录,欢迎查看合集/专栏链接进行全部合集的系统学习。 合集完整版请参考这里

在前面几节,从最基础的像素开始了介绍,并且着重介绍了RGB图片和YUV图片以及通道的概念。

其实这几节的内容,很多细节和知识暂时不用都学会。你只需要知道计算机在处理图片时,计算机看到的都是一堆像素,而这一堆像素,都是以数值的形式存放在计算机中的。

为了更好的展示彩色图像,并且处理图像数据,人们为图像设置了几个通道,比如 RGB 通道。

了解这些基本就可以了,从本节开始介绍一些传统计算机视觉的知识,方便为后面学习基于深度学习的计算机视觉提供知识积累。

在传统计算机视觉中,有一类非常基础的算法,就是对图像进行滤波操作。

什么是滤波?

估计在很多场合你或多或少都听说过滤波的概念。

图像滤波是图像处理中最常见的一种操作,它的主要目的是改变图像中的某些特征,比如去除图像中的噪声。

滤波操作的是通过一定的数学算法来完成的,最常见的滤波方式包括均值滤波、中值滤波和高斯滤波。

从名字就可以看出,均值滤波是取一些像素值的平均值作为滤波的输出,中值滤波便是取一些像素的中值作为滤波后的输出。

高斯滤波就稍微复杂一些,人们特意设计了一个符合高斯分布的滤波器,完成对图像像素的高斯滤波运算。

以均值滤波为例,它是取图像中的哪些像素值来计算平均值呢?

为了清楚的表示取哪些像素值,人们设计了一个窗口,称为滤波器的窗口,在AI算法的卷积算法中,这个窗口也可以看做是卷积的卷积核。

(均值滤波示意图,灰色阴影即为窗口)

如上图,均值滤波的运算过程,是每次取灰色阴影中像素的平均值作为输出,然后将窗口往右滑动继续计算下一个窗口,直至全部计算完成。

均值滤波的作用

均值滤波既然是取了窗口内的均值,显而易见它的作用主要有:平滑图像和去除噪点(这是因为一般噪点的像素值和正常像素比会发生突变,要么突然变得很大,要么突然变得很小)。

一取均值的话,噪声点突变的像素值就被平均了,输出就会显得没那么明显了,图片的平滑效果就会好很多。因此,对于图像中存在畸变噪点的图像,采用均值滤波会有一定的效果。

上图左侧是原图,中间是增加了一些黑色的噪声点,最右侧是对中间含有噪声点的图像做了一次均值滤波。

可以看到,均值滤波之后,噪声点没有那么明显了。

你可以通过调整均值滤波的窗口大小,来获取更好的滤波效果。一般而言,窗口设置的越大,输出图像平滑的越厉害,可能也越模糊,所以需要根据实际需要选择合适的窗口大小。

实现上述滤波的源代码在下方,你可以在这个目录下获取源代码和原始图像来体验滤波的过程。

ini 复制代码
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread('panda.png')

# 添加椒盐噪声
def add_salt_and_pepper_noise(image, salt_prob, pepper_prob):
    noisy_image = image.copy()
    total_pixels = image.size
    
    # 添加椒盐噪声
    num_salt = np.ceil(salt_prob * total_pixels)
    salt_coords = [np.random.randint(0, i-1, int(num_salt)) for i in image.shape]
    noisy_image[salt_coords[0], salt_coords[1], :] = 255
    
    num_pepper = np.ceil(pepper_prob * total_pixels)
    pepper_coords = [np.random.randint(0, i-1, int(num_pepper)) for i in image.shape]
    noisy_image[pepper_coords[0], pepper_coords[1], :] = 0
    
    return noisy_image

# 生成椒盐噪声
salt_and_pepper_image = add_salt_and_pepper_noise(image, salt_prob=0.02, pepper_prob=0.02)

# 定义均值滤波器的大小
kernel_size = (8, 8)

# 应用均值滤波
filtered_image = cv2.blur(salt_and_pepper_image, kernel_size)

# 使用Matplotlib显示原始图像、椒盐噪声图像和滤波后的图像
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[0].set_title('Original Image')
axes[0].axis('off')

axes[1].imshow(cv2.cvtColor(salt_and_pepper_image, cv2.COLOR_BGR2RGB))
axes[1].set_title('Image with Salt and Pepper Noise')
axes[1].axis('off')

axes[2].imshow(cv2.cvtColor(filtered_image, cv2.COLOR_BGR2RGB))
axes[2].set_title('Filtered Image')
axes[2].axis('off')

plt.show()

如果你想学习 AI ,欢迎来添加我的微信 (vx: ddcsggcs ),会有很多好玩的AI技术分享,可以咨询、也可以围观朋友圈呀!欢迎查看我的专栏 >>1. 专栏:计算机视觉入门与调优 , 2. 专栏:Transformer 通关与大模型实战

相关推荐
BUG收容所所长15 分钟前
二分查找的「左右为难」:如何优雅地找到数组中元素的首尾位置
前端·javascript·算法
itsuifengerxing1 小时前
python 自定义无符号右移
算法
猎板PCB厚铜专家大族1 小时前
高频 PCB 技术发展趋势与应用解析
人工智能·算法·设计规范
dying_man2 小时前
LeetCode--24.两两交换链表中的结点
算法·leetcode
yours_Gabriel2 小时前
【力扣】2434.使用机器人打印字典序最小的字符串
算法·leetcode·贪心算法
草莓熊Lotso2 小时前
【数据结构初阶】--算法复杂度的深度解析
c语言·开发语言·数据结构·经验分享·笔记·其他·算法
KyollBM2 小时前
【CF】Day75——CF (Div. 2) B (数学 + 贪心) + CF 882 (Div. 2) C (01Trie | 区间最大异或和)
c语言·c++·算法
CV点灯大师3 小时前
C++算法训练营 Day10 栈与队列(1)
c++·redis·算法
GGBondlctrl3 小时前
【leetcode】递归,回溯思想 + 巧妙解法-解决“N皇后”,以及“解数独”题目
算法·leetcode·n皇后·有效的数独·解数独·映射思想·数学思想
武子康3 小时前
大数据-276 Spark MLib - 基础介绍 机器学习算法 Bagging和Boosting区别 GBDT梯度提升树
大数据·人工智能·算法·机器学习·语言模型·spark-ml·boosting