[Deep Learning] [Opencv] Python/C++ appelle le modèle onnx [Bases]

[Deep Learning] [Opencv] python/C++ appelle le modèle onnx [Bases]

Astuce : le blogueur a sélectionné de nombreux articles de blog de grands noms et les a personnellement testés pour vérifier leur efficacité. Il partage ses notes et invite tout le monde à les étudier et à en discuter ensemble.


Préface

OpenCV est une bibliothèque logicielle multiplateforme de vision par ordinateur et d'apprentissage automatique (open source) publiée sous licence BSD et peut fonctionner sur les systèmes d'exploitation Linux, Windows, Android et Mac OS. Le modèle formé dans pytorch peut être exporté à l'aide d'ONNX, puis directement chargé à l'aide du module dnn dans opencv.
Répertoire d'apprentissage de la série :
[CPU] Explication détaillée du modèle Pytorch vers le processus de modèle ONNX
[GPU] Explication détaillée du modèle Pytorch vers le processus de format ONNX
[Modèle ONNX] Déploiement rapide
[Modèle ONNX] Déploiement rapide multithread
[Modèle ONNX] Opencv appelle onnx


Version PythonOpenCV

Installer OpenCV sur la plateforme Windows

Le blogueur a installé l'environnement anaconda dans l'environnement win10 , puis a construit l'environnement openCV requis pour exécuter le modèle onnx.

# 搭建opencv环境
conda create -n opencv_onnx python=3.10 -y
# 激活环境
activate opencv_onnx
# 安装opencv
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

Voir la version opencv

import cv2
cv2.__version__

opencv appelle le modèle onnx

Désormais, le code met de côté toutes les dépendances liées à pytorch et à onnx, et utilise uniquement opencv pour terminer l'ensemble du processus d'inférence.

import cv2
import numpy as np

def normalizeImage(image,mean,std):
    normalized = image.astype(np.float32)
    normalized = normalized / 255.0 - mean
    normalized = normalized / std
    return normalized

def main():
    # 读取图片
    image = cv2.imread(r"./animal-1.jpg")
    # 将BGR图像转换为RGB格式
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    # 获取图像的大小
    ori_w, ori_h, = image.shape[0], image.shape[1]

    # 指定调整后的大小
    new_width = 416
    new_height = 416
    # 图片尺寸缩放
    resized_img = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA)

    # 定义每个通道的归一化参数
    mean = np.array([0.485, 0.456, 0.406]).astype(np.float32)  # 均值
    std = np.array([0.229, 0.224, 0.225]).astype(np.float32)  # 标准差
    # 图片归一化
    normalized = normalizeImage(resized_img, mean, std)

    # 加载ONNX模型
    net = cv2.dnn.readNetFromONNX("PFNet.onnx")  # 加载训练好的识别模型
    # onnx是多输出,每个输出都会对应一个name,因此需要获取所有输出的name
    output_layer_names = net.getUnconnectedOutLayersNames()
    blob = cv2.dnn.blobFromImage(normalized)  # 由图片加载数据 这里还可以进行缩放、归一化等预处理
    # 将Blob设置为模型的输入
    net.setInput(blob)
    # 运行前向传播,将所有输出name作为参数传递
    out = net.forward(output_layer_names)
    out = np.squeeze(out[3]) * 255.0
    output = cv2.resize(out, (ori_h, ori_w), interpolation=cv2.INTER_AREA)

    # 保存图像
    cv2.imwrite('saved_opencv_python_image.png', output)

if __name__ == '__main__':
    main()


Version C++OpenCV

Installer OpenCV sur la plateforme Windows

Téléchargez l'adresse du fichier d'installation sur le site officiel . Le blogueur utilise la version opencv-4.8.0-windows.exe et double-cliquez pour l'exécuter et le décompresser pour obtenir les fichiers suivants :
Open VS 2019 : Créer un nouveau projet --- ->Application console---->Projet de configuration ----> Chemin du projet et cochez "Placer la solution et le projet dans le même répertoire ----> Cliquez sur Créer.

Définissez le chemin OpenCV : Projet ----> Propriétés.

Ajouter Répertoire d'inclusion supplémentaire : Debug | x64 ---->C/C+±—>Général---->Répertoires d'inclusion supplémentaires.

D:\C++_demo\opencv\build\x64\vc16\bin
D:\C++_demo\opencv\build\bin
D:\C++_demo\opencv\build\include
D:\C++_demo\opencv\build\include\opencv2

Linker : Debug | x64---->Linker---->Général---->Répertoires d'inclusion supplémentaires.

D:\C++_demo\opencv\build\x64\vc16\lib

Linker : Debug | x64---->Linker---->Entrée---->Dépendances supplémentaires.

Recherchez les fichiers pour les dépendances supplémentaires sous D:\C++_demo\opencv\build\x64\vc16\lib.

opencv_world480d.lib

Pour tester en mode Debug x64, copiez le fichier opencv_world480d.dll avec d dans le répertoire Debug de votre projet.

Lorsqu'il n'y a pas de répertoire Debug, vous devez exécuter le code en mode Debug | x64.

D:\C++_demo\opencv\build\x64\vc16\bin
===>
D:\C++_demo\opencv_onnx\x64\Debug

Le blogueur a installé ici la version de débogage pour faciliter le débogage. Les lecteurs peuvent installer la version finale. Il leur suffit de modifier le paramètre Debug |

opencv appelle le modèle onnx

Simple à utiliser

Voici une simple vérification pour savoir si opencv est installé avec succès. Il convient à de nombreuses personnes, y compris aux blogueurs qui ne sont pas familiers avec le C++. Le code complète la lecture et l'affichage d'images simples.

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
    
    
	Mat src = imread("./animal-1.jpg");
	//没有图像输入
	if (src.empty()) {
    
    
		printf("....\n");
		return -1;
	}
	//namedWindow("输入窗口", WINDOW_FREERATIO);
	imshow("输入窗口", src);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

Appelez le modèle onnx

Après avoir converti la version python d'opencv en la version C++ correspondante, nous avons constaté que les effets de sortie sont exactement les mêmes.Le modèle onnx peut être utilisé comme interface C++ pour que d'autres applications puissent l'appeler.

#include <iostream>
#include <string>
#include <vector>
#include<opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace std;
cv::Mat normalizeImage(const cv::Mat& image, const cv::Scalar& mean, const cv::Scalar& std) {
    
    
    cv::Mat normalized;
    image.convertTo(normalized, CV_32F);
    cv::subtract(normalized / 255.0, mean, normalized);
    cv::divide(normalized, std, normalized);
    return normalized;
}
int main()
{
    
       
    // 读取图片
    cv::Mat bgrImage = cv::imread("./animal-1.jpg", cv::IMREAD_COLOR);
    // 图片格式转化bgr-->rgb
    cv::Mat rgbImage;
    cv::cvtColor(bgrImage, rgbImage, cv::COLOR_BGR2RGB);
    // 获取图像的大小
    cv::Size originalSize(rgbImage.cols, rgbImage.rows);
    cv::Mat resizedImage;

    // 定义目标图像大小
    cv::Size targetSize(416, 416);
    //图片尺寸缩放
    cv::resize(rgbImage, resizedImage, targetSize, 0, 0, cv::INTER_AREA);

    // 定义每个通道的归一化参数
    cv::Scalar mean(0.485, 0.456, 0.406); // 均值
    cv::Scalar std(0.229, 0.224, 0.225);  // 标准差
    // 图片归一化
    cv::Mat normalized = normalizeImage(resizedImage, mean, std);
    
    // 加载ONNX模型
    cv::dnn::Net net = cv::dnn::readNetFromONNX("D:/C++_demo/opencv_onnx/PFNet.onnx");
    cv::Mat blob = cv::dnn::blobFromImage(normalized);
    // 将Blob设置为模型的输入
    net.setInput(blob);
    // 运行前向传播
    std::vector<cv::Mat> output_probs;
    // 获取多输出对应的名称
    std::vector<cv::String> output_layer_names = net.getUnconnectedOutLayersNames();
    net.forward(output_probs, output_layer_names);
    cv::Mat prediction = output_probs[3];
    cv::Mat mask;
    cv::resize(prediction.reshape(1, 416) * 255.0, mask, originalSize, 0, 0, cv::INTER_AREA);
    cv::imwrite("saved_opencv_c++_image.png", mask);
    return 0;
}


Résumer

Présentez le processus d'appel du modèle ONNX par POpencv sous Python et C++ aussi simplement et en détail que possible.

Je suppose que tu aimes

Origine blog.csdn.net/yangyu0515/article/details/132894953
conseillé
Classement