数字图像处理:边缘检测

news2024/11/19 1:41:06

数字图像处理:边缘检测

笔记来源:
1.Gradient and Laplacian Filter, Difference of Gaussians (DOG)

1.1 图像一阶梯度



水平方向的一阶导数





一阶导数滤波器在实际应用中难实现的原因


图像梯度中,一阶梯度中找局部极大值就是边缘所在处,二阶梯度中找过零点处就是边缘所在处


例如:这个函数f(x),对它求一阶导,无法找到局部极大值,即无法找到边缘


解决办法:首先对该函数进行一次高斯平滑,之后再求一阶导

在这里插入图片描述
将上述操作整合一下:对f进行高斯平滑后求导 等价于 对高斯求导后与原函数卷积

1.2 Roberts算子(一阶微分算子)


1.3 Prewitt算子(一阶微分算子)


1.4 Sobel算子(一阶微分算子)


1.5 图像二阶梯度

水平方向的二阶导数




我们发现像素变化剧烈的地方(即边缘),边缘处的二阶导比一阶导更加剧烈,也就是二阶导对细节的响应更强,二阶导比一阶导更有助于图像增强

1.6 Laplace算子(二阶微分算子)


在图像上应用拉普拉斯滤波器,我们得到一个图像,突出边缘和其他不连续性

拉普拉斯滤波的结果并不是增强后的图像,我们需要从原始图像中减去拉普拉斯滤波结果,生成最终的锐化增强图像

1.7 LoG算子(Laplacian of Gaussian,二阶微分算子)


对高斯二阶导后再与原函数卷积


1.8 DoG算子(Difference of Gaussians,二阶微分算子)


1.9 代码

(1)选取实验用的实验图像,完成图像读取和显示,给图像加上高斯噪声;
(2)利用三种一阶微分算子(Roberts、Prewitt、Sobel)和二阶微分算子(Laplace、LoG、DoG)实现边缘检测;

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 = 20  # 标准差(调整噪声强度)
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

# Roberts 算子
def roberts(image):
    kernel_x = np.array([[1, 0], [0, -1]], dtype=np.float32)
    kernel_y = np.array([[0, 1], [-1, 0]], dtype=np.float32)
    edge_x = cv.filter2D(image, -1, kernel_x)
    edge_y = cv.filter2D(image, -1, kernel_y)
    roberts_edge_image = np.sqrt(edge_x**2 + edge_y**2).astype(np.uint8)
    return roberts_edge_image

# Prewitt 算子
def prewitt(image):
    kernel_x = np.array([[1, 0, -1], [1, 0, -1], [1, 0, -1]], dtype=np.float32)
    kernel_y = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=np.float32)
    edge_x = cv.filter2D(image, -1, kernel_x)
    edge_y = cv.filter2D(image, -1, kernel_y)
    prewitt_edge_image = np.sqrt(edge_x**2 + edge_y**2).astype(np.uint8)
    return prewitt_edge_image

# Sobel 算子
def sobel(image):
    edge_x = cv.Sobel(image, cv.CV_64F, 1, 0, ksize=3)
    edge_y = cv.Sobel(image, cv.CV_64F, 0, 1, ksize=3)
    sobel_edge_image = np.sqrt(edge_x**2 + edge_y**2).astype(np.uint8)
    return sobel_edge_image

# Laplace 算子
def laplace(image):
    laplace_edge_image = cv.Laplacian(image, cv.CV_64F)
    laplace_edge_image = np.uint8(np.absolute(laplace_edge_image))  # 取绝对值并转换为uint8
    return laplace_edge_image

# LoG 算子 (Laplacian of Gaussian)
def loguass(image):
    blurred = cv.GaussianBlur(image, (5, 5), 0)  # 高斯平滑
    log_edge_image = cv.Laplacian(blurred, cv.CV_64F)  # Laplace 边缘检测
    log_edge_image = np.uint8(np.absolute(log_edge_image))  # 取绝对值并转换为uint8
    return log_edge_image

# DoG 算子 (Difference of Gaussian)
def dog(image):
    blurred1 = cv.GaussianBlur(image, (5, 5), 1)  # 第一次高斯模糊
    blurred2 = cv.GaussianBlur(image, (5, 5), 2)  # 第二次高斯模糊
    dog_edge_image = blurred1 - blurred2  # 两次模糊图像的差分
    dog_edge_image = np.uint8(np.absolute(dog_edge_image))  # 取绝对值并转换为uint8
    return dog_edge_image

# 进行边缘检测
roberts_edge_image = roberts(noisy_image_clipped)
prewitt_edge_image = prewitt(noisy_image_clipped)
sobel_edge_image = sobel(noisy_image_clipped)
laplace_edge_image = laplace(noisy_image_clipped)
log_edge_image = loguass(noisy_image_clipped)
dog_edge_image = dog(noisy_image_clipped)

# 定义运算及其标题
operations = [
    ("Original", gray),  # 原始图像
    ("Noised", noisy_image_clipped), 
    ("Roberts", roberts_edge_image),  
    ("Prewitt", prewitt_edge_image),  
    ("Sobel", sobel_edge_image),  
    ("Laplace", laplace_edge_image),
    ("LoG", log_edge_image), 
    ("DoG", dog_edge_image) 
]

# 绘图
plt.figure(figsize=(15, 7))  # 设置绘图窗口大小
for i, (title, result) in enumerate(operations, 1):  # 遍历运算结果
    plt.subplot(2, 4, i)  # 创建子图,2行4列
    plt.title(title)  # 设置子图标题
    plt.imshow(result, cmap='gray')  # 显示图像,使用灰度颜色映射
    plt.axis('off')  # 关闭坐标轴显示

plt.tight_layout()  # 自动调整子图布局,使之不重叠
plt.show()  # 显示图像

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2、Stable Diffusion

2、Stable Diffusion Stable Diffusion 是一种高效的文本到图像生成模型,它利用扩散模型(Diffusion Model)技术将自然语言描述转换为高质量的图像。其工作原理是通过反向扩散过程,逐渐将噪声引导到符合输入文本描述的图像上。相比…

HTB:Three[WriteUP]

使用OpenVPN连接并启动机器 1.How many TCP ports are open? 使用nmap对靶机进行扫描:nmap -sV 10.129.233.85 可见仅开启了 22、80 共2个端口 2.What is the domain of the email address provided in the "Contact" section of the website? 直接对…

探索自闭症寄宿学校:为孩子的未来铺设坚实基石

在自闭症儿童教育的广阔天地中,寄宿学校以其独特的教育模式和全方位的关怀体系,为这些特殊孩子提供了一个安全、稳定且充满爱的成长环境。这些学校不仅关注孩子们的学习与康复,更致力于培养他们独立生活的能力,为他们的未来铺设坚…

java 解析excel (网络资源)

在Java中解析Excel文件,可以使用Apache POI库。以下是一个简单的例子,展示如何使用Apache POI读取一个Excel文件(假设为.xlsx格式)的内容。 首先,确保你的项目中包含了Apache POI的依赖。如果你使用Maven,…

【muduo源码分析】「阻塞」「非阻塞」「同步」「异步」

欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 文章目录 引言何为「muduo库」安装muduo库阻塞、非阻塞、同步、异步数据准备数据准备 引言 从本篇博客开始,我会陆续发表muduo库源码分析的相关文章。感谢大家的持续关注!!…

ORM的了解

什么是ORM?为什么要用ORM?-CSDN博客 C高级编程(99)面向资源的设计思想(ORM)_c orm-CSDN博客 ORM:Object-Relational-Mapping 对象关系映射 -------------------------- 我想对数据库中的表A进行增删改…

International Journal of Metalcasting是否值得投稿?

International Journal of Metalcasting期刊如何? 投稿快不快?这是一本材料科学3区期刊,冶金工程3区期刊,是美国铸造协会(American Foundry Society)创办,Springer International Publishing出版的期刊,旨在促进金属铸造领域的…

电脑使用adb工具连接手机,全文完整教程

目录 前言 正文 前置条件 打开开发者选项 打开usb调试 连接步骤 1、保证电脑和手机在同一网络下 2、打开电脑cmd窗口。 3、在cmd窗口输入adb connect手机IP地址 4、验证 扩展 问题解决 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝…

D16【python接口自动化学习】-python基础之内置数据类型

day16 字典的常见操作(下) 学习日期:20240923 学习目标:内置数据类型--25 常见常新:字典的常见操作(下) 学习笔记: 字典的高级用法 # 字典的高级用法 # setdefaul函数 tom_mail …

CHI trans简介--Retry

总目录: CHI协议简读汇总-CSDN博客 Retry trans flow requester发送一个请求,该请求没有protocol credit(P-Credit); 也就是说,该请求不保证completer一定能够接收该trans;completer返回一个retry resp, RetryAck, 给到Requester;completer再…

关于GPIO输入模式的配置选择

GPIO(通用输入输出)口是嵌入式系统中的重要组成部分,输入模式使得微控制器能够与外部世界进行交互。本文将探讨GPIO输入模式中的浮空输入、上拉输入和下拉输入的配置、使用场景及注意事项,并提供一些决策指导,帮助读者…

技术速递|加入 .NET 智能组件生态系统

作者:Daniel Roth - 首席产品经理 排版:Alan Wang .NET 智能组件是一组示例嵌入式 UI 组件,使得在应用中轻松添加 AI 启用的功能变得更加简单,例如从剪贴板数据自动填写表单、智能文本补全以及语义搜索等场景。.NET 智能组件演示了…

【STM32开发环境搭建】-3-STM32CubeMX Project Manager配置-自动生成一个Keil(MDK-ARM) 5的工程

目录 1 KEIL(MDK-ARM) 5 Project工程设置 2 MCU和嵌入式软件包的选择 3 Code Generator 3.1 STM32Cube Firmware Library Package 3.2 Generated files 3.3 HAL Settings 3.4 Template Settings 4 Advanced Settings 5 自动生成的KEIL(MDK-ARM) 5 Project工程目录 结…

【hot100-java】【划分字母区间】

R9-贪心算法篇 印象题: 我记得,先用字典记录每个字母出现的下标,取出首个字母的下标j,然后我们for循环遍历一次,如果该下标大于 j,就要变化新的首字母,如果相等就说明一个字符串完成,如果小于就…

自动蛋鸡饲料机组:粉碎搅拌一步到位

蛋鸡养殖如何科学、高效地喂养蛋鸡,直接关系到蛋品的产量与质量。一款让养殖户赞不绝口的“黑科技”——蛋鸡饲料粉碎搅拌机组! 传统的蛋鸡饲料加工方式,往往依赖人工或简单机械,不仅效率低下,还难以保证饲料的均匀度…

MySQL 5.8 Performance Schema 配置详解

MySQL 5.8 Performance Schema 配置详解 MySQL 的 Performance Schema 是一个用于监控和优化数据库性能的子系统,专门用来收集 MySQL 服务器的运行情况和性能指标。它的核心原理是通过“生产者”和“消费者”的概念来采集和存储数据库中的事件信息,帮助…

第十四周周报:Transformer for CV

目录 摘要 Abstract 一、Swin Transformer 1.1 输入 1.2 Patch Partition 1.3 Linear Embedding 1.4 Patch Merging 1.5 Swin Transformer Block 1.6 代码 二、MLP-Mixer 2.1 网络模型整体结构 2.2 Mixer Layer 2.3 MLP 总结 摘要 本篇博客介绍了采用类似于卷积…

MySQL篇(leetcode刷题100(查询))(二)(持续更新迭代)

目录 一、普通查询 1. 可回收且低脂的产品(简单) 1.1. 题目描述 1.2. 解题思路 2. 寻找用户推荐人(简单) 2.1. 题目描述 2.2. 解题思路 3. 大的国家(简单) 3.1. 题目描述 3.2. 解题思路 4. 文章浏…

【JavaEE初阶】文件IO(下)

欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 文件内容操作 打开 关闭文件 文件描述符表 字节流 读文件 写文件 字符流 读文件 写文件 Scanner 示例一:通过scanner读取文件中的数字 示例二:扫描指定⽬录 示例三:实…

JUC第23讲:Java线程池最佳实践

JUC第23讲:Java线程池最佳实践 本文是JUC第23讲,先介绍为什么使用线程池;然后结合实际业务,讲解如何使用线程池,以及使用过程中踩过的坑。 1、Java线程池概述 1.1、什么是线程池? 线程池是一种用于管理和…