如何檢視程式視窗類名
【小白向】基於YOLOV5的資料集標註,訓練,Windows/Linux/Jetson Nano多平臺部署全流程
準備工作和資料標註
1. 安裝配置Cuda, Cudnn, Pytorch
該部分不進行詳細介紹, 具體過程請百度。此處小編使用
Pytorch1.9
。
2. 製作自己的資料集
這裡小編給大家準備了一個人體檢測的資料集,供大家測試使用。
3. 資料集準備工作.
(1) 層級關係
yolov5資料集所需的資料夾結構,以小編提供的資料集為例。
people資料夾下包含兩個子資料夾images(用於存放圖片)和labels(用於存放標籤檔案)。
images資料夾下包含train和val兩個資料夾,分別存放訓練集的圖片和驗證集的圖片。
labels資料夾下包含train和val兩個資料夾,分別存放訓練集的標籤和驗證集的標籤。
dataset。png
(2) 下載標註軟體
這裡小編自己編寫了一款標註軟體,直接支援匯出yolov5格式。
標註軟體介面展示
(3) 準備需要標註的資料(
注意本軟體單次只能標註1000張,建議單次500張以下
)
這裡我簡單準備了5張貓狗資料的。
貓狗資料集展示
(4) 準備標籤檔案
新建一個labels。txt檔案(名字任意)。將類名按照自己需要的順序進行輸入(
注意,這裡的順序關係到最後匯出yolov5 labels檔案的標籤順序
)
labels。txt內容
4. 開始標註.
(1) 匯入圖片和標籤檔案
開啟CasiaLabeler軟體。點選
標註>開啟
匯入圖片。
點選
標註>新增標籤
匯入標籤。 選擇之前建立的標籤檔案,匯入後如圖。
匯入標籤
(2) 開始標註並指定標籤
初步框選標註物件。
框選目標
在標註資訊欄,修改目標的標籤。
修改目標的標籤
在屬性視窗可以修改標註框的顏色。
屬性視窗
完成之後。(
PS.標註框可以透過Ctrl+C和Ctrl+V進行復制貼上
)
標註完成效果展示
(3) 匯出標註結果
點選
標註>匯出標註結果>yolov5
,並指定一個空資料夾。
標籤匯出到一個空資料夾
(4) 整理資料集層級結構
資料集的組織結構按照這個圖排列
PS.
1。標註過程請及時儲存工程檔案
2。第一次儲存工程後,會在工程目錄下間隔一定時間自動儲存工程。可以點選
幫助>設定
選擇自動儲存時間間隔。
標註工程儲存間隔時間設定,可調節
3。標註完成後,可以自動切換下一張預覽標註結果。點選
檢視>預覽
即可自動切換標註場景,切換間隔時間按可以點選
幫助>設定
設定預覽間隔時間。
設定預覽間隔時間
4。在標註一部分圖片後,圖片的位置發生了變化,或者圖片複製至另外一臺的電腦上,則會出現路徑丟失的情況。
容錯機制
5。丟失解決方法,點選
幫助>設定
。在圖片路徑修改處,選擇需要修改的工程,並指定圖片新的路徑,點選
轉換
即可完成工程檔案修復。再次開啟工程即可。
丟失解決方法
5. 準備Yolov5程式碼
1 Clone程式碼
git clone https://github。com/msnh2012/MsnhnetModelZoo。git
(注意!必須Clone小編為msnhnet定製的程式碼!)
2 安裝依賴
pip install requirements。txt(
可以手動安裝
)
6. 準備Yolov5預訓練模型
(1) 這裡小編已經給大家準備好了預訓練模型(yolov5_pred資料夾中)
(2) 將下載好的預訓練模型檔案複製至yolov5ForMsnhnet/yolov5/weights資料夾下
模型訓練
1. 準備工作
(1) 資料集準備(這裡以people資料集為例)
將標註好的資料集放置在datas資料夾下。
在datas資料夾下建立一個people。yaml檔案,用於配置資料集資訊
train:
訓練集圖片位置
val:
驗證集圖片位置
nc:
類別數量
names:
所有類的名稱
yaml檔案配置
(2) 選擇所需訓練的模型(
這裡以yolov5m為例
)
在models資料夾下,複製一份yolov5m。yaml,重新命名為yolov5m_people。yaml。
將nc改為1(還是一樣,改成資料集的類的個數)。
nc代表資料集目標類別總數
(3) 關於anchors
# anchors
anchors:
-[10,13,16,30,33,23]# P3/8
-[30,61,62,45,59,119]# P4/16
-[116,90,156,198,373,326]# P5/32
anchors引數共有三行,每行9個數值;每一行代表不同的特徵圖;
第一行是在最大的特徵圖上的anchors
第二行是在中間的特徵圖上的anchors
第三行是在最小的特徵圖上的anchors
yolov5會在訓練最開始自動對anchors進行check(可以修改 train。py中以下程式碼使用或者不使用自動anchor)。
parser。add_argument(‘——noautoanchor’, action=‘store_true’, help=‘disable autoanchor check’)
如果標註資訊對anchor的最佳召回率>=0。98,則不需要重新計算anchors, 反之則需要從新計算。
check程式碼如下:
引數:
dataset:
資料集
model:
模型
thr:
dataset中標註框寬高比最大閾值,引數在超參檔案 hyp。scratch。yaml“中”anchor_t“設定。
imgsz:
圖片尺寸
defcheck_anchors(dataset, model, thr=4。0, imgsz=640):
# Check anchor fit to data, recompute if necessary
print(‘\nAnalyzing anchors。。。 ’, end=‘’)
m = model。module。model[-1] if hasattr(model, ‘module’) else model。model[-1] # Detect()
shapes = imgsz * dataset。shapes / dataset。shapes。max(1, keepdims=True)
scale = np。random。uniform(0。9, 1。1, size=(shapes。shape[0], 1)) # augment scale
wh = torch。tensor(np。concatenate([l[:, 3:5] * s for s, l in zip(shapes * scale, dataset。labels)]))。float() # wh
defmetric(k):# compute metric
r = wh[:, None] / k[None]
x = torch。min(r, 1。 / r)。min(2)[0] # ratio metric
best = x。max(1)[0] # best_x
aat = (x > 1。 / thr)。float()。sum(1)。mean() # anchors above threshold
bpr = (best > 1。 / thr)。float()。mean() # best possible recall
return bpr, aat
bpr, aat = metric(m。anchor_grid。clone()。cpu()。view(-1, 2))
print(‘anchors/target = %。2f, Best Possible Recall (BPR) = %。4f’ % (aat, bpr), end=‘’)
if bpr < 0。98: # threshold to recompute
print(‘。 Attempting to generate improved anchors, please wait。。。’ % bpr)
na = m。anchor_grid。numel() // 2# number of anchors
new_anchors = kmean_anchors(dataset, n=na, img_size=imgsz, thr=thr, gen=1000, verbose=False)
new_bpr = metric(new_anchors。reshape(-1, 2))[0]
if new_bpr > bpr: # replace anchors
new_anchors = torch。tensor(new_anchors, device=m。anchors。device)。type_as(m。anchors)
m。anchor_grid[:] = new_anchors。clone()。view_as(m。anchor_grid) # for inference
m。anchors[:] = new_anchors。clone()。view_as(m。anchors) / m。stride。to(m。anchors。device)。view(-1, 1, 1) # loss
check_anchor_order(m)
print(‘New anchors saved to model。 Update model *。yaml to use these anchors in the future。’)
else:
print(‘Original anchors better than new anchors。 Proceeding with original anchors。’)
print(‘’) # newline
聚類anchor程式碼:
引數:
path:
之前建立的people。yaml資料集配置檔案路徑
n:
anchors 組數量 xx,xx為一組
img_size:
圖片尺寸
thr:
dataset中標註框寬高比最大閾值,引數在超參檔案 hyp。scratch。yaml”中“anchor_t”設定。
gen:
kmean演算法iter次數
verbose:
是否列印結果
defkmean_anchors(path=‘。/data/coco128。yaml’, n=9, img_size=640, thr=4。0, gen=1000, verbose=True):
“”“ Creates kmeans-evolved anchors from training dataset
Arguments:
path: path to dataset *。yaml, or a loaded dataset
n: number of anchors
img_size: image size used for training
thr: anchor-label wh ratio threshold hyperparameter hyp[‘anchor_t’] used for training, default=4。0
gen: generations to evolve anchors using genetic algorithm
Return:
k: kmeans evolved anchors
Usage:
from utils。general import *; _ = kmean_anchors()
”“”
thr = 1。 / thr
defmetric(k, wh):# compute metrics
r = wh[:, None] / k[None]
x = torch。min(r, 1。 / r)。min(2)[0] # ratio metric
# x = wh_iou(wh, torch。tensor(k)) # iou metric
return x, x。max(1)[0] # x, best_x
deffitness(k):# mutation fitness
_, best = metric(torch。tensor(k, dtype=torch。float32), wh)
return (best * (best > thr)。float())。mean() # fitness
defprint_results(k):
k = k[np。argsort(k。prod(1))] # sort small to large
x, best = metric(k, wh0)
bpr, aat = (best > thr)。float()。mean(), (x > thr)。float()。mean() * n # best possible recall, anch > thr
print(‘thr=%。2f: %。4f best possible recall, %。2f anchors past thr’ % (thr, bpr, aat))
print(‘n=%g, img_size=%s, metric_all=%。3f/%。3f-mean/best, past_thr=%。3f-mean: ’ %
(n, img_size, x。mean(), best。mean(), x[x > thr]。mean()), end=‘’)
for i, x in enumerate(k):
print(‘%i,%i’ % (round(x[0]), round(x[1])), end=‘, ’if i < len(k) - 1else‘\n’) # use in *。cfg
return k
if isinstance(path, str): # *。yaml file
with open(path) as f:
data_dict = yaml。load(f, Loader=yaml。FullLoader) # model dict
from utils。datasets import LoadImagesAndLabels
dataset = LoadImagesAndLabels(data_dict[‘train’], augment=True, rect=True)
else:
dataset = path # dataset
# Get label wh
shapes = img_size * dataset。shapes / dataset。shapes。max(1, keepdims=True)
wh0 = np。concatenate([l[:, 3:5] * s for s, l in zip(shapes, dataset。labels)]) # wh
# Filter
i = (wh0 < 3。0)。any(1)。sum()
if i:
print(‘WARNING: Extremely small objects found。 ’
‘%g of %g labels are < 3 pixels in width or height。’ % (i, len(wh0)))
wh = wh0[(wh0 >= 2。0)。any(1)] # filter > 2 pixels
# Kmeans calculation
print(‘Running kmeans for %g anchors on %g points。。。’ % (n, len(wh)))
s = wh。std(0) # sigmas for whitening
k, dist = kmeans(wh / s, n, iter=30) # points, mean distance
k *= s
wh = torch。tensor(wh, dtype=torch。float32) # filtered
wh0 = torch。tensor(wh0, dtype=torch。float32) # unflitered
k = print_results(k)
# Plot
# k, d = [None] * 20, [None] * 20
# for i in tqdm(range(1, 21)):
# k[i-1], d[i-1] = kmeans(wh / s, i) # points, mean distance
# fig, ax = plt。subplots(1, 2, figsize=(14, 7))
# ax = ax。ravel()
# ax[0]。plot(np。arange(1, 21), np。array(d) ** 2, marker=‘。’)
# fig, ax = plt。subplots(1, 2, figsize=(14, 7)) # plot wh
# ax[0]。hist(wh[wh[:, 0]<100, 0],400)
# ax[1]。hist(wh[wh[:, 1]<100, 1],400)
# fig。tight_layout()
# fig。savefig(‘wh。png’, dpi=200)
# Evolve
npr = np。random
f, sh, mp, s = fitness(k), k。shape, 0。9, 0。1# fitness, generations, mutation prob, sigma
pbar = tqdm(range(gen), desc=‘Evolving anchors with Genetic Algorithm’) # progress bar
for _ in pbar:
v = np。ones(sh)
while (v == 1)。all(): # mutate until a change occurs (prevent duplicates)
v = ((npr。random(sh) < mp) * npr。random() * npr。randn(*sh) * s + 1)。clip(0。3, 3。0)
kg = (k。copy() * v)。clip(min=2。0)
fg = fitness(kg)
if fg > f:
f, k = fg, kg。copy()
pbar。desc = ‘Evolving anchors with Genetic Algorithm: fitness = %。4f’ % f
if verbose:
print_results(k)
return print_results(k)
(4) train檔案
複製一個train。py檔案命名為train_people。py。修改模型引數
模型可配置的超引數
修改opt引數
weights:
載入的權重檔案(weights資料夾下yolov5m。pt)
cfg:
模型配置檔案,網路結構(model資料夾下yolov5m_people。yaml)
data:
資料集配置檔案,資料集路徑,類名等(datas資料夾下people。yaml)
hyp:
超引數檔案
epochs:
訓練總輪次
batch-size:
批次大小
img-size:
輸入圖片解析度大小(512*512)
rect:
是否採用矩形訓練,預設False
resume:
接著打斷訓練上次的結果接著訓練
nosave:
不儲存模型,預設False
notest:
不進行test,預設False
noautoanchor:
不自動調整anchor,預設False
evolve:
是否進行超引數進化,預設False
bucket:
谷歌雲盤bucket,一般不會用到
cache-images:
是否提前快取圖片到記憶體,以加快訓練速度,預設False
name:
資料集名字,如果設定:results。txt to results_name。txt,預設無
device:
訓練的裝置,cpu;0(表示一個gpu裝置cuda:0);0,1,2,3(多個gpu裝置)
multi-scale:
是否進行多尺度訓練,預設False
single-cls:
資料集是否只有一個類別,預設False
adam:
是否使用adam最佳化器
sync-bn:
是否使用跨卡同步BN,在DDP模式使用
local_rank:
gpu編號
logdir:
存放日誌的目錄
workers:
dataloader的最大worker數量(
windows需設定為0
)
超引數配置
2. 開始train
python train_people。py
訓練流程展示
訓練過程中,會在yolov5/runs資料夾下生成一個exp資料夾,
weights包含訓練過程中最後一次訓練好的模型last。pt和歷史最佳模型best。pt。
events檔案可以使用tensorboard檢視訓練過程。在exp資料夾中,開啟終端,執行tensorboard ——logdir=。在瀏覽器中輸入http://localhost:6006/可檢視訓練過程與曲線。
其它過程檔案。
推理測試
將runs/exp資料夾下的best。pt檔案複製到weights資料夾下。
在inference/images資料夾下放置幾個測試圖片。這裡放置一張官方的bus。jpg
bus。jpg
在yolov5資料夾中開啟終端,執行:
python detect ——weights weights/best。pt ——source inference/images ——output inference/output
在inference/output資料夾中會生成推理結果。
預測結果
至此,使用pytorch訓練yolov5模型完成,下一節將介紹如何在CMake(c++),Winform(C#)以及windows(PC),linux(Jetson Nx)中使用Msnhnet部署yolov5。
基於MsnhNet部署yolov5
本篇將分windows和linux, pc和jetson nx平臺分別給大家講解如何使用Msnhnet部署yolov5。
pytorch模型轉msnhnet
在yolov5資料夾下開啟終端。將best。pt複製至weights資料夾下。執行
python yolov5ToMsnhnet。py
yolov5ToMsnhnet。py檔案內容:
from PytorchToMsnhnet import *
Msnhnet。Export = True
from models。experimental import attempt_load
import torch
weights = “weights/best。pt”# pt檔案
msnhnetPath = “yolov5m。msnhnet”# 匯出。msnhnet檔案
msnhbinPath = “yolov5m。msnhbin”# 匯出。msnhbin檔案
model = attempt_load(weights, “cpu”)
model。eval() # cpu模式,推理模式
img = torch。rand(512*512*3)。reshape(1,3,512,512) #生成隨機推理資料
tans(model,img,msnhnetPath,msnhbinPath) #模型轉換
匯出成功後會在資料夾下生成yolov5m。msnhnet和yolov5m。msnhbin檔案。
Windows 篇
1. 準備工作
(1) 安裝Visual studio
網址:https://visualstudio。microsoft。com/zh-hans/
下載visual studio 2017以上任意版本進行安裝。此處勾選。Net桌面開發和使用c++的桌面開發。
vs安裝介面
(2) 安裝cuda和cudnn, 此處請自行百度。
cuda網址:https://developer。nvidia。com/cuda-downloads
cudnn網址:https://developer。nvidia。com/zh-cn/cudnn
下載cudaxx。exe檔案安裝cuda(此過程最好使用cuda中自帶的顯示卡驅動程式),下載cudnnxxx。zip檔案,將其解壓到 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vxx。xx資料夾下,即完成了cuda和cudnn配置。
將C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vxx。xx 新增到系統環境變數。
設定CUDA環境變數
(3) 開啟cmd, 輸入nvcc。測試cuda是否安裝完成。以下結果說明cuda配置完成。
CUDA配置成功標誌
(4) 安裝cmake(建議3。17)。
cmake下載網址:https://cmake。org/files/v3。17/
下載檔案: cmake-3。17。5-win64-x64。msi
完成安裝。
(5) clone Msnhnetgit clone https://github。com/msnh2012/Msnhnet。git
2. 編譯OpenCV庫
(1) 小編這裡給大家準備好了OpenCV的原始碼檔案,不用科學上網了。
(2) 開啟cmake-gui。exe。
選擇OpenCV和要編譯的目標路徑
(3) 點選config選擇安裝的visual studio版本,選擇x64(此處以VS2017為例),點選Finish,等待配置完成。
選擇安裝的visual studio版本
(4) 引數配置。
-CMAKE_INSTALL_PREFIX#指定安裝位置,如: D:/libs/opencv
-CPU_BASELINE#選擇AVX2(如果CPU支援AVX2加速)
-BUILD_TESTS#取消勾選
(5) 點選generate->Generating done。
(6) 點選Open Project。分別選擇Debug右鍵生成。(此過程需要等待10min~60min不等,根據電腦配置)
OpenCV編譯
(7) 右鍵安裝。(會將編譯好的可執行檔案安裝在指定安裝位置,如:D:/libs/opencv)
安裝OpenCV到指定路徑
(8) 重複6-7步選擇Release版本進行編譯安裝。
(9) 指定OpenCV_DIR環境變數,用於CMakeList能使用FindPackage找到OpenCV。
OpenCV環境變數
(10) 指定Path環境變數。在Path環境變數下新增Opencv的bin資料夾位置,如: D:\libs\opencv\x64\vc15\bin
3. 編譯Msnhnet庫
(1) 開啟cmake-gui。exe。
選中Msnhnet原始碼路徑和build資料夾路徑
(2) 點選config選擇安裝的visual studio版本,選擇x64(此處以VS2017為例),點選Finish,等待配置完成。
選擇安裝的visual studio版本
(3) 勾選以下引數。
-CMAKE_INSTALL_PREFIX#指定安裝位置,如: D:/libs/Msnhnet
-BUILD_EXAMPLE#構建示例
-BUILD_SHARED_LIBS#構建動態連結庫
-BUILD_USE_CUDNN#使用CUDNN
-BUILD_USE_GPU#使用GPU
-BUILD_USE_OPENCV#使用OPENCV
-ENABLE_OMP#使用OMP
-OMP_MAX_THREAD#使用最大核心數
編譯Msnhnet cmake選項
(4) 點選generate->Generating done。
(5) 點選Open Project。分別選擇Debug右鍵生成。
VS編譯MsnhNet
(6) 右鍵安裝。(會將編譯好的可執行檔案安裝在指定安裝位置,如:D:/libs/Msnhnet)
VS安裝MsnhNet
(7) 重複6-7步選擇Release版本進行編譯安裝。
(8) 指定Msnhnet_DIR環境變數,用於CMakeList能使用FindPackage找到Msnhnet。
配置MsnhNet環境變數
(9)指定Path環境變數。在Path環境變數下新增Msnhnet的bin資料夾位置,如: D:\libs\Msnhnet\bin
(10) 測試。
下載小編準備好的一系列Msnhnet測試模型。並解壓到如D盤根目錄連結:https:///s/1mBaJvGx7tp2ZsLKzT5ifOg提取碼:x53z
在Msnhnet安裝目錄開啟終端。執行
yolov3_gpu D:/models
yolov3_gpu_fp16 D:/models #fp16推理
推理結果展示
當然,你可以可以測試其它模型。
4. 使用C#部署Msnhnet
(1) clone MsnhnetSharp
git clone https://github。com/msnh2012/MsnhnetSharp
(2) 雙擊開啟MsnhnetSharp。sln檔案
(3) 選擇x64平臺和Release模式,右鍵生成MsnhnetSharp,再生成MsnhnetForm。
(4) 點選啟動按鈕。
(5) 在引數配置欄,分別指定msnhnetPath和msnhbinPath為之前匯出的yolov5m的引數。然後將上一節制作好的labels。txt檔案,複製一份,重新命名為labels。names。
(6) 點選初始化網路。等待初始化完成,init done。
(7) 點選讀取圖片, 選擇那張bus。jpg。
(8) 點選yolo GPU(Yolo Detect GPU)。 第一次推理時間較長。
(9) 點選重置圖片。
(10) 再次點選yolo GPU(Yolo Detect GPU)。 隨後推理時間正常。
介面展示
至此,使用C#部署Msnhnet完成,後續可以參考MsnhnetForm將MsnhnetSharp部署到你自己的工程中。
5. 使用CMake部署Msnhnet
(1) 新建MsnhnetPrj資料夾
(2) 將yolov5m。msnhnet,yolov5m。msnhbin,labels。txt複製到MsnhnetPrj資料夾內
(3) 新建CMakeLists。txt檔案
cmake_minimum_required(VERSION 3。15)
project(yolov5m_msnhnet
LANGUAGES CXX C CUDA
VERSION 1。0)
find_package(OpenCV REQUIRED)
find_package(Msnhnet REQUIRED)
find_package(OpenMP REQUIRED)
add_executable(yolov5m_msnhnet yolov5m_msnhnet。cpp)
target_include_directories(yolov5m_msnhnet PUBLIC ${Msnhnet_INCLUDE_DIR})
target_link_libraries(yolov5m_msnhnet PUBLIC ${OpenCV_LIBS} Msnhnet)
(4) 新建yolov5m_msnhnet。cpp檔案
#include
#include“Msnhnet/net/MsnhNetBuilder。h”
#include“Msnhnet/io/MsnhIO。h”
#include“Msnhnet/config/MsnhnetCfg。h”
#include“Msnhnet/utils/MsnhOpencvUtil。h”
voidyolov5sGPUOpencv(conststd::string& msnhnetPath, conststd::string& msnhbinPath, conststd::string& imgPath, conststd::string& labelsPath)
{
try
{
Msnhnet::NetBuilder msnhNet;
Msnhnet::NetBuilder::setOnlyGpu(true);
//msnhNet。setUseFp16(true); //開啟使用FP16推理
msnhNet。buildNetFromMsnhNet(msnhnetPath);
std::cout< msnhNet。loadWeightsFromMsnhBin(msnhbinPath); std::vector Msnhnet::IO::readVectorStr(labels, labelsPath。data(), “\n”); Msnhnet::Point2I inSize = msnhNet。getInputSize(); std::vector std::vector img = Msnhnet::OpencvUtil::getPaddingZeroF32C3(imgPath, cv::Size(inSize。x,inSize。y)); for (size_t i = 0; i < 10; i++) { auto st = Msnhnet::TimeUtil::startRecord(); result = msnhNet。runYoloGPU(img); std::cout<<“time : ” << Msnhnet::TimeUtil::getElapsedTime(st) <<“ms”< } cv::Mat org = cv::imread(imgPath); Msnhnet::OpencvUtil::drawYoloBox(org,labels,result,inSize); cv::imshow(“test”,org); cv::waitKey(); } catch (Msnhnet::Exception ex) { std::cout< } } intmain(int argc, char** argv) { std::string msnhnetPath = “yolov5m。msnhnet”; std::string msnhbinPath = “yolov5m。msnhbin”; std::string labelsPath = “labels。txt”; std::string imgPath = “bus。jpg”; yolov5sGPUOpencv(msnhnetPath, msnhbinPath, imgPath,labelsPath); getchar(); return0; } (5) 配置CMake 開啟cmake-gui。exe,按以下配置。點選Config。Generate 基於Cmake編譯Msnhnet,更加方便的方式 (6) 編譯,點選Open Project,選擇Release模式,參考之前編譯Msnhnet直接生成。 編譯MsnhNet工程 (7) 複製可執行檔案。從MsnhnetPrj/build/Release/yolov5m_msnhnet。exe複製到MsnhnetPrj目錄。 (8) 部署結果 雙擊yolov5m_msnhnet。exe檢視部署結果 推理完成 Linux(Jetson NX) 篇 1. 準備工作 一般來說,Jetson都已經自帶了cuda和cudnn,故不用專門安裝。 安裝構建工具 sudo apt-get install build-essential 安裝opencv sudo apt-get install libopencv 2. 編譯Msnhnet庫 (1) 終端開啟cmake-gui。 cmake-gui介面 (2) 點選config選擇cmake的編譯鏈 使用預設的gcc編譯器 (3) 勾選以下引數。 -CMAKE_INSTALL_PREFIX#指定安裝位置,如: D:/libs/Msnhnet -BUILD_EXAMPLE#構建示例 -BUILD_SHARED_LIBS#構建動態連結庫 -BUILD_USE_CUDNN#使用CUDNN -BUILD_USE_GPU#使用GPU -BUILD_USE_NEON#使用neon加速 -BUILD_USE_OPENCV#使用OPENCV -ENABLE_OMP#使用OMP -OMP_MAX_THREAD#使用最大核心數 Linux Cmake編譯MsnhNet的編譯選項 (4) 點選generate->Generating done。 (5) 在Msnhnet/build資料夾中開啟終端。 make -j sudo make install (6) 配置系統環境變數 sudo gedit /etc/ld。so。conf。d/usr。confg # 新增: /usr/local/lib sudo ldconfig (7) 測試。 下載小編準備好的一系列Msnhnet測試模型。並解壓到如home根目錄 連結:https:///s/1mBaJvGx7tp2ZsLKzT5ifOg 提取碼:x53z cd /usr/local/bin yolov3_gpu /home/xxx/models yolov3_gpu_fp16 /home/xxx/models #fp16推理 預測結果展示 當然,你可以可以測試其它模型。 3. 使用CMake部署Msnhnet (1) 新建MsnhnetPrj資料夾 (2) 將yolov5m。msnhnet,yolov5m。msnhbin,labels。txt複製到MsnhnetPrj資料夾內 (3) 新建CMakeLists。txt檔案 cmake_minimum_required(VERSION 3。15) project(yolov5m_msnhnet LANGUAGES CXX C CUDA VERSION 1。0) find_package(OpenCV REQUIRED) find_package(Msnhnet REQUIRED) find_package(OpenMP REQUIRED) add_executable(yolov5m_msnhnet yolov5m_msnhnet。cpp) target_include_directories(yolov5m_msnhnet PUBLIC ${Msnhnet_INCLUDE_DIR}) target_link_libraries(yolov5m_msnhnet PUBLIC ${OpenCV_LIBS} Msnhnet) (4) 新建yolov5m_msnhnet。cpp檔案 #include #include“Msnhnet/net/MsnhNetBuilder。h” #include“Msnhnet/io/MsnhIO。h” #include“Msnhnet/config/MsnhnetCfg。h” #include“Msnhnet/utils/MsnhOpencvUtil。h” voidyolov5sGPUOpencv(conststd::string& msnhnetPath, conststd::string& msnhbinPath, conststd::string& imgPath, conststd::string& labelsPath) { try { Msnhnet::NetBuilder msnhNet; Msnhnet::NetBuilder::setOnlyGpu(true); //msnhNet。setUseFp16(true); //開啟使用FP16推理 msnhNet。buildNetFromMsnhNet(msnhnetPath); std::cout< msnhNet。loadWeightsFromMsnhBin(msnhbinPath); std::vector Msnhnet::IO::readVectorStr(labels, labelsPath。data(), “\n”); Msnhnet::Point2I inSize = msnhNet。getInputSize(); std::vector std::vector img = Msnhnet::OpencvUtil::getPaddingZeroF32C3(imgPath, cv::Size(inSize。x,inSize。y)); for (size_t i = 0; i < 10; i++) { auto st = Msnhnet::TimeUtil::startRecord(); result = msnhNet。runYoloGPU(img); std::cout<<“time : ” << Msnhnet::TimeUtil::getElapsedTime(st) <<“ms”< } cv::Mat org = cv::imread(imgPath); Msnhnet::OpencvUtil::drawYoloBox(org,labels,result,inSize); cv::imshow(“test”,org); cv::waitKey(); } catch (Msnhnet::Exception ex) { std::cout< } } intmain(int argc, char** argv) { std::string msnhnetPath = “。。/yolov5m。msnhnet”; std::string msnhbinPath = “。。/yolov5m。msnhbin”; std::string labelsPath = “。。/labels。txt”; std::string imgPath = “。。/bus。jpg”; yolov5sGPUOpencv(msnhnetPath, msnhbinPath, imgPath,labelsPath); getchar(); return0; } (5) 編譯,在MsnhnetPrj資料夾下開啟終端 mkdir build cd build make 。/yolov5m_msnhnet (6) 部署結果 基於Cmake構建工程結果展示 Linux(PC) 篇 和Jetson Nx部署類似, 主要區別是先要在Linux上配置好cuda和cudnn, 然後解除安裝CMake, 安裝CMake 3。17版本。 其它的和Jestson NX一樣。(ps。 在CMake引數配置裡沒有NEON項,此為ARM平臺專有) 到此,使用Msnhnet從0到部署Yolov5網路完成。 最後 歡迎關注我和BBuf及公眾號的小夥伴們一塊維護的一個深度學習框架Msnhnet: https://github。com/msnh2012/Msnhnet