数字图像处理:空间域滤波
1.数字图像处理:空间域滤波
1.1 滤波器核(相关核)与卷积
图像上的邻域计算
线性空间滤波的原理
滤波器核(相关核)是如何得到的?
空间域的卷积
卷积:滤波器核与window中的对应值相乘后所有值相加得到一个像素值,滑动窗口遍历整个图像
滤波器核(相关核)与卷积的区别
截图来源:【小动画】彻底理解卷积【超形象】卷的由来,小元老师
滤波器核对称时,翻转与不翻转没有影响,所以卷积等于相关性
卷积的物理实质可以通过以下几个方面进行理解,这些方面涉及到信号处理、系统响应和图像处理等领域
1.2 图像加噪
噪声点的判定标准
由灰度直方图得到概率密度函数的方法
从含噪图像中确定具体噪声模型的系统化方法?
选取实验用的实验图像,完成图像读取和显示,给图像加上高斯噪声
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt# 打开图片并转换为灰度图像
img_dir = r'D:\Document\Experiment\data\image1.jpg'
# 读取图像并转换为灰度
gray = cv.imread(img_dir, 0)
image_array = np.array(gray)# 定义高斯噪声的参数
mean = 0 # 均值
sigma = 80 # 标准差(调整噪声强度)# 生成高斯噪声
gaussian_noise = np.random.normal(mean, sigma, image_array.shape)# 将噪声加入图像
noisy_image = image_array + gaussian_noise# 将噪声后的图像剪裁到0-255范围内,并转换为uint8
noisy_image_clipped = np.clip(noisy_image, 0, 255).astype(np.uint8)# 显示原图和加入噪声后的图像
plt.figure(figsize=(10,5))
plt.subplot(1,2,1)
plt.title('Original Image')
plt.imshow(image_array, cmap='gray')plt.subplot(1,2,2)
plt.title('Noisy Image')
plt.imshow(noisy_image_clipped, cmap='gray')
plt.show()
1.3 均值滤波、高斯滤波、中值滤波
均值滤波
高斯滤波
中值滤波
为了使得卷积能够正常进行,对原图像外围进行填充(padding)
用自己编写的滤波函数分别对实验图像进行滤波;
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt# 读取图像并转换为灰度
img_dir = r'D:\Document\Experiment\data\image1.jpg' # 图像路径
gray = cv.imread(img_dir, 0) # 读取图像,并将其转换为灰度图像# 定义高斯噪声的参数
mean = 0 # 高斯噪声的均值
sigma = 80 # 高斯噪声的标准差,用于控制噪声强度# 生成高斯噪声并添加到图像
gaussian_noise = np.random.normal(mean, sigma, gray.shape) # 生成与图像相同大小的高斯噪声
noisy_image = gray + gaussian_noise # 将生成的噪声添加到图像
noisy_image_clipped = np.clip(noisy_image, 0, 255).astype(np.uint8) # 将噪声叠加后的图像值限制在0到255,并转换为uint8类型# 均值滤波实现
# 其中,均值滤波一般的具体实现步骤是:
# .选择一个(2n+l) x (2n+l)的窗口(通常为3 x 3或5 x 5),并用该窗口沿图像数据进行行或列的滑动;
# .读取窗口下各对应像素的灰度值;
# .求取这些像素的灰度平均值替代窗口中心位置的原始像素灰度值。
def mean_filter(image, kernel_size=3):# 填充大小# 根据传入的窗口大小 kernel_size 计算需要的填充尺寸# 因为均值滤波会涉及到窗口的滑动,所以为了保持输出图像的尺寸与输入图像相同,需要在图像的边缘进行填充。对于 3x3 的窗口,pad_size 为 1;对于 5x5 的窗口,pad_size 为 2pad_size = kernel_size // 2 # 根据核大小计算需要的填充尺寸# 使用 np.pad 函数将原始图像进行填充,pad_size 为填充的边界大小,mode='constant' 指定使用常数值填充,constant_values=0 表示用 0 填充。这使得在处理图像边缘时能够避免索引超出边界的错误。padded_image = np.pad(image, pad_size, mode='constant', constant_values=0) # 用常数0填充图像边缘# 创建一个与输入图像 image 形状相同的全零数组 output_image,用于存储均值滤波后的结果。output_image = np.zeros_like(image) # 初始化输出图像,大小与原图一致# 滑动窗口进行均值滤波# 外层循环:通过 for 循环遍历填充后的图像的行,从 pad_size 开始到 padded_image.shape[0] - pad_size 结束。这样做是为了避免在处理图像边缘时出现越界for i in range(pad_size, padded_image.shape[0] - pad_size):# 内层循环:同样通过 for 循环遍历填充后的图像的列,范围与行的处理相同。这两个嵌套循环用于对图像的每一个像素进行处理for j in range(pad_size, padded_image.shape[1] - pad_size):# 获取窗口内的像素:通过切片操作从填充后的图像中获取当前窗口的像素值。窗口的大小为 (kernel_size, kernel_size),即从 (i-pad_size, j-pad_size) 到 (i+pad_size, j+pad_size) 的区域window = padded_image[i-pad_size:i+pad_size+1, j-pad_size:j+pad_size+1] # 获取窗口内的像素# 使用 np.mean(window) 计算窗口中像素值的平均值,并将结果赋值给输出图像 output_image 的对应位置。为了保持位置一致性,索引使用 i-pad_size 和 j-pad_sizeoutput_image[i-pad_size, j-pad_size] = np.mean(window) # 计算窗口像素的平均值,并赋给输出图像的对应位置return output_image # 返回滤波后的图像# 高斯滤波实现
# 高斯滤波一般的具体实现步骤是:
# .选择一个(2n+l) x (2n+l)的窗口(通常为3 x 3或5 x 5),生成二维高斯模板,并用该窗口沿图像数据进行行或列的滑动;
# .读取窗口下各对应像素的灰度值;
# .求取这些像素与二维高斯模板对应位置元素的乘积再求和,用该值替代窗口中心位置的原始像素灰度值。
def gaussian_kernel(kernel_size=3, sigma=1.0):k = kernel_size // 2 # 计算高斯核中心的偏移gaussian_kernel = np.zeros((kernel_size, kernel_size), dtype=np.float32) # 初始化高斯核for x in range(-k, k + 1): # 遍历核的行坐标for y in range(-k, k + 1): # 遍历核的列坐标gaussian_kernel[x + k, y + k] = np.exp(-(x**2 + y**2) / (2 * sigma**2)) # 根据高斯公式计算权重gaussian_kernel /= (2 * np.pi * sigma**2) # 归一化常数gaussian_kernel /= gaussian_kernel.sum() # 对高斯核进行归一化,使其所有元素的和为1return gaussian_kernel # 返回生成的高斯核def gaussian_filter(image, kernel_size=3, sigma=1.0):pad_size = kernel_size // 2 # 计算填充大小padded_image = np.pad(image, pad_size, mode='constant', constant_values=0) # 用常数0填充图像边缘output_image = np.zeros_like(image) # 初始化输出图像kernel = gaussian_kernel(kernel_size, sigma) # 生成高斯核# 滑动窗口进行高斯滤波for i in range(pad_size, padded_image.shape[0] - pad_size):for j in range(pad_size, padded_image.shape[1] - pad_size):window = padded_image[i-pad_size:i+pad_size+1, j-pad_size:j+pad_size+1] # 获取窗口内的像素output_image[i-pad_size, j-pad_size] = np.sum(window * kernel) # 计算窗口像素与高斯核的加权和return output_image # 返回滤波后的图像# 中值滤波实现
# 中值滤波一般的具体实现步骤是:
# .选择一个(2n+l)x(2n+l)的窗口(通常为3x3或5x5),并用该窗口沿图像数据进行行或列的滑动;
# .读取窗口下各对应像素的灰度值;
# .将这些灰度值从小到大排成一列,用排序所得的中值替代窗口中心位置的原始像素灰度值;
def median_filter(image, kernel_size=3):pad_size = kernel_size // 2 # 计算填充大小padded_image = np.pad(image, pad_size, mode='constant', constant_values=0) # 用常数0填充图像边缘output_image = np.zeros_like(image) # 初始化输出图像# 滑动窗口进行中值滤波for i in range(pad_size, padded_image.shape[0] - pad_size):for j in range(pad_size, padded_image.shape[1] - pad_size):# 获取窗口内的像素window = padded_image[i-pad_size:i+pad_size+1, j-pad_size:j+pad_size+1] output_image[i-pad_size, j-pad_size] = np.median(window) # 计算窗口像素的中值,并赋给输出图像的对应位置return output_image # 返回滤波后的图像# 进行均值滤波、高斯滤波、中值滤波
mean_filtered_img = mean_filter(noisy_image_clipped, kernel_size=3) # 应用均值滤波,使用3x3窗口
gaussian_filtered_img = gaussian_filter(noisy_image_clipped, kernel_size=3, sigma=1.0) # 应用高斯滤波,使用3x3窗口,sigma为1.0
median_filtered_img = median_filter(noisy_image_clipped, kernel_size=3) # 应用中值滤波,使用3x3窗口# 定义运算及其标题
operations = [("Original", gray), # 原始图像("Noised", noisy_image_clipped), # 添加噪声后的图像("Mean Filter", mean_filtered_img), # 均值滤波后的图像("Gaussian Filter", gaussian_filtered_img), # 高斯滤波后的图像("Median Filter", median_filtered_img) # 中值滤波后的图像
]# 绘图
plt.figure(figsize=(15, 7)) # 设置绘图窗口大小
for i, (title, result) in enumerate(operations, 1): # 遍历运算结果plt.subplot(2, 3, i) # 创建子图,2行3列plt.title(title) # 设置子图标题plt.imshow(result, cmap='gray') # 显示图像,使用灰度颜色映射plt.axis('off') # 关闭坐标轴显示plt.tight_layout() # 自动调整子图布局,使之不重叠
plt.show() # 显示图像
用OpenCV自带的滤波函数对实验图像分别进行滤波;
# (4)用OpenCV自带的滤波函数对实验图像分别进行滤波;
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt# 读取图像并转换为灰度
img_dir = r'D:\Document\Experiment\data\image1.jpg'
gray = cv.imread(img_dir, 0)# 灰度加噪(添加高斯噪声)
mean = 0 # 均值
sigma = 80 # 标准差(调整噪声强度)
gaussian_noise = np.random.normal(mean, sigma, gray.shape) # 生成高斯噪声
noisy_image = gray + gaussian_noise # 将噪声加入图像
noisy_image_clipped = np.clip(noisy_image, 0, 255).astype(np.uint8) # 剪裁到0-255范围并转换为uint8# 均值滤波实现
def mean_filter(image, kernel_size=5):# 使用cv2的blur函数进行均值滤波return cv.blur(image, (kernel_size, kernel_size))# 高斯滤波实现
def gaussian_filter(image, kernel_size=5, sigma=1.0):# 使用cv2的GaussianBlur函数进行高斯滤波return cv.GaussianBlur(image, (kernel_size, kernel_size), sigma)# 中值滤波实现
def median_filter(image, kernel_size=5):# 使用cv2的medianBlur函数进行中值滤波return cv.medianBlur(image, kernel_size)# 进行均值滤波、高斯滤波、中值滤波
mean_filtered_img = mean_filter(noisy_image_clipped)
gaussian_filtered_img = gaussian_filter(noisy_image_clipped)
median_filtered_img = median_filter(noisy_image_clipped)# 定义运算及其标题
operations = [("Original", gray),("Noised", noisy_image_clipped),("Mean Filter", mean_filtered_img),("Gaussian Filter", gaussian_filtered_img),("Median Filter", median_filtered_img)
]# 绘图
plt.figure(figsize=(15, 7))
for i, (title, result) in enumerate(operations, 1):plt.subplot(2, 3, i)plt.title(title)plt.imshow(result, cmap='gray')plt.axis('off') # 关闭坐标轴显示plt.tight_layout()
plt.show()
相关文章:

数字图像处理:空间域滤波
1.数字图像处理:空间域滤波 1.1 滤波器核(相关核)与卷积 图像上的邻域计算 线性空间滤波的原理 滤波器核(相关核)是如何得到的? 空间域的卷积 卷积:滤波器核与window中的对应值相乘后所有…...

【easypoi 一对多导入解决方案】
easypoi 一对多导入解决方案 1.需求2.复现问题2.1校验时获取不到一对多中多的完整数据2.2控制台报错 Cannot add merged region B5:B7 to sheet because it overlaps with an existing merged region (B3:B5). 3.如何解决第二个问题处理: Cannot add merged region …...
DDOS攻击会对网站服务器造成哪些影响?
DDOS攻击作为日常生活正比较常见的网络攻击类型,可以让多台计算机在同一时间内遭受到攻击,下面小编就带领大家一起来了解一下DDOS攻击会对网站服务器造成哪些影响吧! 首先DDOS攻击在进行攻击的过程中,可以对源IP地址进行伪造&…...

linux基础指令的认识
在正式学习linux前,可以简单认识一下linux与win的区别 win:是图形界面,用户操作更简单;在刚开始win也是黑屏终端 指令操作,图形界面就是历史发展的结果。Linux:也存在图形界面比如desktop OS;但…...

html5 + css3(下)
目录 CSS基础基础认识体验cssCSS引入方式 基础选择器选择器-标签选择器-类选择器-id选择器-通配符 字体和文本样式1.1 字体大小1.2 字体粗细1.3 字体样式(是否倾斜)1.4 常见字体系列(了解)1.5 字体系列拓展-层叠性font复合属性文本…...

828华为云征文|部署个人文档管理系统 Docspell
828华为云征文|部署个人文档管理系统 Docspell 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 Docspell3.1 Docspell 介绍3.2 Docspell 部署3.3 Docspell 使用…...

【深度学习】—激活函数、ReLU 函数、 Sigmoid 函数、Tanh 函数
【深度学习】—激活函数、ReLU 函数、 Sigmoid 函数、Tanh 函数 4.1.2 激活函数ReLU 函数参数化 ReLU Sigmoid 函数背景绘制 sigmoid 函数Sigmoid 函数的导数 Tanh 函数Tanh 函数的导数总结 4.1.2 激活函数 激活函数(activation function)用于计算加权和…...

对于基础汇编的趣味认识
汇编语言 机器指令 机器语言是机器指令的集合 机器指令展开来讲就是一台机器可以正确执行的命令 电子计算机的机器指令是一列二进制数字 (计算机将其转变为一列高低电平,使得计算机的电子器件受到驱动,进行运算 寄存器:微处理器…...
网络基础知识笔记(一)
什么是计算机网络 1.计算机网络发展的第一个阶段:(60年代) 标志性事件:ARPANET 关键技术:分组交换 计算机网络发展的第二个阶段:(70-80年代) 标志性事件:NSFNET 关键技术:TCP/IP 计算机网络发展的第三个阶段ÿ…...
fatal: urdf 中的 CRLF 将被 LF 替换
git add relaxed_ik_ros2 fatal: relaxed_ik_ros2/relaxed_ik_core/configs/urdfs/mobile_spot_arm.urdf 中的 CRLF 将被 LF 替换 这个错误信息表示 Git 在处理文件 mobile_spot_arm.urdf 时发现它使用了 CRLF(回车换行符,常见于 Windows 系统࿰…...

构建electron项目
1. 使用electron-vite构建工具 官网链接 安装构建工具 pnpm i electron-vite -g创建electron-vite项目 pnpm create quick-start/electron安装所有依赖 pnpm i其他 pnpm -D add sass scss1. 启动项目 2. 配置 package.json "dev": "electron-vite dev --…...

Stable Diffusion绘画 | 插件-Deforum:动态视频生成(中篇)
本篇文章重点讲解参数最多的 关键帧 模块。 「动画模式」选择「3D」: 下方「运动」Tab 会有一系列参数: 以下4个参数,只有「动画模式」选择「2D」才会生效,可忽略: 运动 平移 X 让镜头左右移动: 大于0&a…...

STM32中断——外部中断
目录 一、概述 二、外部中断(Extern Interrupt简称EXTI) 三、实例-对射式红外传感器 1、配置中断: 2 、完整代码 一、概述 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当…...
LeetCode78 子集
题目: 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出:[[…...

《python语言程序设计》2018版第8章19题几何Rectangle2D类(下)-头疼的几何和数学
希望这个下集里能有完整的代码 一、containsPoint实现 先从网上找一下Statement expected, found Py:DEDENTTAB还是空格呢??小小总结如何拆分矩形的四个点呢.我们来小小的测试一下这个函数结果出在哪里呢???修改完成variable in function should be lowercase 函数变量应该…...

【C++】入门基础介绍(上)C++的发展历史与命名空间
文章目录 1. 前言2. C发展历史2. 1 C版本更新特性一览2. 2 关于C23的一个小故事: 3. C的重要性3. 1 编程语言排行榜3. 2 C在工作领域中的应用 4. C学习建议和书籍推荐4. 1 C学习难度4. 2 学习书籍推荐 5. C的第一个程序6. 命名空间6. 1 namespace的价值6. 2 namespace的定义6. …...

dll动态库加载失败导致程序启动报错以及dll库加载失败的常见原因分析与总结
目录 1、问题说明 2、dll库的隐式加载与动态加载 2.1、dll库的隐式加载 2.2、dll库的显式加载 3、使用Process Explorer查看进程加载的dll库信息以及动态加载的dll库有没有加载成功 3.1、使用Process Explorer查看进程加载的dll库信息 3.2、使用Process Explorer查看动态…...

SAP MM学习笔记 - 豆知识10 - OMSY 初期化会计期间,ABAP调用MMPV/MMRV来批量更新会计期间(TODO)
之前用MMRV,MMPV来一次一个月来修改会计期间。 如果是老的测试机,可能是10几年前的,一次1个月,更新到当前期间,搞个100多次,手都抖。 SAP MM学习笔记 - 错误 M7053 - Posting only possible in periods 2…...

Pytorch实现RNN实验
一、实验要求 用 Pytorch 模块的 RNN 实现生成唐诗。要求给定一个字能够生成一首唐诗。 二、实验目的 理解循环神经网络(RNN)的基本原理:通过构建一个基于RNN的诗歌生成模型,学会RNN是如何处理序列数据的,以及如何在…...

四、Drf认证组件
四、Drf认证组件 4.1 快速使用 from django.shortcuts import render,HttpResponse from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.authentication import BaseAuthentication from rest_framework.exception…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...