AI分割一切模型SAM(Segment Anything Model)的C++部署

2023年最火爆的分割模型莫过于SAM,截止今天2024年1月19日,github上的star已经达到了41.7k的惊人数量。下面我们来体会一下如何运行这个模型,以及如何用C++部署这个模型。

检查cuda环境

我的Cuda版本是12.0.1,如下,

Cudnn是在官网下载的版本,

cudnn-windows-x86_64-8.9.2.26_cuda12-archive.zip

如果没有cuda也没关系,测试嘛,运行cpu版本就行。有cuda后面要注意版本问题。

下载SAM

SAM的官网地址是:https://github.com/facebookresearch/segment-anything

(base) D:\aiSeg> git clone --recursive https://github.com/facebookresearch/segment-anything

(base) D:\aiSeg>cd segment-anything;

(base) D:\aiSeg\segment-anything>

配置anaconda环境

(base) D:\aiSeg\segment-anything> conda ctreate -n seg

(base) D:\aiSeg\segment-anything> conda activate seg

(seg) D:\aiSeg\segment-anything>

然后,按照pytorch上的说明安装,详情可以参考:

PyTorch

(seg) D:\aiSeg\segment-anything> conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia

这里选pytorch-cuda=12.1,反正后面也没碰到啥问题,就酱。

再然后安装cudatools,默认安装了11.8,

(seg) D:\aiSeg\segment-anything> conda install cudatoolkit

The following NEW packages will be INSTALLED:

  cudatoolkit        pkgs/main/win-64::cudatoolkit-11.8.0-hd77b12b_0

再安装segment-anything,

(seg) D:\aiSeg\segment-anything>pip install -e .

Obtaining file:///D:/aiSeg/segment-anything

  Preparing metadata (setup.py) ... done

Installing collected packages: segment-anything

  Running setup.py develop for segment-anything

Successfully installed segment-anything-1.0

还有OpenCV等等等等要安装。。。。

(seg) D:\aiSeg\segment-anything>conda install opencv

The following NEW packages will be INSTALLED:

  opencv             pkgs/main/win-64::opencv-4.6.0-py311h5d08a89_5

(seg) D:\aiSeg\segment-anything>

测试SAM

安装完毕后,用vscode直接打开segment-anything文件夹,选择要测试运行的amg.py文件,

然后配置launch.json中的参数,内容如下,

{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387"version": "0.2.0","configurations": [{"name": "Python: Current File","type": "python","request": "launch","program": "${file}","console": "integratedTerminal","justMyCode": false,"args": ["--input=D:/aiImages/SoderbergLenna/Lenna.png","--output=D:/aiImages/SoderbergLenna/","--model-type=“vit_b","--checkpoint=D:/aiDataset/sam/sam_vit_b_01ec64.pth"]}]
}

这时候,就可以点击Starting Debug(F5)直接开跑了,一路顺利的话会得到下面的结果,

原图,

生成的mask,

导出ONNX文件

然后我们导出onnx文件,这一步是为后面的c++部署做准备的。

python scripts/export_onnx_model.py --checkpoint D:/aiDataset/sam/sam_vit_h_4b8939.pth --model-type vit_h --output sam_vit_h_4b8939.onnx

这样,我们就生成了sam_vit_h_4b8939.onnx文件。

下载cpp部署

项目地址在:https://github.com/dinglufe/segment-anything-cpp-wrapper

老办法,

> git clone --recursive https://github.com/dinglufe/segment-anything-cpp-wrapper

然后发现作者用的onnxruntime,因此我们也安装一下,

> conda install onnx

> conda install onnxruntime

另外,还要到 https://github.com/microsoft/onnxruntime

去下载windows上的动态库,我这里的本机地址是,

D:\aiEngine\onnxruntime-win-x64-gpu-1.16.2

生成所需要的辅助文件

项目中有一个export_pre_model.py文件,我略改了一下,因为我没有用hq-sam,直接用的segment-anything,改后内容如下,

# Code formatter may move "import segment_anything as SAM" and "import mobile_sam as SAM" to the top
# But this may bring errors after switching models
import torch
import numpy as np
import osfrom segment_anything.utils.transforms import ResizeLongestSidefrom onnxruntime.quantization import QuantType
from onnxruntime.quantization.quantize import quantize_dynamicoutput_names = ['output']# Generate preprocessing model of Segment-anything in onnx format
# Use original segment-anything, Mobile-SAM or HQ-SAM model
# Each in a separate Python virtual environment# Uncomment the following lines to generate preprocessing model of Segment-anything
import segment_anything as SAM
# # Download Segment-anything model "sam_vit_h_4b8939.pth" from https://github.com/facebookresearch/segment-anything#model-checkpoints
# # and change the path below
checkpoint = 'sam_vit_h_4b8939.pth'
model_type = 'vit_h'
output_path = 'models/sam_preprocess.onnx'
quantize = True# Target image size is 1024x720
image_size = (1024, 720)output_raw_path = output_path
if quantize:# The raw directory can be deleted after the quantization is doneoutput_name = os.path.basename(output_path).split('.')[0]output_raw_path = '{}/{}_raw/{}.onnx'.format(os.path.dirname(output_path), output_name, output_name)
os.makedirs(os.path.dirname(output_raw_path), exist_ok=True)sam = SAM.sam_model_registry[model_type](checkpoint=checkpoint)
sam.to(device='cpu')
transform = ResizeLongestSide(sam.image_encoder.img_size)image = np.zeros((image_size[1], image_size[0], 3), dtype=np.uint8)
input_image = transform.apply_image(image)
input_image_torch = torch.as_tensor(input_image, device='cpu')
input_image_torch = input_image_torch.permute(2, 0, 1).contiguous()[None, :, :, :]class Model(torch.nn.Module):def __init__(self, image_size, checkpoint, model_type):super().__init__()self.sam = SAM.sam_model_registry[model_type](checkpoint=checkpoint)self.sam.to(device='cpu')self.predictor = SAM.SamPredictor(self.sam)self.image_size = image_sizedef forward(self, x):self.predictor.set_torch_image(x, (self.image_size))if 'interm_embeddings' not in output_names:return self.predictor.get_image_embedding()else:return self.predictor.get_image_embedding(), torch.stack(self.predictor.interm_features, dim=0)model = Model(image_size, checkpoint, model_type)
model_trace = torch.jit.trace(model, input_image_torch)
torch.onnx.export(model_trace, input_image_torch, output_raw_path,input_names=['input'], output_names=output_names)if quantize:quantize_dynamic(model_input=output_raw_path,model_output=output_path,per_channel=False,reduce_range=False,weight_type=QuantType.QUInt8,)

生成的这一堆文件如下,

然后cmake生成项目,就可以把项目跑起来了,最后的视频效果如下所示。

segment-anything-cpp-wrapper

注意事项

  1. 注意配置路径,让项目能找到相应的dll文件。
  2. 注意如果要使用HQ-sam,要另外再建一个conda的环境,不然生成onnx文件时会有冲突报错。

本文结束。

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

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

相关文章

【江科大】STM32:中断系统(理论)

文章目录 中断系统为什么要使用中断中断优先级中断嵌套STM32的中断系统如何管理这些中断NVIC的结构![请添加图片描述](https://img-blog.csdnimg.cn/c77b038fd63a4ddfbcd3b86f6dfe596b.png) 优先级窗口看门狗(WWDG):外部中断模块的特性&#…

K8S搭建(centos)四、安装K8S

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

i18n多国语言Internationalization的动态实现

一、数据动态的更新 在上一篇i18n多国语言Internationalization的实现-CSDN博客,可能会遇到一个问题,我们在进行英文或中文切换时,并没有办法对当前的数据进行动态的更新。指的是什么意思呢?当前app.js当中一个组件内容&#xff…

ESP32-HTTP_webServer库(Arduino)

ESP32-HTTP 介绍 ESP32是一款功能强大的微控制器,具有丰富的网络和通信功能。其中之一就是支持HTTP协议,这使得ESP32可以用于创建Web服务器。 HTTP是什么? HTTP(Hyper Text Transfer Protocol),即超文本传…

STM32标准库开发——串口发送/单字节接收

USART基本结构 串口发送信息 启动串口一的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);初始化对应串口一的时钟,引脚,将TX引脚设置为复用推挽输出。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_In…

leetcode—图 岛屿数量

岛屿数量 给你一个由 1(陆地)和 0(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网…

鸿蒙开发(五)鸿蒙UI开发概览

从用户角度来讲,一个软件拥有好看的UI,那是锦上添花的事情。再精确的算法,再厉害的策略,最终都得通过UI展现给用户并且跟用户交互。那么,本篇一起学习下鸿蒙开发UI基础知识,认识下各种基本控件以及使用方式…

【设计模式】美团三面:你连装饰器都举不出例子?

什么是装饰器模式? 装饰器模式,这个设计模式其实和它的名字一样,非常容易理解。 想象一下,每天出门的时候,我们都会思考今天穿什么。睡**衣、睡裤加拖鞋,还是西装、领带加皮鞋?又或者说是&…

Mysql数据库DQL查询语言之表连接(联合查询)

表连接 关系字段:两表中有关联关系的字段 \关系字段:两表之间存在关系的字段 什么是表连接? 当我们的查询结果需要从多张表中获取时,此时应该让表之间建立连接,同时获取数据 内连接 特点:同时对连接双方做…

性能优化-HVX 指令介绍

「发表于知乎专栏《移动端算法优化》」 本文主要介绍了 HVX 指令相关的知识,包括 HVX 寄存器相关内容,指令的背景依赖,部分常用 intrinsic HVX 指令。具体指令的详细内容及使用还需阅读 HVX 的指令文档,以及细致的实践操作。 &…

(十二)Head first design patterns代理模式(c++)

代理模式 代理模式:创建一个proxy对象,并为这个对象提供替身或者占位符以对这个对象进行控制。 典型例子:智能指针... 例子:比如说有一个talk接口,所有的people需要实现talk接口。但有些人有唱歌技能。不能在talk接…

Flink中的容错机制

一.容错机制 在Flink中,有一套完整的容错机制来保证故障后的恢复,其中最重要的就是检查点。 1.1 检查点(Checkpoint) 在流处理中,我们可以用存档读档的思路,将之前某个时间点的所有状态保存下来&#xf…

JAVA 学习 面试(六)数据类型与方法

数据类型 基本数据类型 为什么float3.4报错 3.4 默认是浮点double类型的,如果赋值给float是向下转型,会出现精度缺失,,需要强制转换 Switch支持的数据类型? byte、short、int、char 、 enum 、 String 基本类型与包…

使用 Swift 代码优化项目编译速度

引言 软件的性能是评价一个软件质量的重要指标,尤其在今天这个时代,性能已成为大型项目不可或缺的考虑因素之一。对于用户量极大的软件,如网银系统、在线购物商城等,更是必须保证其高效稳定的性能。在这种背景下,优化…

Python-基础篇-类与对象/面向对象程序设计-py脚本

面向对象基础 第一个面向对象 class Cat:def eat(self):print("小猫爱吃鱼")def drink(self):print("小猫要喝水")# 创建猫对象 tom Cat()tom.eat() tom.drink()print(tom)addr id(tom) print("%x" % addr)新建两个猫对象 class Cat:def ea…

Dockerfile-xxxx

1、Dockerfile-server FROM openjdk:8-jdk-alpine WORKDIR /app COPY . . CMD java -Xms1536M -Xmx1536M -XX:UseG1GC -jar -Dlog4j2.formatMsgNoLookupstrue -Dloader.pathresources,lib -Duser.timezoneGMT-05 /app/server-main-1.0.0.jar 2、Dockerfile-bgd #FROM openjdk…

MySQL-SQL-DQL

DQL-介绍 DQL-语法 基本查询 1、查询多个字段 2、设置别名 3、去除重复记录 条件查询 1、语法 2、条件 聚合函数 1、介绍 2、常见的聚合函数 3、语法 分组查询 1、语法 2、where与having区别 排序查询 1、语法 2、排序方式 分页查询 1、语法 DQL-执行顺序

【代码随想录】刷题笔记Day54

前言 差单调栈就结束代码随想录一刷啦,回家二刷打算改用python补充进博客,小涛加油!!! 647. 回文子串 - 力扣(LeetCode) 双指针法 中心点外扩,注意中心点可能有一个元素可能有两个…

MacOS受欢迎的数据库开发工具 Navicat Premium 15 中文版

Navicat Premium 15 Mac是一款数据库管理工具,提供了一个全面的解决方案,用于连接、管理和维护各种数据库系统。以下是Navicat Premium 15 Mac的一些主要功能和特点: 软件下载:Navicat Premium 15 中文版下载 多平台支持&#xff…

PLC从HTTP服务端获取JSON文件,解析数据到寄存器

智能网关IGT-DSER集成了多种PLC协议,方便实现各种PLC与HTTP服务端之间通讯。通过网关的参数配置软件绑定JSON文件的字段与PLC寄存器地址,配置URL,即可采用POST命令,将JSON文件提交给HTTP的服务端; 服务端有返回的JSON&…