OpenCV与AI深度学习 | 实战 | 基于YOLOv9+SAM实现动态目标检测和分割(步骤 + 代码)

本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。

原文链接:实战 | 基于YOLOv9+SAM实现动态目标检测和分割(步骤 + 代码)

0 导  读

    本文主要介绍基于YOLOv9+SAM实现动态目标检测和分割,并给出详细步骤和代码。

1 背景介绍

    在本文中,我们使用YOLOv9+SAM在RF100 Construction-Safety-2 数据集上实现自定义对象检测模型。

    这种集成不仅提高了在不同图像中检测和分割对象的准确性和粒度,而且还扩大了应用范围——从增强自动驾驶系统到改进医学成像中的诊断过程。

    通过利用 YOLOv9 的高效检测功能和 SAM 以零样本方式分割对象的能力,这种强大的组合最大限度地减少了对大量再训练或数据注释的需求,使其成为一种多功能且可扩展的解决方案。

2 YOLOv9简介

2.1 YOLOv9简介(You Only Look Once)

YOLOv9性能图示

YOLOv9模型图

    YOLOv9 在实时目标检测方面取得了重大进步,结合了可编程梯度信息 (PGI) 和通用高效层聚合网络 (GELAN),以提高效率、准确性和适应性,其在 MS COCO 数据集上的性能证明了这一点。

    利用开源社区的协作工作并在 Ultralytics YOLOv5 的基础上构建,YOLOv9 通过信息瓶颈原理和可逆函数解决深度学习中信息丢失的挑战,跨层保留基本数据。

    这些创新策略提高了模型的结构效率,并确保精确的检测能力,而不会影响细节,即使在轻量级模型中也是如此。

    YOLOv9 的架构减少了不必要的参数和计算需求,使其能够在各种模型大小(从紧凑的 YOLOv9-S 到更广泛的 YOLOv9-E)上实现最佳性能,展示了速度和检测精度之间的和谐平衡。

    作为计算机视觉领域的里程碑,YOLOv9不仅建立了新的基准,而且拓宽了人工智能在目标检测和分割方面的应用视野,凸显了该领域战略创新和协作努力的影响。

3 SAM简介

3.1 SAM简介(Segment-Anything-Model)

SAM模型图

    分割一切模型 (SAM) 通过简化图像分割来推动计算机视觉向前发展,这对于从科学研究到创造性工作的一系列用途至关重要。

    SAM 利用迄今为止最大的 Segment Anything 1-Billion (SA-1B) 掩模数据集,通过减少对专业知识、强大的计算能力和广泛的数据集标注的依赖来实现分割的民主化。

    在 Apache 2.0 许可证下,SAM 引入了一个基础模型框架,允许通过简单的提示轻松调整任务,反映自然语言处理中的进步。

    通过对超过 10 亿个不同掩模的训练,SAM 理解了物体的广义概念,促进了跨陌生领域的零镜头传输,并增强了其在 AR/VR、创意艺术和科学研究等各个领域的实用性。

    该模型的提示驱动灵活性和广泛的任务适应性标志着分割技术的重大飞跃,将 SAM 定位为研究社区和应用程序开发人员的多功能且易于访问的工具。

关于数据集

    该项目利用Roboflow 的RF100施工数据集,特别是Construction-Safety-2子集,来演示集成模型的功能。

https://blog.roboflow.com/roboflow-100/

    RF100 是由英特尔发起的一项计划,旨在建立对象检测模型的开源基准。它侧重于 Roboflow Universe 上可用数据集的通用性,提高可访问性并加快人工智能和深度学习的开发过程。

    RF100 构建数据集与 Roboflow 中的其他项目一样,是开源的,可以免费使用。      

5 实现步骤

5.1 实现步骤目录

  • 环境设置
  • 下载 YOLOv9 和 SAM 的预训练模型权重
  • 图像推理
  • 可视化和分析
  • 获取检测结果
  • 使用 SAM 进行分割

5.2 环境设置

    需要有 Google 帐户才能访问 Google Colab,这是一项免费云服务,为深度学习任务提供必要的计算资源,包括访问高达 16 GB 的 GPU 和 TPU。

    GPU状态检查

    首先,我们确保 GPU 的可用性和就绪性,用于处理和运行 YOLOv9+SAM 模型。

5.3 安装 Google 云盘

    接下来,如果您已经下载了数据集,我们需要导航到存储数据集的文件夹,否则我们可以直接使用 Roboflow 加载数据集。

from google.colab import drive
drive.mount('/content/drive')

or

%cd {HOME}/
!pip install -q roboflow

from roboflow import Roboflow
rf = Roboflow(api_key="YOUR API KEY")
project = rf.workspace("roboflow-100").project("construction-safety-gsnvb")
dataset = project.version(2).download("yolov7")

5.4 配置 YOLOv9

    数据集准备好后,克隆 YOLOv9 存储库,然后切换到 YOLOv9 目录并安装所需的依赖项,为对象检测和分割任务做好准备。

!git clone https://github.com/SkalskiP/yolov9.git
%cd yolov9
!pip3 install -r requirements.txt -q

5.5 显示当前目录

    将当前工作目录的路径存储在HOME变量中以供参考。

import os
HOME = os.getcwd()
print(HOME)

5.6 下载权重模型

    让我们为模型权重创建一个目录,并从 GitHub 上的发布页面下载特定的 YOLOv9 和 GELAN 模型权重,这对于使用预训练参数初始化模型至关重要。

!mkdir -p {HOME}/weights
!wget -P {HOME}/weights -q https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-c.pt
!wget -P {HOME}/weights -q https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-e.pt
!wget -P {HOME}/weights -q https://github.com/WongKinYiu/yolov9/releases/download/v0.1/gelan-c.pt
!wget -P {HOME}/weights -q https://github.com/WongKinYiu/yolov9/releases/download/v0.1/gelan-e.pt

5.7 下载图像进行推理

    为了使用 YOLOv9 权重进行推理,我们必须设置一个数据目录并下载一个示例图像进行处理,并在变量中设置该图像的路径SOURCE_IMAGE_PATH。

!mkdir -p {HOME}/data
!wget -P {HOME}/data -q /content/drive/MyDrive/data/image9.jpeg
SOURCE_IMAGE_PATH = f"{HOME}/image9.jpeg"

5.8 使用自定义数据运行检测

    之后,执行detect.py指定参数对图像进行目标检测,设置置信度阈值并保存检测结果。这将创建一个包含 class_ids、边界框坐标和置信度分数的文本文件,我们稍后将使用它。

!python detect.py --weights {HOME}/weights/gelan-c.pt --conf 0.1 --source /content/drive/MyDrive/data/image9.jpeg --device 0 --save-txt --save-conf

5.9 显示检测结果

    然后,我们利用 IPython 的显示和图像功能来展示指定路径图像中检测到的对象,并进行调整以获得最佳观看效果。

5.10 安装 Ultralytics

    安装 Ultralytics 包以访问 YOLO 对象检测模型实现和实用程序,不要忘记导入 YOLO 类以执行对象检测任务。

!pip install ultralytics 
from ultralytics import YOLO

5.11 安装Segment-Anything模型

    现在让我们安装 Segment-Anything 库并下载 SAM 模型的权重文件,为高质量图像分割任务做好准备。

!pip install 'git+https://github.com/facebookresearch/segment-anything.git'

!wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth

5.12 提取检测结果和置信度分数

    我们需要将 YOLOv9 检测结果保存在上面的文本文件中来提取类 ID、置信度分数和边界框坐标。这里的坐标已经标准化,所以我们先将它们转换为图像比例,然后打印它们进行验证。

import cv2

# Specify the path to your image
image_path = '/content/drive/MyDrive/data/image9.jpeg'

# Read the image to get its dimensions
image = cv2.imread(image_path)
image_height, image_width, _ = image.shape

detections_path = '/content/yolov9/runs/detect/exp/labels/image9.txt'

bboxes = []
class_ids = []
conf_scores = []

with open(detections_path, 'r') as file:
    for line in file:
        components = line.split()
        class_id = int(components[0])
        confidence = float(components[5])
        cx, cy, w, h = [float(x) for x in components[1:5]]

        # Convert from normalized [0, 1] to image scale
        cx *= image_width
        cy *= image_height
        w *= image_width
        h *= image_height

        # Convert the center x, y, width, and height to xmin, ymin, xmax, ymax
        xmin = cx - w / 2
        ymin = cy - h / 2
        xmax = cx + w / 2
        ymax = cy + h / 2

        class_ids.append(class_id)
        bboxes.append((xmin, ymin, xmax, ymax))
        conf_scores.append(confidence)

# Display the results
for class_id, bbox, conf in zip(class_ids, bboxes, conf_scores):
    print(f'Class ID: {class_id}, Confidence: {conf:.2f}, BBox coordinates: {bbox}')

5.13 初始化 SAM 以进行图像分割

    使用指定的预训练权重初始化 SAM 后,我们继续从 SAM 模型注册表中选择模型类型以生成分段掩码。

from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor
sam_checkpoint = "/content/yolov9/sam_vit_h_4b8939.pth"
model_type = "vit_h"
sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
predictor = SamPredictor(sam)

5.14 加载图像进行分割

    通过 OpenCV 库,我们加载图像以使用 SAM 进行处理,为分割做好准备。

import cv2
image = cv2.cvtColor(cv2.imread('/content/drive/MyDrive/data/image9.jpeg'), cv2.COLOR_BGR2RGB)
predictor.set_image(image)

5.15 结果可视化​​​​​​​

    为了可视化检测和分割结果,我们必须使用 SAM 将边界框转换为分割掩模。我们随机为类 ID 分配唯一的颜色,然后定义用于显示掩码、置信度分数和边界框的辅助函数。coco.yaml 文件用于将 class_ids 映射到类名。

import matplotlib.patches as patches
from matplotlib import pyplot as plt
import numpy as np
import yaml

with open('/content/yolov9/data/coco.yaml', 'r') as file:
    coco_data = yaml.safe_load(file)
    class_names = coco_data['names']

for class_id, bbox, conf in zip(class_ids, bboxes, conf_scores):
    class_name = class_names[class_id]
    # print(f'Class ID: {class_id}, Class Name: {class_name}, BBox coordinates: {bbox}')

color_map = {}
for class_id in class_ids:
    color_map[class_id] = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)

def show_mask(mask, ax, color):
    h, w = mask.shape[-2:]
    mask_image = mask.reshape(h, w, 1) * np.array(color).reshape(1, 1, -1)
    ax.imshow(mask_image)

def show_box(box, label, conf_score, color, ax):
    x0, y0 = box[0], box[1]
    w, h = box[2] - box[0], box[3] - box[1]
    rect = plt.Rectangle((x0, y0), w, h, edgecolor=color, facecolor='none', lw=2)
    ax.add_patch(rect)

    label_offset = 10

    # Construct the label with the class name and confidence score
    label_text = f'{label} {conf_score:.2f}'

    ax.text(x0, y0 - label_offset, label_text, color='black', fontsize=10, va='top', ha='left',
            bbox=dict(facecolor=color, alpha=0.7, edgecolor='none', boxstyle='square,pad=0.4'))

plt.figure(figsize=(10, 10))
ax = plt.gca()
plt.imshow(image)

# Display and process each bounding box with the corresponding mask
for class_id, bbox in zip(class_ids, bboxes):
    class_name = class_names[class_id]
    # print(f'Class ID: {class_id}, Class Name: {class_name}, BBox coordinates: {bbox}')

    color = color_map[class_id]
    input_box = np.array(bbox)

    # Generate the mask for the current bounding box
    masks, _, _ = predictor.predict(
        point_coords=None,
        point_labels=None,
        box=input_box,
        multimask_output=False,
    )

    show_mask(masks[0], ax, color=color)
    show_box(bbox, class_name, conf, color, ax)

# Show the final plot
plt.axis('off')
plt.show()

5.16 提取掩码

    最后,我们生成一个合成图像,在白色背景下突出显示检测到的对象,从分割蒙版创建聚合蒙版,并将其应用到将原始图像与白色背景混合以增强可视化

aggregate_mask = np.zeros(image.shape[:2], dtype=np.uint8)

# Generate and accumulate masks for all bounding boxes
for bbox in bboxes:
    input_box = np.array(bbox).reshape(1, 4)
    masks, _, _ = predictor.predict(
        point_coords=None,
        point_labels=None,
        box=input_box,
        multimask_output=False,
    )
    aggregate_mask = np.where(masks[0] > 0.5, 1, aggregate_mask)

# Convert the aggregate segmentation mask to a binary mask
binary_mask = np.where(aggregate_mask == 1, 1, 0)

# Create a white background with the same size as the image
white_background = np.ones_like(image) * 255

# Apply the binary mask to the original image
# Where the binary mask is 0 (background), use white_background; otherwise, use the original image
new_image = white_background * (1 - binary_mask[..., np.newaxis]) + image * binary_mask[..., np.newaxis]

# Display the new image with the detections and white background
plt.figure(figsize=(10, 10))
plt.imshow(new_image.astype(np.uint8))
plt.axis('off')
plt.show()

​​​​​​​​​​​​​​

THE END!

文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

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

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

相关文章

微信小程序展示倒计时

html <view class"countdown"> <text>倒计时&#xff1a;</text> <text wx:for"{{countdown}}" wx:key"index">{{item}}</text> </view> ts data: {countdown: [], // 存放倒计时数组 targetTime:…

【个人博客搭建】(8)全局异常处理

1、net 8 webapi 全局异常处理: 在 .NET 8 WebAPI 中&#xff0c;全局异常处理可以通过实现**IExceptionHandler接口或使用IAsyncExceptionFilter接口来完成**。 首先&#xff0c;关于IExceptionHandler接口&#xff0c;它是ASP.NET Core中用于全局异常处理的新抽象。这个接口有…

从小到大输出四个整数(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int a, b, c, d;int t 0;//提示用户&#xff1b;printf("请输入四个整数a b c d&…

C语言趣味代码(一)

C语言相关知识点的博客和大家分享完了&#xff0c;接下来我想开始数据结构相关的博客&#xff0c;在此之前呢&#xff0c;有的小伙伴问过我学完C语言的相关知识&#xff0c;我能干些什么呢&#xff1f;只有刷题吗&#xff1f;这不禁让我反思&#xff1a;在我们学习的过程中&…

【RSGIS数据资源】2001-2022年中国玉米种植分布数据集

文章目录 数据介绍精彩截图2001&#xff5e;2020年中国玉米种植频率分布2001年至2020年研究区域融合数据的平均填充百分比。 数据介绍 2001-2022年中国玉米种植分布数据集&#xff08;CCD-Maize&#xff09;&#xff0c;涵盖中国22个省、市的玉米种植分布图&#xff0c;文件格…

一文搞定 EventLoop、宏任务、微任务

面试官&#xff1a;你了解JavaScript事件循环吗&#xff0c;掌握多少&#xff0c;把你知道的都说一下。 今天我们就来说一下&#xff0c;JavaScript作为一门单线程语言&#xff0c;如何通过事件循环&#xff08;Event Loop&#xff09;和任务队列&#xff08;Task Queue&#…

CTFHUB-技能树-Web前置技能-文件上传(无验证,JS前端验证,前端验证)

CTFHUB-技能树-Web前置技能-文件上传&#xff08;无验证&#xff0c;JS前端验证&#xff0c;前端验证—.htaccess&#xff09; 文章目录 CTFHUB-技能树-Web前置技能-文件上传&#xff08;无验证&#xff0c;JS前端验证&#xff0c;前端验证—.htaccess&#xff09;文件上传无验…

关联规则挖掘(二)

目录 三、FP-增长算法&#xff08;一&#xff09;算法的背景&#xff08;二&#xff09;构造FP-树&#xff08;三&#xff09;生成频繁项集 四、关联规则的评价&#xff08;一&#xff09;支持度和置信度的不足&#xff08;二&#xff09;相关性分析 三、FP-增长算法 &#xf…

C++内存管理——new/delete、operator new/operator delete

内存管理 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd";int* ptr1 (int*)malloc(sizeof(int) * 4);int* pt…

tcp三次握手和四次断开以及tcpdump的基本使用

前言 最近工作中会发现有超时的问题&#xff0c;还有就是在面试的时候很多都要求深入理解TCP/IP协议。突然感觉TCP/IP协议是一个既熟悉&#xff0c;又陌生的技术。又想到上大学的时候&#xff0c;老师说过 网络的圣经&#xff1a;“TCP/IP详解” 卷一 卷二 卷三&#xff0c;三…

IIC总线读取温度湿度传感器数据实验

iic.c #include "iic.h"extern void printf(const char* fmt, ...); /** 函数名 &#xff1a; delay_us* 函数功能&#xff1a;延时函数* 函数参数&#xff1a;无* 函数返回值&#xff1a;无* */ void delay_us(void) //微秒级延时 {unsigned int i 2000;while(i-…

性能工具之emqtt-bench BenchMark 测试示例

文章目录 一、前言二、典型压测场景三、机器准备四、典型压测场景1、并发连接2、消息吞吐量测试2.1 1 对 1&#xff08;示例&#xff09;2.2 多对1&#xff08;示例&#xff09;2.3 1对多&#xff08;示例&#xff09; 五、遇到的问题client(): EXIT for {shutdown,eaddrnotava…

java学习之路-多态

文章目录 目录 文章目录 前言 1.多态 1.1 多态的概念 1.2 多态实现条件&#xff08;重点&#xff09; 多态实现的栗子 1.3重写 重写的规则 重写和重载的区别 1.4静态和动态绑定 1.5向上转型和向下转型 1.向上转型 2.向下转型 1.6多态的优点 前言 本文内容&#xff1a;多…

DHCP是什么意思 路由器中DHCP服务器怎么设置?

概述 DHCP是什么意思&#xff1f;很多朋友在路由器设置中&#xff0c;都会看到有一项“DHCP服务器”设置功能&#xff0c;而很多朋友对这个功能不太了解&#xff0c;也不知道怎么设置。其实&#xff0c;对于普通用户来说&#xff0c;无需去单独设置路由器DHCP服务器功能&#…

李沐46_语义分割和数据集——自学笔记

语义分割 语义分割将图片中的每个像素分类到对应的类别。 实例分割&#xff08;目标检测的进化版本&#xff09; 如果有物体&#xff0c;会区别同一类的不同物体。 语义分割重要数据集&#xff1a;Pascal VOC2012 %matplotlib inline import os import torch import torch…

【强化学习的数学原理-赵世钰】课程笔记(九)策略梯度方法(Policy Gradient Method)

目录 一.policy gradient 的基本思路&#xff08;Basic idea of policy gradient&#xff09; 二.定义最优策略的 metrics&#xff0c;也就是 objective function 是什么 三.objective function 的 gradient 四.梯度上升算法&#xff08;REINFORCE&#xff09; 五.总结 上…

DevExpress WinForms中文教程 - 如何通过UI测试自动化增强应用可靠性?(二)

DevExpress WinForm拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜任…

数字工厂管理系统与MES系统有什么区别

随着工业4.0时代的到来&#xff0c;数字化转型已经成为制造企业发展的必然趋势。在这个过程中&#xff0c;数字工厂管理系统和MES管理系统都扮演者至关重要的角色。然而&#xff0c;尽管两者都致力于优化生产流程和提高生产效率&#xff0c;但它们在实际应用、功能定位和系统架…

Datapump数据迁移方案

环境准备 确认源数据库和目标数据库的版本 确保源数据库和目标数据库的Oracle版本兼容&#xff0c;以保证Datapump工具能够正常工作。 硬件资源检查 确认源数据库和目标数据库服务器的硬件资源&#xff08;如CPU、内存、存储空间&#xff09;能够满足数据迁移的需求。 网络连…

基于STM32的智能垃圾分类识别系统设计(论文)_kaic

摘 要 智能垃圾分类技术逐渐受到了政府的重视和支持&#xff0c;越来越多的城市开始推行垃圾分类政策。因此设计一款能够对垃圾进行识别并分类的控制系统具有一定的现实意义。本设计采用STM32单片机作为整个系统的控制核心&#xff0c;利用K210开发板作为图像识别控制系统&…