计算机视觉与模式识别实验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 plt

def 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.3
        salt = 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 = 50
        noise = 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.shape
    J = J / 255
    gauss = np.random.normal(0, 0.1, size)
    J = J + gauss
    J = np.clip(J, 0, 1)  # 将像素值限制在 [0, 1] 范围内
    J = (J * 255).astype(np.uint8)  # 将像素值重新缩放回 [0, 255] 范围
    return J

ori = 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.shape
    else:
        img = np.expand_dims(img, axis=-1)
        H, W, C = img.shape
    ## Zero padding
    pad = K_size // 2
    out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=float)
    out[pad: pad + H, pad: pad + W] = img.copy().astype(float)
    
    ## prepare Kernel
    K = 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()
    
    ## filtering
    for 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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java项目:95 springboot班级回忆录的设计与实现

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本管理系统有管理员和用户。 本海滨学院班级回忆录管理员功能有个人中心&#xff0c;用户信息管理&#xff0c;班委信息管理&#xff0c;班级信息管理…

云计算-高级云资源配置(Advanced Cloud Provisioning)

向Bucket添加公共访问&#xff08;Adding Public Access to Bucket&#xff09; 在模块5中&#xff0c;我们已经看到如何使用CloudFormation创建和更新一个Bucket。现在我们将进一步更新该Bucket&#xff0c;添加公共访问权限。我们在模块5中使用的模板&#xff08;third_templ…

多维数组找最大值

调用JavaScript的一个内置函数&#xff1a;Math.max() <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title…

汇编原理(二)寄存器——CPU工作原理

寄存器&#xff1a;所有寄存器都是16位&#xff08;0-15&#xff09;&#xff0c;可以存放两个字节 AX,BX,CX,DX存放一般性数据&#xff0c;称为通用寄存器 AX的逻辑结构。最大存放的数据为2的16次方减1。可分为AH和AL&#xff0c;兼容8位寄存器。 字&#xff1a;1word 2Byte…

c++实现:小型公司的信息管理系统(关于多态)

前言&#xff1a; 介绍员工信息&#xff1a;一个小型公司的人员信息管理系统 某小型公司&#xff0c;主要有四类人员&#xff1a;经理、技术人员、销售经理和推销员。现在&#xff0c;需要存储这些人员的姓名、编号、级别、当前薪水。计算月薪总额并显示全部信息人员编号基数为…

前端组件业务数据选择功能优雅写法

1. 业务场景 后台管理在实际业务中&#xff0c;经常可见的功能为&#xff1a;在当前的页面中从其他列表中选择数据。 例如&#xff0c;在一个商品活动列表页面中 需要选择配置的商品。 2. 遇到问题 从代码划分的角度来说&#xff0c;每个业务列表代码首先分散开来&#xff0…

基于Weaviate构建多模态检索和多模态检索增强(RAG): Building Multimodal Search and RAG

Building Multimodal Search and RAG 本文是学习 https://www.deeplearning.ai/short-courses/building-multimodal-search-and-rag/ 这门课的学习笔记。 What you’ll learn in this course Learn how to build multimodal search and RAG systems. RAG systems enhance an …

张大哥笔记:下一个风口是什么?

我们经常会问&#xff0c;下一个风口是什么&#xff1f;我们可以大胆预测一下&#xff0c;2024年的风口是什么呢&#xff1f; 40年前&#xff0c;如果你会开车&#xff0c;那就是响当当的铁饭碗&#xff1b; 30年前&#xff0c;如果你会英语和电脑&#xff0c;那也绝对是个人才…

SSMP整合案例第五步 在前端页面上拿到service层调数据库里的数据后列表

在前端页面上列表 我们首先看看前端页面 我们已经把数据传入前端控制台 再看看我们的代码是怎么写的 我们展示 数据来自图dataList 在这里 我们要把数据填进去 就能展示在前端页面上 用的是前端数据双向绑定 axios发送异步请求 函数 //钩子函数&#xff0c;VUE对象初始化…

RK3568笔记二十九:RTMP推流

若该文为原创文章&#xff0c;转载请注明原文出处。 基于RK3568的RTMP推流测试&#xff0c;此代码是基于勇哥的github代码修改的&#xff0c;源码地址MontaukLaw/3568_rknn_rtmp: rk3568的推理推流 (github.com) 感兴趣的可以clone下来测试。 也可以下载修改后的代码测试。Y…

VirtualBox Ubuntu系统硬盘扩容

1、关闭虚拟机&#xff0c;找到需要扩容的硬盘&#xff0c;修改为新的容量80GB&#xff0c;应用保存。 2、打开VM&#xff0c;进入系统&#xff0c;使用lsblk可以看到硬盘容量已经变为80GB&#xff0c;但硬盘根分区还没有扩容&#xff0c;使用df查看根文件系统也没有扩容。 [19…

Java八股文面试全套真题

Java八股文面试全套真题 一、Redis1.1、你在最近的项目中哪些场景使用了redis呢&#xff1f;1.2、缓存穿透1.3、布隆过滤器1.4、缓存击穿1.5、缓存雪崩1.6、redis做为缓存&#xff0c;mysql的数据如何与redis进行同步呢&#xff1f;&#xff08;双写一致性&#xff09;1.6.1、读…

微信小程序的服务调取

微信小程序的服务调取概述 微信小程序允许开发者通过网络请求与服务器进行交互&#xff0c;从而实现数据的上传和下载。这是通过小程序提供的API&#xff0c;如wx.request、wx.downloadFile、wx.uploadFile等来完成的。这些API使得小程序可以从远程服务器获取数据&#xff0c;…

打造智能化未来:智能运维系统架构解析与应用实践

在数字化转型的大背景下&#xff0c;智能运维系统成为了企业提升效率、降低成本、增强安全性的关键利器。本文将深入探讨智能运维系统的技术架构&#xff0c;介绍其核心要素和应用实践&#xff0c;帮助读者全面了解智能运维系统的概念、优势和应用价值。 ### 1. 智能运维系统的…

uniapp实现微信小程序调用云函数【vue3】

本人是从微信开发者工具写原生微信小程序一步一步走来&#xff0c;由于vue3框架的慢慢的步入前端市场&#xff0c;为了不被前端市场遗弃&#xff0c;果断从vue2开始步入vue3的学习&#xff0c;本人习惯在在HBuilder X写uniapp的项目&#xff0c;过去uniapp默认vue2框架&#xf…

MT3045 松鼠接松果

思路&#xff1a; 求x的一个区间&#xff0c;使区间中的松果的最大y坐标和最小y坐标的差至少为D。若有多个区间&#xff0c;则取最小的那个。 即使用单调队列不断维护最大值和最小值。 首先L固定不动&#xff0c;R不断右移&#xff1a; 即若函数f(R)max[L,R]-min[L,R] >…

Pytest框架中用例用例执行常用参数介绍

pytest 支持通过命令行参数来定制测试运行的方式。以下是一些常用的 pytest 执行参数介绍。 学习目录 -q 或 --quiet: 安静模式&#xff0c;只显示进度和摘要 -s : 选项允许在测试的输出中捕获 stdout 和 stderr。 -v : 选项会使 pytest 的输出更加详细。 -k &#xff1a;…

数据分析必备:一步步教你如何用Pandas做数据分析(15)

1、Pandas 数据丢失 Pandas 数据丢失的操作实例 在现实生活中&#xff0c;数据丢失始终是一个问题。机器学习和数据挖掘等领域在模型预测的准确性方面面临严重问题&#xff0c;因为缺少值会导致数据质量较差。在这些领域中&#xff0c;缺失值处理是使模型更准确和有效的主要重…

godot.bk2

1.$node_name 其实 就是 get_node 的语法糖 2.场景内部用get_node&#xff0c;场景外部用信号 这是自定义信号的绑定&#xff0c;如果是内置信号&#xff0c;直接右键点击链接到一个函数即可 3.场景切换和摄像头一直居中 4.class_name命名一个类&#xff0c;extends继承&…

【TB作品】MSP430F149,ADC采集,光强GY-30,DS18B20温度采集

功能 读取了GY-30 DS18B20 P6.0ADC P6.1ADC 显示到了LCD12864 硬件 //GY30 //SCL–P1.0 //SDA–P1.1 //VCC–3.3V //GND–GND //ADDR–不接 //DS18B20 //DATA–P1.6 //VCC–3.3V //GND–GND //ADC //DATA–P1.6 //P6.0 P6.1 ADC输入口 部分程序 #include <msp430.h>…