目录
写在前面
为何要写这个文档?因为我想跑通sam模型,并在本地用c++跑通,可是网上的教程写的都太简单,或者写的太隐晦,很多都有错,于是干脆自己从头到尾搞了一遍,希望帮助到大家!
【完整资源项目代码】直通下载地址:【图像分割领域】+【SegmentAnything模型】+【C++本地部署】资源-CSDN文库
项目来源
dinglufe/segment-anything-cpp-wrapper
原始文档翻译
本项目旨在为Segment Anything、MobileSAM、HQ-SAM 和 EdgeSAM 提供一个纯 C++ 推理 API,运行时不依赖于 Python。
代码库包含一个 C++ 库,并提供了一个测试程序,便于将接口集成到其他项目中。
模型加载大约需要 10 到 1 秒,单次推理大约需要 20ms,测试环境为 Intel Xeon W-2145 CPU(16 核心)。在运行时,接口大约消耗 6GB 或 1GB 内存(如果使用 CPU 运行),或 16GB 或 1GB 内存(如果使用 CUDA)。其中,“或”指的是对“Segment Anything”或“MobileSAM”的内存要求。
目前,该程序已在 Windows 上经过充分测试,可能在 Linux 上运行时会遇到问题(未提供预编译的 Linux 版本)。
测试程序 - sam_cpp_test
视频演示 链接;图片由 Brenda 提供,按键记录使用了 KeyCastOW。
使用方法
下载release压缩文件并解压,然后直接运行 sam_cpp_test
或在命令行中运行:
# 显示帮助信息
./sam_cpp_test -h
# 示例(更改设备,使用 CPU 进行预处理,CUDA 进行 SAM)
# 如果有多个 GPU,可以使用 CUDA:1、CUDA:2 等。
# 所有操作在 CPU 或全部在 CUDA 上进行也支持。
./sam_cpp_test -pre_device="cpu" -sam_device="cuda:0"
# 示例(默认选项)
./sam_cpp_test -pre_model="models/sam_preprocess.onnx" -sam_model="models/sam_vit_h_4b8939.onnx" -image="images/input.jpg"
# 示例(使用 MobileSAM)
./sam_cpp_test -pre_model="models/mobile_sam_preprocess.onnx" -sam_model="models/mobile_sam.onnx"
# 示例(使用 HQ-SAM)
./sam_cpp_test -pre_model="models/sam_hq_preprocess.onnx" -sam_model="models/sam_hq_vit_h.onnx"
# 示例(使用 EdgeSAM)
./sam_cpp_test -pre_model="models/edge_sam_3x_encoder.onnx" -sam_model="models/edge_sam_3x_decoder.onnx"
# 示例(更改图片)
./sam_cpp_test -image="images/input2.jpg"
C++ 库 - sam_cpp_lib
一个简单的示例:
Sam::Parameter param("sam_preprocess.onnx", "sam_vit_h_4b8939.onnx", std::thread::hardware_concurrency());
param.providers[0].deviceType = 0; // 预处理使用 CPU
param.providers[1].deviceType = 1; // SAM 使用 CUDA
Sam sam(param);
// 使用 MobileSAM
Sam::Parameter param("mobile_sam_preprocess.onnx", "mobile_sam.onnx", std::thread::hardware_concurrency());
// 使用 HQ-SAM
Sam::Parameter param("sam_hq_preprocess.onnx", "sam_hq_vit_h.onnx", std::thread::hardware_concurrency());
auto inputSize = sam.getInputSize();
cv::Mat image = cv::imread("input.jpg", -1);
cv::resize(image, image, inputSize);
sam.loadImage(image); // 使用 CPU 时大约需要 6GB 内存,使用 CUDA 时需要 16GB 内存
// 使用 SAM 和提示(输入:x, y)
cv::Mat mask = sam.getMask({200, 300});
cv::imwrite("output.png", mask);
// 使用 SAM 和多个提示(输入:points, nagativePoints)
cv::Mat mask = sam.getMask(points, nagativePoints); // 会占用大约 1GB 内存/显存
cv::imwrite("output-multi.png", mask);
// 使用 SAM 和框选提示(输入:points, nagativePoints, box)
// points 和 negativePoints 可以为空(使用 {} 作为参数)
cv::Rect box{444, 296, 171, 397};
cv::Mat mask = sam.getMask(points, nagativePoints, box);
cv::imwrite("output-box.png", mask);
// 自动生成掩膜(输入:每边点的数量)
// 如果使用 CPU,运行较慢,结果不如官方演示
cv::Mat maskAuto = sam.autoSegment({10, 10});
cv::imwrite("output-auto.png", maskAuto);
更多细节可以参考 test.cpp 和 sam.h 文件。
"sam_vit_h_4b8939.onnx" 和 "mobile_sam.onnx" 模型可以使用这里的 官方步骤 和