python实现图像特征提取算法1

python实现Marr-Hildreth算法、Canny边缘检测器算法

      • 1.Marr-Hildreth算法详解
        • 算法步骤
        • 公式
        • Python 实现
        • 详细解释
        • 优缺点
      • 2.Canny边缘检测器算法详解
        • 算法步骤
        • 公式
        • Python 实现
        • 详细解释
        • 优缺点

1.Marr-Hildreth算法详解

Marr-Hildreth算法是一个用于图像边缘检测的经典算法,其基本思想是通过检测图像的二阶导数(拉普拉斯算子)来找到边缘。该算法首先对图像进行高斯平滑处理,以减少噪声,然后计算拉普拉斯算子,最后通过检测零交叉点来确定边缘。

算法步骤
  1. 高斯平滑:使用高斯滤波器对图像进行平滑处理,以减少噪声。
  2. 计算拉普拉斯算子:对平滑后的图像计算拉普拉斯算子。
  3. 检测零交叉点:在拉普拉斯算子图像中检测零交叉点,这些点即为边缘。
公式

在这里插入图片描述

Python 实现

以下是Marr-Hildreth算法的Python实现代码:

import numpy as np
import cv2
import matplotlib.pyplot as pltdef marr_hildreth(image, sigma=1.4):"""Marr-Hildreth边缘检测算法实现参数:image (numpy.ndarray): 输入的灰度图像sigma (float): 高斯平滑的标准差返回:numpy.ndarray: 边缘检测后的二值化图像"""# 1. 高斯平滑smoothed_image = cv2.GaussianBlur(image, (0, 0), sigma)# 2. 计算拉普拉斯算子laplacian = cv2.Laplacian(smoothed_image, cv2.CV_64F)# 3. 检测零交叉点zero_crossing = np.zeros_like(laplacian)for i in range(1, laplacian.shape[0] - 1):for j in range(1, laplacian.shape[1] - 1):if laplacian[i, j] == 0:if (laplacian[i, j-1] < 0 and laplacian[i, j+1] > 0) or (laplacian[i, j-1] > 0 and laplacian[i, j+1] < 0) or \(laplacian[i-1, j] < 0 and laplacian[i+1, j] > 0) or (laplacian[i-1, j] > 0 and laplacian[i+1, j] < 0):zero_crossing[i, j] = 255elif laplacian[i, j] < 0:if (laplacian[i, j-1] > 0 or laplacian[i, j+1] > 0 or laplacian[i-1, j] > 0 or laplacian[i+1, j] > 0):zero_crossing[i, j] = 255return zero_crossing# 示例用法
if __name__ == "__main__":# 读取灰度图像image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)# 调用Marr-Hildreth边缘检测算法edges = marr_hildreth(image)# 显示原始图像和边缘检测后的图像plt.figure(figsize=(12, 6))plt.subplot(1, 2, 1)plt.title('Original Image')plt.imshow(image, cmap='gray')plt.axis('off')plt.subplot(1, 2, 2)plt.title('Marr-Hildreth Edges')plt.imshow(edges, cmap='gray')plt.axis('off')plt.show()
详细解释
  1. 读取图像并转换为灰度图像

    image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
    
  2. 高斯平滑

    smoothed_image = cv2.GaussianBlur(image, (0, 0), sigma)
    

    这里使用OpenCV的GaussianBlur函数对图像进行高斯平滑处理。

  3. 计算拉普拉斯算子

    laplacian = cv2.Laplacian(smoothed_image, cv2.CV_64F)
    

    使用OpenCV的Laplacian函数计算平滑后的图像的拉普拉斯算子。

  4. 检测零交叉点

    zero_crossing = np.zeros_like(laplacian)
    for i in range(1, laplacian.shape[0] - 1):for j in range(1, laplacian.shape[1] - 1):if laplacian[i, j] == 0:if (laplacian[i, j-1] < 0 and laplacian[i, j+1] > 0) or (laplacian[i, j-1] > 0 and laplacian[i, j+1] < 0) or \(laplacian[i-1, j] < 0 and laplacian[i+1, j] > 0) or (laplacian[i-1, j] > 0 and laplacian[i+1, j] < 0):zero_crossing[i, j] = 255elif laplacian[i, j] < 0:if (laplacian[i, j-1] > 0 or laplacian[i, j+1] > 0 or laplacian[i-1, j] > 0 or laplacian[i+1, j] > 0):zero_crossing[i, j] = 255
    

    通过遍历拉普拉斯算子图像中的每个像素,并根据其相邻像素值检测零交叉点,从而确定边缘。

  5. 显示和保存边缘检测后的图像

    plt.subplot(1, 2, 1)
    plt.title('Original Image')
    plt.imshow(image, cmap='gray')
    plt.axis('off')plt.subplot(1, 2, 2)
    plt.title('Marr-Hildreth Edges')
    plt.imshow(edges, cmap='gray')
    plt.axis('off')
    plt.show()
    
优缺点

优点

  • 噪声抑制:通过高斯平滑处理,可以有效地抑制噪声。
  • 边缘检测准确:通过检测零交叉点,能够准确地找到图像中的边缘。

缺点

  • 计算复杂度高:计算高斯平滑和拉普拉斯算子比较耗时。
  • 参数敏感:平滑参数(σ)对结果影响较大,需要根据具体图像进行调整。

Marr-Hildreth算法通过高斯平滑和拉普拉斯算子相结合,实现了对图像边缘的有效检测,广泛应用于图像处理和计算机视觉领域。

2.Canny边缘检测器算法详解

Canny边缘检测器是一种经典的图像处理算法,用于检测图像中的边缘。它通过多步骤的处理流程来实现高质量的边缘检测,包括高斯平滑、计算梯度、非极大值抑制、双阈值检测和边缘跟踪。

算法步骤
  1. 高斯平滑:使用高斯滤波器对图像进行平滑处理,以减少噪声。
  2. 计算梯度:计算图像的梯度强度和方向。
  3. 非极大值抑制:对梯度图像进行非极大值抑制,以细化边缘。
  4. 双阈值检测:通过设定高低阈值,将像素分类为强边缘、弱边缘和非边缘。
  5. 边缘跟踪:通过连接强边缘像素,形成完整的边缘。
公式

在这里插入图片描述

Python 实现

以下是Canny边缘检测器的Python实现代码:

import numpy as np
import cv2
import matplotlib.pyplot as pltdef canny_edge_detection(image, sigma=1.4, low_threshold=20, high_threshold=60):"""Canny边缘检测算法实现参数:image (numpy.ndarray): 输入的灰度图像sigma (float): 高斯平滑的标准差low_threshold (int): 双阈值低阈值high_threshold (int): 双阈值高阈值返回:numpy.ndarray: 边缘检测后的二值化图像"""# 1. 高斯平滑smoothed_image = cv2.GaussianBlur(image, (5, 5), sigma)# 2. 计算梯度G_x = cv2.Sobel(smoothed_image, cv2.CV_64F, 1, 0, ksize=3)G_y = cv2.Sobel(smoothed_image, cv2.CV_64F, 0, 1, ksize=3)# 3. 计算梯度强度和方向magnitude = np.sqrt(G_x**2 + G_y**2)angle = np.arctan2(G_y, G_x) * (180 / np.pi)angle[angle < 0] += 180  # 调整角度范围从0到180度# 4. 非极大值抑制nms_image = np.zeros_like(smoothed_image)for i in range(1, magnitude.shape[0] - 1):for j in range(1, magnitude.shape[1] - 1):if (0 <= angle[i, j] < 22.5 or 157.5 <= angle[i, j] <= 180) or (22.5 <= angle[i, j] < 67.5):if magnitude[i, j] >= max(magnitude[i, j-1], magnitude[i, j+1]):nms_image[i, j] = magnitude[i, j]elif (67.5 <= angle[i, j] < 112.5):if magnitude[i, j] >= max(magnitude[i-1, j-1], magnitude[i+1, j+1]):nms_image[i, j] = magnitude[i, j]elif (112.5 <= angle[i, j] < 157.5):if magnitude[i, j] >= max(magnitude[i-1, j], magnitude[i+1, j]):nms_image[i, j] = magnitude[i, j]# 5. 双阈值检测和边缘跟踪edges = np.zeros_like(nms_image)strong_edge = 255weak_edge = 50strong_i, strong_j = np.where(nms_image >= high_threshold)weak_i, weak_j = np.where((nms_image >= low_threshold) & (nms_image < high_threshold))edges[strong_i, strong_j] = strong_edgeedges[weak_i, weak_j] = weak_edge# 边缘跟踪for i in range(1, edges.shape[0] - 1):for j in range(1, edges.shape[1] - 1):if edges[i, j] == weak_edge:if np.any(edges[i-1:i+2, j-1:j+2] == strong_edge):edges[i, j] = strong_edgeelse:edges[i, j] = 0return edges# 示例用法
if __name__ == "__main__":# 读取灰度图像image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)# 调用Canny边缘检测算法edges = canny_edge_detection(image)# 显示原始图像和边缘检测后的图像plt.figure(figsize=(12, 6))plt.subplot(1, 2, 1)plt.title('Original Image')plt.imshow(image, cmap='gray')plt.axis('off')plt.subplot(1, 2, 2)plt.title('Canny Edges')plt.imshow(edges, cmap='gray')plt.axis('off')plt.show()
详细解释
  1. 读取图像并转换为灰度图像

    image = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
    
  2. 高斯平滑

    smoothed_image = cv2.GaussianBlur(image, (5, 5), sigma)
    

    这里使用OpenCV的GaussianBlur函数对图像进行高斯平滑处理,以减少噪声。

  3. 计算梯度

    G_x = cv2.Sobel(smoothed_image, cv2.CV_64F, 1, 0, ksize=3)
    G_y = cv2.Sobel(smoothed_image, cv2.CV_64F, 0, 1, ksize=3)
    

    使用OpenCV的Sobel函数计算平滑后的图像在水平和垂直方向的梯度。

  4. 计算梯度强度和方向

    magnitude = np.sqrt(G_x**2 + G_y**2)
    angle = np.arctan2(G_y, G_x) * (180 / np.pi)
    angle[angle < 0] += 180
    

    计算梯度强度和方向,注意调整方向角度范围从0到180度。

  5. 非极大值抑制

    for i in range(1, magnitude.shape[0] -

1):
for j in range(1, magnitude.shape[1] - 1):
if (0 <= angle[i, j] < 22.5 or 157.5 <= angle[i, j] <= 180) or (22.5 <= angle[i, j] < 67.5):
if magnitude[i, j] >= max(magnitude[i, j-1], magnitude[i, j+1]):
nms_image[i, j] = magnitude[i, j]
elif (67.5 <= angle[i, j] < 112.5):
if magnitude[i, j] >= max(magnitude[i-1, j-1], magnitude[i+1, j+1]):
nms_image[i, j] = magnitude[i, j]
elif (112.5 <= angle[i, j] < 157.5):
if magnitude[i, j] >= max(magnitude[i-1, j], magnitude[i+1, j]):
nms_image[i, j] = magnitude[i, j]
```
在梯度方向上执行非极大值抑制,以保留局部梯度最大值,细化边缘。

  1. 双阈值检测和边缘跟踪

    edges = np.zeros_like(nms_image)
    strong_edge = 255
    weak_edge = 50
    strong_i, strong_j = np.where(nms_image >= high_threshold)
    weak_i, weak_j = np.where((nms_image >= low_threshold) & (nms_image < high_threshold))edges[strong_i, strong_j] = strong_edge
    edges[weak_i, weak_j] = weak_edge# 边缘跟踪
    for i in range(1, edges.shape[0] - 1):for j in range(1, edges.shape[1] - 1):if edges[i, j] == weak_edge:if np.any(edges[i-1:i+2, j-1:j+2] == strong_edge):edges[i, j] = strong_edgeelse:edges[i, j] = 0
    

    根据设定的高低阈值,将像素分类为强边缘、弱边缘和非边缘,并通过边缘跟踪将弱边缘连接成完整的边缘。

  2. 显示和保存边缘检测后的图像

    plt.subplot(1, 2, 1)
    plt.title('Original Image')
    plt.imshow(image, cmap='gray')
    plt.axis('off')plt.subplot(1, 2, 2)
    plt.title('Canny Edges')
    plt.imshow(edges, cmap='gray')
    plt.axis('off')
    plt.show()
    

    使用Matplotlib库显示原始图像和Canny边缘检测后的图像。

优缺点

优点

  • 准确性高:能够检测出细节丰富的边缘。
  • 抗噪声能力强:通过高斯平滑和非极大值抑制,有效抑制噪声。
  • 参数少:只需设置两个阈值参数。

缺点

  • 计算复杂度高:包括高斯滤波和梯度计算等多个步骤,对计算资源要求较高。
  • 对图像质量敏感:图像质量对结果影响较大,需要进行适当的预处理。

Canny边缘检测器因其高精度和可控性而被广泛应用于计算机视觉和图像处理领域,特别适用于需要精确边缘检测的应用场景。

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

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

相关文章

思维+01背包,LeetCode LCP 47. 入场安检

一、题目 1、题目描述 「力扣挑战赛」 的入场仪式马上就要开始了&#xff0c;由于安保工作的需要&#xff0c;设置了可容纳人数总和为 M 的 N 个安检室&#xff0c;capacities[i] 记录第 i 个安检室可容纳人数。安检室拥有两种类型&#xff1a; 先进先出&#xff1a;在安检室中…

Git笔记:(上传Git、Git获取文件版本、删除、统计)

目录 一、上传文件到github 1.1 配置用户名和邮箱 1.2 初始化本地仓库 1.3 添加项目目录下所有文件至本地仓库 1.4 使用如下命令加入注释提交 1.5 将本地仓库与远程仓库相连接 1.6 将本地仓库中的文件推送至指定的远程仓库中 二、git获取不同版本 2.1 git下载特定历史…

【SpringBoot3】全局异常处理

【SpringBoot3】全局异常处理 一、全局异常处理器step1&#xff1a;创建收入数字的页面step2:创建控制器&#xff0c;计算两个整数相除step3:创建自定义异常处理器step5&#xff1a;创建给用提示的页面step6&#xff1a;测试输入&#xff08;10/0&#xff09; 二、BeanValidato…

【Python正则表达式】:文本解析与模式匹配

文章目录 1.正则表达式2. re模块3.修饰符3.元字符3-1 字符匹配元字符3-2 重复次数限定元字符3-3 字符集合匹配元字符3-4 分组元字符3-5 边界匹配元字符3-6 字符类别匹配元字符 4.技巧4-1 贪婪与非贪婪 5.案例 1.正则表达式 正则表达式面向什么样的问题&#xff1f; 1、判断一个…

【Linux】线程——线程互斥的概念、锁的概念、互斥锁的使用、死锁、可重入和线程安全、线程同步、条件变量的概念和使用

文章目录 Linux线程4. 线程互斥4.1 线程互斥的概念4.2 锁的概念4.2.1 互斥锁的概念4.2.2 互斥锁的使用4.2.3 死锁4.2.4 可重入和线程安全 5. 线程同步5.1 条件变量的概念5.2 条件变量的使用 Linux线程 4. 线程互斥 我们之前使用了线程函数实现了多线程的简单计算模拟器。 可以…

如何在 Android 中删除和恢复照片

对于智能手机用户来说&#xff0c;相机几乎已经成为一种条件反射&#xff1a;你看到值得注意的东西&#xff0c;就拍下来&#xff0c;然后永远保留这段记忆。但如果那张照片不值得永远保留怎么办&#xff1f;众所周知&#xff0c;纸质快照拿在手里很难舍弃&#xff0c;而 Andro…

php通用防伪溯源查询系统可自定义字段

性能描述&#xff1a; 1. 适合中小规模查询&#xff0c;建议100万条以内(具体视服务器配置)。 2. 自定义前台是否使用验证码&#xff0c;即可以自行开启/关闭验证码。 3. 灵活支持N列内容&#xff0c;只要前几列按照规则;其余列均自定义内容。 4. 可单个新加&#xff0c;也…

【测开能力提升-fastapi框架】fastapi能力提升 - ORM增删改查操作

1 ORM操作 注释&#xff1a; fastapi缺少合适的ORM&#xff0c;官方推荐&#xff1a;sqlalchemy&#xff0c;但我们就不听官方的话&#xff0c;我们选择使用Tortoise ORM&#xff0c;因为他是支持异步的 1.1 tortoise ORM支持的数据库 PostgreSQL&#xff08;使用asyncpg&am…

上市公司产品市场竞争程度指数(1990-2023年)

数据来源&#xff1a;基础数据来源于上市公司年报以及证监会及统计局时间跨度&#xff1a; 1990-2023年数据范围&#xff1a;企业及行业层面数据指标&#xff1a;本数据包含赫芬达尔指数/行业集中度/勒纳指数三个数据: 行业代码 行业名称 统计截止日期 市场类型 是否…

指针!!C语言(第二篇)

目录 一. 数组名的理解 二. 一维数组传参的本质 三. 冒泡排序法 四. 二级指针与指针数组 五. 字符指针变量与数组指针 一. 数组名的理解 在我们对指针有了初步的理解之外&#xff0c;今天我们来掌握一些新的知识就是数组与指针&#xff0c;第一个对数组名的了解&#xff…

#三元运算符(python/java/c)

引入&#xff1a;什么是三元运算符呢&#xff1f;无疑其操作元有三个&#xff0c;一个是条件表达式&#xff0c;剩余两个为值&#xff0c;条件表达式为真时运算取第一个值&#xff0c;为假时取第二个值。 一 Python true_expression if condition else false_expressi…

matlab永磁同步电机反馈试验装置的设计和永磁同步电机仿真

1、内容简介 略 85-可以交流、咨询、答疑 2、内容说明 略 摘要&#xff1a;得益于电力电子器件及控制技术的高速发展&#xff0c;使得电机的应用越来越方便及精确&#xff0c;适应了实际应用对电机性能及质量提出的更高要求和标准。同时电机测试技术也因为电力电子技术的发…

AI多模态实战教程:面壁智能MiniCPM-V多模态大模型问答交互、llama.cpp模型量化和推理

一、项目简介 MiniCPM-V 系列是专为视觉-语⾔理解设计的多模态⼤型语⾔模型&#xff08;MLLMs&#xff09;&#xff0c;提供⾼质量的⽂本输出&#xff0c;已发布4个版本。 1.1 主要模型及特性 &#xff08;1&#xff09;MiniCPM-Llama3-V 2.5&#xff1a; 参数规模: 8B性能…

将Excel或CSV文件导入MySQL

数据库信息 版本:mysql-5.7.22 字符集如下 一、将 Excel 文件导入 MySQL,此时 MySQL 中不存在该表。 在数据库中,右键-导入向导

刚刚 威尼斯影评人周公布 2024 年电影阵容 包括敏感纪录片《本土》

《本土》 威尼斯影评人周是威尼斯电影节专门为首次拍摄电影的人设立的侧边活动&#xff0c;该活动公布了第 39 届威尼斯电影节的七部竞赛片和两部非竞赛片的入选名单&#xff0c;第 39 届威尼斯电影节将于 8 月 28 日至 9 月 7 日举行。 较为及时的作品之一是美国导演迈克尔普…

【IntelliJ IDEA】一篇文章集合所有IDEA的所有设置

IntelliJ IDEA 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;其设置涵盖了多个方面&#xff0c;以满足不同开发者的需求和偏好。由于 IDEA 的设置相当复杂和详尽&#xff0c;这里无法在一篇简短的文章中详细介绍所有设置。然而&#xff0c;我可以提供一…

持续集成07--Jenkins配置Allure测试报告

前言 在持续集成&#xff08;CI&#xff09;流程中&#xff0c;自动化测试报告是评估软件质量和追踪问题的重要工具。Allure Framework作为一个轻量级且功能丰富的测试报告工具&#xff0c;能够生成详细的测试报告&#xff0c;帮助团队更好地理解测试结果。本章节“持续集成07-…

Java二十三种设计模式-装饰器模式(7/23)

装饰器模式&#xff1a;动态扩展功能的灵活之选 引言 装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;用于在不修改对象自身的基础上&#xff0c;通过添加额外的职责来扩展对象的功能。 基础知识&#xff0c;java设计模式总体来说设计…

特征工程方法总结

方法有以下这些 首先看数据有没有重复值、缺失值情况 离散&#xff1a;独热 连续变量&#xff1a;离散化&#xff08;也成为分箱&#xff09; 作用&#xff1a;1.消除异常值影响 2.引入非线性因素&#xff0c;提升模型表现能力 3.缺点是会损失一些信息 怎么分&#xff1a;…

爬取百度图片,想爬谁就爬谁

前言 既然是做爬虫&#xff0c;那么肯定就会有一些小心思&#xff0c;比如去获取一些自己喜欢的资料等。 去百度图片去抓取图片吧 打开百度图片网站&#xff0c;点击搜索xxx&#xff0c;打开后&#xff0c;滚动滚动条&#xff0c;发现滚动条越来越小&#xff0c;说明图片加载…