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

news2025/1/10 17:17:31

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 plt

def 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] = 255
            elif 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

    return 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] = 255
            elif 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 plt

def 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 = 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_edge
                else:
                    edges[i, j] = 0

    return 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_edge
                else:
                    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.coloradmin.cn/o/1941832.html

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

相关文章

一些和颜色相关网站

1.中国传统色 2.网页颜色选择器 3.渐变色网站 4.多风格色卡生成 5.波浪生成 6.半透明磨砂框

基于3D开发引擎HOOPS平台的大型三维PLM系统的设计、开发与应用

产品生命周期管理&#xff08;Product Lifecycle Management&#xff0c;PLM&#xff09;系统在现代制造业中扮演着至关重要的角色。随着工业4.0和智能制造的推进&#xff0c;PLM系统从最初的CAD和PDM系统发展到现在的全面集成、协作和智能化的平台。本文将探讨基于HOOPS平台的…

四大引用——强软弱虚

目录 一、强引用 二、软引用 三、弱引用 四、虚引用 一、强引用 强引用是在程序代码之中普遍存在的&#xff0c;类似于“Object obj new Object()”&#xff0c;obj变量引用Object这个对象&#xff0c;就叫做强引用。当内存空间不足&#xff0c;Java虚拟机宁愿抛出OutOfMe…

乐鑫AWS IoT ExpressLink方案,简化物联网设备连接AWS IoT服务

在现代科技迅速发展的今天&#xff0c;物联网&#xff08;IoT&#xff09;已经成为连接物理世界与数字世界的重要桥梁&#xff0c;越来越多的设备开始接入网络&#xff0c;实现智能化控制。 在这个大背景下&#xff0c;乐鑫携手亚马逊&#xff0c;推出了AWS IoT ExpressLink方…

【机器学习】机器学习解决的问题特点、机器学习学的是什么、怎么学、如何构建高效机器学习模型的策略、机器学习的分类以及机器学习、模式识别、数据挖掘和人工智能的区别

引言 机器学习是人工智能的一个重要分支&#xff0c;主要解决的是如何通过算法让机器从数据中自动学习规律和知识&#xff0c;以完成特定任务或解决特定问题。 文章目录 引言一、机器学习解决的是什么样的问题1.2 数据驱动的预测问题1.3 数据理解与挖掘1.4 优化与决策问题1.5 异…

一个简单好用安全的开源交互审计系统,支持SSH,Telnet,Kubernetes协议(带私活)

前言 在当今的企业网络环境中&#xff0c;远程访问和交互审计成为了保障网络安-全的重要组成部分。然而&#xff0c;现有的解-决方案往往存在一些痛点&#xff0c;如复杂的配置、有限的协议支持、以及审计功能的不足。这些问题不仅增加了IT管理员的负担&#xff0c;也为企业的…

泰迪智能科技携广州华商学院共讨产教融合,校企合作

7月19日&#xff0c;广州华商学院人工智能学院的领导及骨干教师一行莅临泰迪智能科技参观交流&#xff0c;广州华商学院人工智能学院院长助理杨本胜、院长助理洪绍勇、大数据系主任颜远海、金融数学系主任石金诚、人工智能系主任霍永良&#xff0c;以及骨干教师许丽娟、李志青、…

二十、【机器学习】【非监督学习】- 均值漂移 (Mean Shift)

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…

Electron 渲染进程直接调用主进程的API库@electron/remote引用讲解

背景 remote是个老库&#xff0c;早期Electron版本中有个remote对象&#xff0c;这个对象可以横跨所有进程&#xff0c;随意通信&#xff0c;后来官方认为不安全&#xff0c;被干掉了&#xff0c;之后有人利用Electron的IPC通信&#xff0c;底层通过Promise的await能力&#x…

Text Control 控件教程:使用 .NET C# 中的二维码和条形码增强文档

QR 码和条形码非常适合为文档和 PDF 文件增加价值&#xff0c;因为它们提供轻松的信息访问、验证信息、跟踪项目和提高交互性。条形码可以弥补纸质或数字人类可读文档与网络门户或网络应用程序中的数字信息之间的差距。大多数用户都熟悉 QR 码和条形码&#xff0c;它们在许多过…

Cannot perform upm operation: connect ETIMEDOUT 34.36.199.114:443 [NotFound]

版本&#xff1a;Unity 2018 Windows 问题&#xff1a;打开 Package Manager&#xff0c;加载报错 尝试解决&#xff1a; 删除项目文件里的Packages下的mainfest.json文件&#xff0c;然后重新打开项目&#xff08;X&#xff09;重新登录 Unity 账号&#xff08;X&#xff09…

Http 和 Https 的区别(图文详解)

在现代网络通信中&#xff0c;保护数据的安全性和用户的隐私是至关重要的。HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是两种常见的网络通信协议&#xff0c;但它们在数据保护方面的能力存在…

立创梁山派--移植开源的SFUD万能的串行 Flash 通用驱动库

SFUD是什么 关于SFUD库的介绍&#xff0c;其开源链接(gitee,github)已经详细的阐述了. 这里是截取自它的一部分介绍&#xff1a; SFUD 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多&#xff0c;各个 Flash 的规格及命令存在差异&#xff0c; SF…

Linux云计算 |【第一阶段】SERVICES-DAY5

主要内容&#xff1a; 源码编译安装、rsync同步操作、inotify实时同步、数据库服务基础 实操前骤&#xff1a;&#xff08;所需tools.tar.gz与users.sql&#xff09; 1.两台主机设置SELinnx和关闭防火墙 setenforce 0 systemctl stop firewalld.service //停止防火墙 sy…

<数据集>水果识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;10012张 标注数量(xml文件个数)&#xff1a;10012 标注数量(txt文件个数)&#xff1a;10012 标注类别数&#xff1a;7 标注类别名称&#xff1a;[Watermelon, Orange, Grape, Apple, peach, Banana, Pineapple] 序…

常见的数据集格式

常见的数据集格式有三种&#xff0c;分别为voc(xml)、coco(json)、yolo(txt)。 1 VOC VOC数据集由五个部分构成&#xff1a;JPEGImages&#xff0c;Annotations&#xff0c;ImageSets&#xff0c;SegmentationClass以及SegmentationObject. . └── VOC #根目…

基于微信小程序+SpringBoot+Vue的微信平台签到系统(带1w+文档)

基于微信小程序SpringBootVue的微信平台签到系统(带1w文档) 基于微信小程序SpringBootVue的微信平台签到系统(带1w文档) 微信平台签到系统使用Java语言进行编码&#xff0c;使用Mysql创建数据表保存本系统产生的数据。系统可以提供信息显示和相应服务&#xff0c;其管理微信平台…

使用Diffusion Models进行街景视频生成

Diffusion Models专栏文章汇总&#xff1a;入门与实战 前言&#xff1a;街景图生成相当有挑战性&#xff0c;目前的文本到视频的方法仅限于生成有限范围的场景的短视频&#xff0c;文本到3D的方法可以生成单独的对象但不是整个城市。除此之外街景图对一致性的要求相当高&#x…

IDEA新建module后变为普通文件夹

问题描述&#xff1a; 在父项目中创建module并构建子父关系&#xff0c;但在创建module并配置后出现未生效问题 在父项目中的pom.xml文件中添加 <modules><module>***</module></modules>在新建Module中添加 <parent><groupId>com.***&l…

UFO:革新Windows操作系统交互的UI聚焦代理

人工智能咨询培训老师叶梓 转载标明出处 人机交互的便捷性和效率直接影响着我们的工作和生活质量。尽管现代操作系统如Windows提供了丰富的图形用户界面&#xff08;GUI&#xff09;&#xff0c;使得用户能够通过视觉和简单的点击操作来控制计算机&#xff0c;但随着应用程序功…