惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
U
Unit 42
大猫的无限游戏
大猫的无限游戏
H
Help Net Security
G
Google Developers Blog
Recent Announcements
Recent Announcements
B
Blog RSS Feed
罗磊的独立博客
博客园 - Franky
J
Java Code Geeks
S
SegmentFault 最新的问题
D
DataBreaches.Net
C
Check Point Blog
Blog — PlanetScale
Blog — PlanetScale
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
腾讯CDC
博客园_首页
美团技术团队
V
Visual Studio Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
The Cloudflare Blog
aimingoo的专栏
aimingoo的专栏

又见苍岚

COLMAP PatchMatch Stereo 算法详解 事件驱动的状态机框架:从理论到工程实践 Git 在国内网络环境下无法 Push 的排查与修复 —— 配置 Clash 代理 分段五次多项式插值原理详解 路径插值方法深度对比研究 Claude Code 使用指南 OpenClaw 记忆管理与技能创建指南 CBS(Conflict-Based Search)算法详解 A* 算法及其变种详解 OpenClaw 配置多 Agents Windows Powershell 无法加载文件,因为在此系统上禁止运行脚本问题的解决方案 MaxClaw 安装流程 大模型 AI 名词介绍 AList 网盘聚合工具简介 Protobuf 简介与测试 Claude Code 简介以及 GLM 4.7 模型接入 Github 歌词下载工具 163MusicLyrics Python __getattr__ 懒加载 Python TypedDict 机器人仿真平台 Gazebo 安装记录 机器人仿真平台 Gazebo 简介 多机器人路径规划问题(Multi-Agent Path Finding, MAPF)简介 Python exifread 读取修改过的 jpeg 信息错误问题修复 3D 坐标系变换的理解 3D 旋转矩阵基本概念 MongoDB Compass 介绍 Python 环境管理工具 uv Flutter 开发指南 Snipaste 安装下载与黑屏问题解决方案 全局路径规划算法记录
OpenCV 调用onnx模型
Yiwei Zhang · 2024-06-26 · via 又见苍岚

OpenCV是一个基于BSD许可发行的跨平台计算机视觉和机器学习软件库(开源),可以运行在Linux、Windows、Android和Mac OS操作系统上。可以将pytorch中训练好的模型使用ONNX导出,再使用opencv中的dnn模块直接进行加载使用。

cv2.dnn 是 OpenCV 库中的一个模块,专门用于深度学习计算。这个模块提供了一套用于执行深度学习模型的基础操作,比如卷积、池化、归一化、激活函数和各种前向传播等。使用 cv2.dnn,可以加载预训练的深度学习模型,如卷积神经网络(CNN),进行图像分类、目标检测、图像分割等任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <string>
#include <vector>
#include<opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace std;
void readImagesInFolder(const std::string& folderPath, std::vector<cv::Mat>& images)
{
cv::String path(folderPath + "/*.jpg"); // 这里假设你的图片格式是.jpg,如果是其他格式请相应修改
std::vector<cv::String> fileNames;
cv::glob(path, fileNames, true); // 通过glob函数获取文件夹内所有符合格式的文件名
for (const auto& fileName : fileNames)
{ // 使用imread函数读取图片
cv::Mat bgrImage = cv::imread(fileName, cv::IMREAD_COLOR);
// 图片格式转化bgr-->rgb
if (!bgrImage.empty())
{
cv::Mat rgbImage;
cv::cvtColor(bgrImage, rgbImage, cv::COLOR_BGR2RGB);
images.push_back(rgbImage);
}
}
}

cv::Mat transformation(const cv::Mat& image, const cv::Size & targetSize, const cv::Scalar& mean, const cv::Scalar& std) {

cv::Mat resizedImage;
//图片尺寸缩放
cv::resize(image, resizedImage, targetSize, 0, 0, cv::INTER_AREA);
cv::Mat normalized;
resizedImage.convertTo(normalized, CV_32F);
cv::subtract(normalized / 255.0, mean, normalized);
cv::divide(normalized, std, normalized);
return normalized;
}
cv::dnn::Net loadModel(const string& onnx_path) {
cv::dnn::Net net = cv::dnn::readNetFromONNX(onnx_path);
return net;
}
int main()
{ // 图片存放文件路径
string folderPath = "D:/C++_demo/opencv_onnx_gpu/CAMO/c";
std::vector<cv::Mat> rgbImages;
readImagesInFolder(folderPath, rgbImages);

// string image_path = "./animal-1.jpg";
// 加载ONNX模型
string onnx_path = "D:/C++_demo/opencv_onnx_gpu/PFNet.onnx";
cv::dnn::Net net = loadModel(onnx_path);
// 设置CUDA为后端
net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
cv::Mat output_prob;
std::vector<cv::Mat> output_probs;
std::vector<cv::String> output_layer_names = net.getUnconnectedOutLayersNames();

// 定义目标图像大小
cv::Size targetSize(416, 416);
// 定义每个通道的归一化参数
cv::Scalar mean(0.485, 0.456, 0.406); // 均值
cv::Scalar std(0.229, 0.224, 0.225); // 标准差

// 开始计时
auto start = chrono::high_resolution_clock::now();
for (const auto& rgbImage : rgbImages) {
// 获取图像的大小
cv::Size originalSize(rgbImage.cols, rgbImage.rows);
//cv::imshow("输入窗口", rgbImage);
//cv::waitKey(0);
//cv::destroyAllWindows();
// 图片归一化
cv::Mat normalized = transformation(rgbImage, targetSize, mean, std);
std::cout << normalized.size() << std::endl;
cv::Mat blob = cv::dnn::blobFromImage(normalized);
// 将Blob设置为模型的输入
net.setInput(blob);
// 运行前向传播
net.forward(output_probs, output_layer_names);
// 获取最完整的预测
cv::Mat prediction = output_probs[3];
// 预测图变mask
cv::Mat mask;
cv::resize(prediction.reshape(1, 416) * 255.0, mask, originalSize, 0, 0, cv::INTER_AREA);
}
auto end = std::chrono::high_resolution_clock::now();
// 计算耗时
std::chrono::duration<double> elapsed = end - start;
double elapsedTime = elapsed.count();
// 打印耗时
std::cout << "Elapsed time: " << elapsedTime << " seconds" << std::endl;
return 0;
}