计算机视觉与模式识别实验1-3 图像滤波

文章目录

    • 🧡🧡实验流程🧡🧡
      • 1. 对图像加入椒盐噪声,并用均值滤波进行过滤
      • 2.对图像加入高斯噪声,并用高斯滤波进行过滤
      • 3.对图像加入任意噪声,并用中值滤波进行过滤
      • 4.读入一张灰度图像,比较不同窗口(模板)大小,分别加入高斯噪声,椒盐噪声 和其它噪声,比较不同模板大小,不同噪声下的使用均值滤波器,高斯滤波器和中值滤波的效果。
      • 5.实现高斯滤波
    • 🧡🧡全部代码🧡🧡

🧡🧡实验流程🧡🧡

1. 对图像加入椒盐噪声,并用均值滤波进行过滤

原图、加入椒盐噪声的图
在这里插入图片描述

3x3均值滤波、5x5均值滤波
在这里插入图片描述

2.对图像加入高斯噪声,并用高斯滤波进行过滤

原图、加入高斯噪声后的图.
在这里插入图片描述

高斯滤波
在这里插入图片描述

3.对图像加入任意噪声,并用中值滤波进行过滤

原图、加入椒盐噪声的图
在这里插入图片描述

中值滤波:对中心像素矩形邻域取中值来替代中心像素
在这里插入图片描述

4.读入一张灰度图像,比较不同窗口(模板)大小,分别加入高斯噪声,椒盐噪声 和其它噪声,比较不同模板大小,不同噪声下的使用均值滤波器,高斯滤波器和中值滤波的效果。

均值滤波器: 横轴(模板大小),纵轴(噪声类型)
在这里插入图片描述

高斯滤波器: 横轴(模板大小),纵轴(噪声类型)
在这里插入图片描述

中值滤波器: 横轴(模板大小),纵轴(噪声类型)
在这里插入图片描述
总结:

  • 噪声类型相同时,模板大小越大,去除噪声的效果越明显
  • 模板大小相同时,对于高斯噪声,高斯滤波器目前来看去噪效果相对好一些;对于椒盐噪声,中值滤波器表现最佳,效果明显;对于指数噪声,三个滤波器效果差不多,感官上均值滤波器略胜一筹。

5.实现高斯滤波

原理:按照如下高斯分布,将中心像素周围的像素按照高斯分布加权平均进行平滑化,越接近中心,取值越大,越远离中心,取值越小。计算平滑结果时,只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。
在这里插入图片描述
在这里插入图片描述

添加了高斯噪声的图
在这里插入图片描述

分别手动实现和调库实现结果如下:(模板大小均为5)
在这里插入图片描述
在这里插入图片描述
分析:手写的代码实现的效果要相对模糊一些,可能与选取的sigma值有关,影响了高斯分布函数的权重,从而导致周围9个像素点权重前后会略有差异。sigma 的值越大,图像就会变得更加模糊。

🧡🧡全部代码🧡🧡

import cv2
import numpy as np
import matplotlib.pyplot as pltdef cv_show(img):cv2.imshow('Image', img)cv2.waitKey(0)cv2.destroyAllWindows()
"""3-1 均值滤波
"""
I = cv2.imread('img/test1_LenaRGB.tif')
# 添加椒盐噪声
J = I.copy()
rows, cols, _ = J.shape
amount = 0.05 # 椒盐噪声占总像素的总比例
salt_vs_pepper = 0.5 # 椒与盐的比例
# ===添加盐噪声===
num_salt = np.ceil(amount * salt_vs_pepper * rows * cols) # 盐的数量
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in [rows,cols]] # 随机坐标 (H,W,:)
coords = tuple(coords)  # 将列表转换为元组
J[coords[:]] = (255, 255, 255) # 改变(H,W,C)
# ===添加椒噪声===
num_pepper = np.ceil(amount * (1-salt_vs_pepper) * rows * cols)
coords = [np.random.randint(0,i-1,int(num_pepper)) for i in [rows,cols]] # 随机坐标  (H,W,:)
oords = tuple(coords)
J[coords[:]] = (0,0,0,)# 显示原图像和加噪图像
res = np.hstack((I, J))
cv_show(res)# 3x3和5x5 均值滤波
K1 = cv2.blur(J, (3, 3))
K2 = cv2.blur(J, (5, 5))
res = np.hstack((K1, K2))
cv_show(res)
"""3-2 高斯滤波
"""
I = cv2.imread('img/test1_LenaRGB.tif')
# 添加高斯噪声
J = I.copy()
gauss = np.random.normal(0, 25, J.shape) # 0表示均值,0.1表示标准差sigma,sigma越大,损坏越厉害
J = J + gauss
J = np.clip(J,a_min=0,a_max=255).astype(np.uint8) # 缩放范围为0-255# 显示原图像和加噪图像
res = np.hstack((I, J))
cv_show(res)# 高斯滤波图像
K1 = cv2.GaussianBlur(J, (5, 5), 1)
cv_show(K1)
"""3-3 中值滤波
"""
I = cv2.imread('img/test1_LenaRGB.tif')
# 添加椒盐噪声
J = I.copy()
rows, cols, _ = J.shape
amount = 0.05 # 椒盐噪声占总像素的总比例
salt_vs_pepper = 0.5 # 椒与盐的比例
# ===添加盐噪声===
num_salt = np.ceil(amount * salt_vs_pepper * rows * cols) # 盐的数量
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in [rows,cols]] # 随机坐标 (H,W,:)
coords = tuple(coords)  # 将列表转换为元组
J[coords[:]] = (255, 255, 255) # 改变(H,W,C)
# ===添加椒噪声===
num_pepper = np.ceil(amount * (1-salt_vs_pepper) * rows * cols)
coords = [np.random.randint(0,i-1,int(num_pepper)) for i in [rows,cols]] # 随机坐标  (H,W,:)
oords = tuple(coords)
J[coords[:]] = (0,0,0,)# 显示原图像和加噪图像
res = np.hstack((I, J))
cv_show(res)# 3x3 中值滤波
K1 = cv2.medianBlur(J, 5)
cv_show(K1)
"""3-4 比较不同模板、不同噪声类型、不同滤波器类型的效果
"""
# 生成不同类型的噪声
def generate_noise(image, noise_type):if noise_type == 'gaussian':noise = np.random.normal(0, 50, image.shape).astype(np.float32)noisy_image = cv2.add(image.astype(np.float32), noise)elif noise_type == 'salt':salt_pepper_ratio = 0.3salt = np.where(np.random.random(image.shape) < salt_pepper_ratio, 255, 0).astype(np.uint8)noisy_image = cv2.add(image, salt)elif noise_type == 'exponential':lambd = 50noise = np.random.exponential(lambd, image.shape).astype(np.float32)noisy_image = cv2.add(image.astype(np.float32), noise)else:raise ValueError("Unsupported noise type")return noisy_image.clip(0, 255).astype(np.uint8)# 计算滤波器效果
def apply_filter(image, filter_type, kernel_size):if filter_type == 'mean':filtered_image = cv2.blur(image, (kernel_size, kernel_size))elif filter_type == 'gaussian':filtered_image = cv2.GaussianBlur(image, (kernel_size, kernel_size), 0)elif filter_type == 'median':filtered_image = cv2.medianBlur(image, kernel_size)else:raise ValueError("Unsupported filter type")return filtered_image# 读取灰度图像
image = cv2.imread('img/test1_lena.tif', cv2.IMREAD_GRAYSCALE)# 定义不同模板大小和不同噪声类型
kernel_sizes = [3, 5, 9]
noise_types = ['gaussian', 'salt', 'exponential']# 绘制结果
plt.figure(figsize=(12, 8))for i, noise_type in enumerate(noise_types):for j, kernel_size in enumerate(kernel_sizes):# 生成噪声图像noisy_image = generate_noise(image, noise_type)# 应用滤波器filtered_mean = apply_filter(noisy_image, 'mean', kernel_size)filtered_gaussian = apply_filter(noisy_image, 'gaussian', kernel_size)filtered_median = apply_filter(noisy_image, 'median', kernel_size)# 绘制结果图plt.subplot(len(noise_types), len(kernel_sizes), i * len(kernel_sizes) + j + 1)plt.imshow(filtered_median, cmap='gray')plt.title(f'Median Filter (Size: {kernel_size})(Noise: {noise_type})')plt.axis('off')plt.tight_layout()
plt.show()
"""3-5 实现高斯滤波器
"""
def noise_Gaussian(img,mean,var):J = img.copy()size = J.shapeJ = J / 255gauss = np.random.normal(0, 0.1, size)J = J + gaussJ = np.clip(J, 0, 1)  # 将像素值限制在 [0, 1] 范围内J = (J * 255).astype(np.uint8)  # 将像素值重新缩放回 [0, 255] 范围return Jori = cv2.imread('img/test1_LenaRGB.tif')
img = noise_Gaussian(ori,mean=0,var=0.1)
cv_show(img)
# print(img[100,100])def gaussian_filter(img, K_size=3, sigma=1.0):img = np.asarray(np.uint8(img))if len(img.shape) == 3:H, W, C = img.shapeelse:img = np.expand_dims(img, axis=-1)H, W, C = img.shape## Zero paddingpad = K_size // 2out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=float)out[pad: pad + H, pad: pad + W] = img.copy().astype(float)## prepare KernelK = np.zeros((K_size, K_size), dtype=float)for x in range(-pad, -pad + K_size):for y in range(-pad, -pad + K_size):K[y + pad, x + pad] = np.exp( -(x ** 2 + y ** 2) / (2 * (sigma ** 2)))K /= (2 * np.pi * sigma * sigma) K /= K.sum()tmp = out.copy()## filteringfor y in range(H):for x in range(W):for c in range(C): out[pad + y, pad + x, c] = np.sum(K * tmp[y: y + K_size, x: x + K_size, c])out = np.clip(out, 0, 255)out = out[pad: pad + H, pad: pad + W].astype(np.uint8)return out# 手写实现
gs1=gaussian_filter(img,K_size=5,sigma=5)
cv_show(gs1)# 调库实现
gs2 = cv2.GaussianBlur(img, (5, 5), 1)
cv_show(gs2)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/338963.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前端开发--css学习笔记】CSS超详细的学习笔记。前端开发css学习笔记(非常详细,适合小白入门)

二&#xff0c;CSS学习笔记 1&#xff0c;CSS语法 1-1 CSS 实例 CSS声明总是以分号 ; 结束&#xff0c;声明总以大括号 {} 括起来: <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title…

非对称密钥:应用场景

public class EncryptionAndSignatureExample { public static void main(String[] args) throws Exception {// 生成公私钥对KeyPairGenerator keyPairGenerator KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(1024);KeyPair keyPair keyPai…

TiDB-从0到1-部署篇

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇 一、TiUP TiUP是TiDB4.0版本引入的集群运维工具&#xff0c;通过TiUP可以进行TiDB的日常运维工作&#xff0c;包括部署、启动、关闭、销毁、弹性扩缩容…

Python PyInstaller打包方法介绍

为了将开发好的Python工具交付给其他人使用&#xff0c;除了在目标电脑部署Python编译环境以外&#xff0c;我们还可以将它打包成可执行文件&#xff0c;这样目标电脑不需要安装Python环境就可以运行。将Python程序打包成可执行文件的方法有多种&#xff0c;比如Nuitka、PyInst…

AI去衣技术中的几何着色:揭秘数字时尚的魔法

在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变我们的生活&#xff0c;从智能家居到自动驾驶汽车&#xff0c;再到个性化医疗。然而&#xff0c;AI的影响远不止于此。它正在重塑我们对艺术、设计和时尚的理解。特别是在数字时尚领域&#…

【学习Day5】操作系统

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 学习编辑文章的时间不太够用&#xff0c;先放思维导图&#xff0c;后续复习完善细节。

电脑缺少dll文件怎么解决,分享几种靠谱的解决方法

在现代科技高度发达的时代&#xff0c;电脑已经成为我们生活和工作中不可或缺的工具。然而&#xff0c;在使用电脑的过程中&#xff0c;我们可能会遇到一些问题&#xff0c;其中之一就是电脑丢失dll文件。那么&#xff0c;当我们面临这样的问题时&#xff0c;应该如何解决呢&am…

STC8增强型单片机进阶开发--LED呼吸灯(PWM)

知不足而奋进 望远山而前行 文章目录 目录 文章目录 前言 目标 内容 PWM基础概念 STC8H芯片 PWMA应用 PWM配置详解 周期 占空比 模式 使能PWM 引脚配置 EAXSFR扩展寄存器 总结 前言 学习PWM&#xff08;脉宽调制&#xff09;是探索数字信号转模拟信号的重要一步&#xff0c;尤…

使用 Scapy 库编写 IP 地址欺骗攻击脚本

一、介绍 1.1 概述 IP地址欺骗&#xff08;IP Spoofing&#xff09;是一种网络攻击技术&#xff0c;攻击者伪造其数据包的源IP地址&#xff0c;使其看起来像是从其他合法地址发送的。这种技术常用于各种攻击中&#xff0c;例如DDoS攻击、Man-in-the-Middle&#xff08;MITM&a…

车辆前向碰撞预警系统性能要求和测试规程

前言 本文整理《GB/T 33577-2017 智能运输系统-车辆前向碰撞预警系统性能要求和测试规程》国标文件关键信息,FCW系统性能和测试右给深层次的认识。 术语和定义 车辆前向碰撞预警系统 forward vehicle collision warning system自车 subject vehicle(SV)目标车辆 target ve…

面向对象概述

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 面向对象&#xff08;Object Oriented&#xff09;的英文缩写是OO&#xff0c;它是一种设计思想。从20世纪60年代提出面向对象的概念到现在&#xff…

Zynq学习笔记--AXI4-Stream 图像数据从仿真输出到图像文件

目录 1. 简介 2. 构建工程 2.1 Vivado 工程 2.2 TestBench 代码 2.3 关键代码分析 3. VPG Background Pattern ID (0x0020) Register 4. 总结 1. 简介 使用 SystemVerilog 将 AXI4-Stream 图像数据从仿真输出到图像文件 (PPM)。 用到的函数包括 $fopen、$fwrite 和 $f…

五类数据容器对比总结 知道喔!

五类数据容器对比总结 1.五类数据容器的区别 是否支持下标索引 支持&#xff1a;列表、元组、字符串---序列类型 不支持&#xff1a;集合、字典---非序列类型 是否支持重复元素 支持&#xff1a;列表、元组、字符串---序列类型 不支持&#xff1a;集合、字典---非序列类型 是…

Nginx企业级负载均衡:技术详解系列(16)—— Nginx的try_files指令,你知道这个指令是干什么的吗?

你好&#xff0c;我是赵兴晨&#xff0c;97年文科程序员。 今天咱们来聊一聊Nginx的try_files指令&#xff0c;你知道这个指令是干什么的吗&#xff1f; 如果你对Web服务器配置有所了解&#xff0c;那么你可能会对try_files指令感到好奇。这个指令实际上是Nginx配置中的一项强…

Go跨平台编译

1.编译windows平台运行程序 # windows env GOOSwindows GOARCHamd64 go build main.go2.编译linux平台运行程序 # linux env GOOSlinux GOARCHamd64 go build main.go 3.编译macos平台运行程序 # macos env GOOSdarwin GOARCHamd64 go build main.go 编译结果:

java收徒、java面试辅导、java辅导、java就业辅导

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还…

19.4-STM32接收数据-状态显示在屏幕 openMV寻迹与小车控制 Openmv+STM32F103C8T6视觉巡线小车

这个是全网最详细的STM32项目教学视频。 第一篇在这里: 视频在这里 STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随 19.4-STM32接收数据-状态显示在屏幕 先通过串口上位机模拟发送、 STM32有视觉循迹模式、…

2024四川三支一扶“考生信息表”照着填❗

2024四川三支一扶“考生信息表”照着填❗ ☑️四川三支一扶开始报名&#xff0c;大家要按照提示如实、准确、完整填写《高校毕业生“三支一扶”计划招募考生信息表》哦~ ☑️不知道怎么填写的宝子们&#xff0c;可以参考图1。 ☑️毕业证书编号如实填写&#xff0c;若是应届生&…

VGGNet

VGGNet CNN卷积网络的发展史 1. LetNet5(1998) 2. AlexNet(2012) 3. ZFNet(2013) 4. VGGNet(2014) 5. GoogLeNet(2014) 6. ResNet(2015) 7. DenseNet(2017) 8. EfficientNet(2019) 9. Vision Transformers(2020) 10. 自适应卷积网络(2021) 上面列出了发展到现在CNN的一些经典…

WPF Binding对象、数据校验、数据转换

在WinForm中&#xff0c;我们要想对控件赋值&#xff0c;需要在后台代码中拿到控件对象进行操作&#xff0c;这种赋值形式&#xff0c;从根本上是无法实现界面与逻辑分离的。 在WPF中&#xff0c;微软引入了Binding对象&#xff0c;通过Binding&#xff0c;我们可以直接将控件与…