国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)

這篇具有很好參考價(jià)值的文章主要介紹了[BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

最近一些人問我怎么在BPU上部署yolov5,因?yàn)橹暗牟┛蚚BPU部署教程] 一文帶你輕松走出模型部署新手村介紹的網(wǎng)絡(luò)都是基于Caffe的,自己的網(wǎng)絡(luò)都是基于pytorch的,所以遇到了很多坑。鑒于這些需求,我自己研究了下部署的方式,把自己的過程整理下來供各位參考(看我這么好的份上,來個(gè)三連吧o( ̄▽ ̄)ブ)。

yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

在部署之前,我先說明幾點(diǎn)

  • 本教程使用的一些文件都放在百度云(提取碼:0a09 )里了,可以自行下載使用
  • yolov5的代碼我用的是https://github.com/ultralytics/yolov5的master分支,目前應(yīng)該是版本6.2,后續(xù)作者更新后,可以切換到6.2分支來使用。
  • 盡管本教程轉(zhuǎn)換模型用的是官方模型,但各位可以訓(xùn)練自己的模型來轉(zhuǎn)換,模型轉(zhuǎn)換幾乎沒有啥差異,可放心食用。
  • 代碼版本我應(yīng)該和官方使用的不一樣,X3P給的官方測(cè)試時(shí)間是45ms左右,但我轉(zhuǎn)換模型時(shí)候,發(fā)現(xiàn)有較多的層跑在CPU,導(dǎo)致推理時(shí)間多很多。
  • 很多人說了后處理過程耗時(shí)太高,后處理計(jì)算在python跑的話,確實(shí)速度會(huì)慢很多,所以我以這個(gè),順便教各位如何利用cython來包裝自己的C++代碼來加速,最后測(cè)試時(shí)候,python版的后處理耗時(shí)越450ms,用cython包裝后,后處理僅用9ms

下面,開始我們的部署之旅。

yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

一 環(huán)境配置

1.1 安裝依賴包

如果在當(dāng)前python環(huán)境下能利用pip install onnx輕松安裝onnx,那就直接配置yolov5的環(huán)境就行了。

我電腦是windows,又不想安裝虛擬機(jī),所以環(huán)境的安裝有一些限制。我最開始的python環(huán)境是3.6版本,結(jié)果安裝onnx時(shí)候一堆問題。3.10有onnx的whl包,所以,建議跑模型的python環(huán)境為3.10(3.8好像也可,自己試試)。

下面給出我部署的指令流程,對(duì)于的pytorch包我也放在百度云了。

# 在指定路徑下創(chuàng)建虛擬環(huán)境,我的anaconda安裝在c盤,但我想把環(huán)境放在d盤,所以利用--prefix D:\Anaconda3\envs\yolov5指定路徑
conda create --prefix D:\Anaconda3\envs\yolov5 python=3.10
# 切換虛擬環(huán)境
conda activate D:\Anaconda3\envs\yolov5
# 安裝關(guān)鍵包ONNX
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple onnx
# 安裝yolov5依賴的pytorch
pip install "torch-1.11.0+cu113-cp310-cp310-win_amd64.whl" "torchaudio-0.11.0+cu113-cp310-cp310-win_amd64.whl" "torchvision-0.12.0+cu113-cp310-cp310-win_amd64.whl" -i https://pypi.tuna.tsinghua.edu.cn/simple
# 安裝yolov5需要的包
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib>=3.2.2 numpy>=1.18.5 opencv-python>=4.1.1 Pillow>=7.1.2 PyYAML>=5.3.1 requests>=2.23.0 scipy>=1.4.1 tqdm>=4.64.0 tensorboard>=2.4.1 pandas>=1.1.4 seaborn>=0.11.0 ipython psutil thop>=0.1.1

1.2 運(yùn)行YoloV5

下載百度云中提供的文件,按照如下流程操作:

  1. 解壓yolov5-master.zip。
  2. zidane.jpg放到yolov5-master文件夾中。
  3. yolov5s.pt放到yolov5-master/models文件夾中。
  4. 進(jìn)入yolov5-master文件夾,輸入python .\detect.py --weights .\models\yolov5s.pt --source zidane.jpg,代碼會(huì)輸出檢測(cè)結(jié)果保存路徑,比如我的就是Results saved to runs\detect\exp9,檢測(cè)結(jié)果如下所示。
    yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

1.3 pytorch的pt模型文件轉(zhuǎn)onnx

轉(zhuǎn)換的時(shí)候,一定要清楚一點(diǎn),BPU的工具鏈沒有支持onnx的所有版本的算子,即當(dāng)前BPU支持onnx的opset版本為10和11。錯(cuò)誤的opset在模型檢查階段就無法通過,在后面我給各位展示轉(zhuǎn)換失敗的結(jié)果。

# 錯(cuò)誤的轉(zhuǎn)換指令
python .\export.py --weights .\models\yolov5s.pt --include onnx
# 正確的轉(zhuǎn)換指令
python .\export.py --weights .\models\yolov5s.pt --include onnx --opset 11

轉(zhuǎn)換后,控制臺(tái)會(huì)輸出一些log信息,轉(zhuǎn)換后的模型文件在.\\models\\yolov5s.pt。

export: data=D:\05 - \01 - x3\BPUCodes\yolov5\yolov5-master\data\coco128.yaml, weights=['.\\models\\yolov5s.pt'], imgsz=[640, 640], batch_size=1, device=cpu, half=False, inplace=False, train=False, keras=False, optimize=False, int8=False, dynamic=False, simplify=False, opset=12, verbose=False, workspace=4, nms=False, agnostic_nms=False, topk_per_class=100, topk_all=100, iou_thres=0.45, conf_thres=0.25, include=['onnx']
YOLOv5  2022-9-1 Python-3.10.4 torch-1.11.0+cu113 CPU

Fusing layers... 
YOLOv5s summary: 213 layers, 7225885 parameters, 0 gradients

PyTorch: starting from models\yolov5s.pt with output shape (1, 25200, 85) (14.1 MB)

ONNX: starting export with onnx 1.12.0...
ONNX: export success  3.6s, saved as models\yolov5s.onnx (28.0 MB)

Export complete (4.2s)
Results saved to D:\05 - \01 - x3\BPUCodes\yolov5\yolov5-master\models
Detect:          python detect.py --weights models\yolov5s.onnx
Validate:        python val.py --weights models\yolov5s.onnx
PyTorch Hub:     model = torch.hub.load('ultralytics/yolov5', 'custom', 'models\yolov5s.onnx')
Visualize:       https://netron.app

二 ONNX模型轉(zhuǎn)換

模型轉(zhuǎn)換要在docker中轉(zhuǎn)換,怎么安裝docker,怎么進(jìn)入OE,怎么掛載硬盤,均在博客[BPU部署教程] 一文帶你輕松走出模型部署新手村中詳細(xì)介紹,任何細(xì)節(jié)不懂的,可以去這里面尋找。

新建一個(gè)文件夾,我這里叫bpucodes,把前面轉(zhuǎn)好的yolov5s.onnx放進(jìn)這個(gè)文件夾里,百度云里也提供了相關(guān)的代碼。

docker中,進(jìn)入bpucodes文件夾,開始我們的模型轉(zhuǎn)換。

2.1 模型檢查

模型檢測(cè)的目的是檢測(cè)有沒有不支持的算子,輸入指令hb_mapper checker --model-type onnx --march bernoulli2 --model yolov5s.onnx,開始檢查模型,顯示如下內(nèi)容表示模型檢查通過。(我們可以發(fā)現(xiàn)網(wǎng)絡(luò)的后端部分存在一些層是運(yùn)行在CPU上的,這會(huì)導(dǎo)致耗時(shí)多一些)
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5
前面提到了,在pt轉(zhuǎn)onnx時(shí),要–opset 11,而我最開始轉(zhuǎn)換的時(shí)候,是沒有指定的,下面說一下我是怎么找到問題的(這部分為題外話,想繼續(xù)下一步的話,直接跳2.2節(jié))

我最開始利用python .\export.py --weights .\models\yolov5s.pt --include onnx來轉(zhuǎn)onnx,結(jié)果發(fā)現(xiàn)在BPU的OE工具鏈里,hb_mapper checker檢查不通過,顯示如下錯(cuò)誤。
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5
谷歌搜到了onnx支持的算子信息https://github.com/microsoft/onnxruntime/blob/main/docs/OperatorKernels.md,在我這個(gè)docker里面,onnx庫的版本為1.7.0,發(fā)現(xiàn)MaxPool實(shí)際上是支持的啊,為啥不通過,結(jié)果我發(fā)現(xiàn)后面的數(shù)字8,11,12,才想起來這個(gè)是不是還要指定opset 呀。
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5
然后,我在yolov5的export.py文件里,發(fā)現(xiàn)opset默認(rèn)是12,難怪不通過,最后問了晟哥,得到支持的版本,最終在指令中增加--opset 11,來生成onnx,這樣就通過了。
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

2.2 準(zhǔn)備校準(zhǔn)數(shù)據(jù)

校準(zhǔn)數(shù)據(jù)的代碼參考[BPU部署教程] 一文帶你輕松走出模型部署新手村中的yolov3的校準(zhǔn)代碼,整體沒有太多改變,主要修改了如下兩個(gè)地方(代碼我放百度云了,跟前面的博客內(nèi)容重復(fù)度太高)。

# 修改輸入圖像大小為640x640
img = imequalresize(img, (640, 640))
# 指定輸出的校準(zhǔn)圖像根目錄
dst_root = '/data/horizon_x3/codes/yolov5/bpucodes/calibration_data

輸入prepare_calibration_data.py可以得到校準(zhǔn)數(shù)據(jù)
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5
其實(shí)在上一節(jié)模型檢查過程中,log信息已經(jīng)輸出網(wǎng)絡(luò)輸入的圖像維度了,我也是直接用這個(gè)。
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

2.3 開始轉(zhuǎn)換BPU模型

轉(zhuǎn)換模型需要yaml參數(shù)文件,具體含義參考yolov3的教程,這里我直接放上我的convert_yolov5s.yaml文件信息。

model_parameters:
  onnx_model: 'yolov5s.onnx'
  output_model_file_prefix: 'yolov5s'
  march: 'bernoulli2'
input_parameters:
  input_type_train: 'rgb'
  input_layout_train: 'NCHW'
  input_type_rt: 'nv12'
  norm_type: 'data_scale'
  scale_value: 0.003921568627451
  input_layout_rt: 'NHWC'
calibration_parameters:
  cal_data_dir: './calibration_data'
  calibration_type: 'max'
  max_percentile: 0.9999
compiler_parameters:
  compile_mode: 'latency'
  optimize_level: 'O3'
  debug: False
  core_num: 2  # x3p是雙核BPU,所以指定為2可以速度更快

輸入命令hb_mapper makertbin --config convert_yolov5s.yaml --model-type onnx開始轉(zhuǎn)換我們的模型!校準(zhǔn)過后會(huì)輸出每一層的量化損失。
轉(zhuǎn)換成功后,得到model_output/yolov5s.bin,這個(gè)文件拿出來,拷貝到旭日X3派上使用,它也是我們上板運(yùn)行所需要的模型文件。
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

三 上板運(yùn)行

有小伙伴說后處理部分耗時(shí)太高,所以我這里除了給出推理代碼,還教各位如何利用cython封裝c++來加速你的代碼。

3.1 文件準(zhǔn)備

下載百度云的文件,拷貝到旭日X3派開發(fā)板中,其中yolov5s.bin就是我們轉(zhuǎn)換后的模型,coco_classes.names僅用在畫框的時(shí)候,如果用自己的數(shù)據(jù)集的話,參考coco_classes.names創(chuàng)建個(gè)新的名字文件即可。

yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

輸入sudo apt-get install libopencv-dev安裝opencv庫,之后進(jìn)入代碼根目錄,輸入python3 setup.py build_ext --inplace,編譯后處理代碼,得到lib/pyyolotools.cpython-38-aarch64-linux-gnu.so文件。

3.2 運(yùn)行推理代碼

模型推理的代碼如下所示,其中yolotools.pypostprocess_yolov5為C++實(shí)現(xiàn)的后處理功能,推理代碼在我這里保存為inference_model_bpu.py。

import numpy as np
import cv2
import os
from hobot_dnn import pyeasy_dnn as dnn
from bputools.format_convert import imequalresize, bgr2nv12_opencv
# lib.pyyolotools為封裝的庫
import lib.pyyolotools as yolotools

def get_hw(pro):
    if pro.layout == "NCHW":
        return pro.shape[2], pro.shape[3]
    else:
        return pro.shape[1], pro.shape[2]

def format_yolov5(frame):
    row, col, _ = frame.shape
    _max = max(col, row)
    result = np.zeros((_max, _max, 3), np.uint8)
    result[0:row, 0:col] = frame
    return result

# img_path 圖像完整路徑
img_path = '20220904134315.jpg'
# model_path 量化模型完整路徑
model_path = 'yolov5s.bin'
# 類別名文件
classes_name_path = 'coco_classes.names'
# 設(shè)置參數(shù)
thre_confidence = 0.4
thre_score = 0.25
thre_nms = 0.45
# 框顏色設(shè)置
colors = [(255, 255, 0), (0, 255, 0), (0, 255, 255), (255, 0, 0)]

# 1. 加載模型,獲取所需輸出HW
models = dnn.load(model_path)
model_h, model_w = get_hw(models[0].inputs[0].properties)
print(model_h, model_w)

# 2 加載圖像,根據(jù)前面模型,轉(zhuǎn)換后的模型是以NV12作為輸入的
# 但在OE驗(yàn)證的時(shí)候,需要將圖像再由NV12轉(zhuǎn)為YUV444
imgOri = cv2.imread(img_path)
inputImage = format_yolov5(imgOri)
img = imequalresize(inputImage, (model_w, model_h))
nv12 = bgr2nv12_opencv(img)

# 3 模型推理
t1 = cv2.getTickCount()
outputs = models[0].forward(nv12)
t2 = cv2.getTickCount()
outputs = outputs[0].buffer # 25200x85x1 
print('time consumption {0} ms'.format((t2-t1)*1000/cv2.getTickFrequency()))

# 4 后處理
image_width, image_height, _ = inputImage.shape
fx, fy = image_width / model_w, image_height / model_h
t1 = cv2.getTickCount()
class_ids, confidences, boxes = yolotools.pypostprocess_yolov5(outputs[0][:, :, 0], fx, fy, 
                                                            thre_confidence, thre_score, thre_nms)
t2 = cv2.getTickCount()
print('post consumption {0} ms'.format((t2-t1)*1000/cv2.getTickFrequency()))

# 5 繪制檢測(cè)框
with open(classes_name_path, "r") as f:
    class_list = [cname.strip() for cname in f.readlines()]
t1 = cv2.getTickCount()
for (classid, confidence, box) in zip(class_ids, confidences, boxes):
    color = colors[int(classid) % len(colors)]
    cv2.rectangle(imgOri, box, color, 2)
    cv2.rectangle(imgOri, (box[0], box[1] - 20), (box[0] + box[2], box[1]), color, -1)
    cv2.putText(imgOri, class_list[classid], (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, (0,0,0))
t2 = cv2.getTickCount()
print('draw rect consumption {0} ms'.format((t2-t1)*1000/cv2.getTickFrequency()))

cv2.imwrite('res.png', imgOri)

輸入sudo python3 inference_model_bpu.py,推理結(jié)果保存為res.png,相關(guān)結(jié)果如下所示,可以看出,后處理部分耗時(shí)為7ms,C++和Python混編有效提升了代碼的運(yùn)行速度。
yolov5轉(zhuǎn)bpu,地平線開發(fā)工具,算法,yolov5

3.3 利用Cython封裝后處理代碼

這部分介紹了利用Cython封裝C++的一些過程,后續(xù)各位有什么其他功能要補(bǔ)充的,按照這個(gè)流程處理即可。

3.3.1 寫后處理的C++代碼

首先,我們創(chuàng)建個(gè)頭文件yolotools.h,用來記錄函數(shù)聲明,方便其他代碼調(diào)用。因?yàn)镃ython調(diào)用時(shí),調(diào)用C++的一些類并不方便,所以寫成C語言接口更方便調(diào)用。

后處理的函數(shù)名為postprocess_yolov5,下面我對(duì)這個(gè)函數(shù)的輸入?yún)?shù)進(jìn)行說明:

  • float *_data, int datanum:輸入模型推理數(shù)據(jù),BPU推理完一張640x640的圖像后,會(huì)輸出一個(gè)25200x85x1的矩陣,我們?nèi)サ?這一項(xiàng),得到一個(gè)25200x85的矩陣,以它的數(shù)據(jù)起點(diǎn)指針作為輸入,datanum為25200*85。
  • int rows, int classnum:rows表示25200,而classnum表示數(shù)據(jù)集中的類別總數(shù),我用的這個(gè)模型是以COCO為例的,所以一共80類。值得注意的,上述的85=classnum+1(得分)+4(矩形4個(gè)參數(shù))
  • float x_factor, float y_factor:圖像的縮放因子
  • float thre_cof, float thre_score, float thre_nms:后處理參數(shù)
  • int *_detected_num, signed int **_classids, float **_confidences, signed int **_boxes:后處理輸出,_detected_num表示預(yù)測(cè)的矩形框個(gè)數(shù),其余的分別為對(duì)應(yīng)得數(shù)據(jù),并返回對(duì)應(yīng)的數(shù)據(jù)指針。
#ifndef YOLOV5_TOOLS_H
#define YOLOV5_TOOLS_H

void postprocess_yolov5(float *_data, int datanum, 
                        int rows, int classnum,
                        float x_factor, float y_factor, 
                        float thre_cof, float thre_score, float thre_nms,
                        int *_detected_num, signed int **_classids, float **_confidences, signed int **_boxes);
// 釋放由postprocess_yolov5動(dòng)態(tài)分配的內(nèi)存                        
void free_postprocess_yolov5(signed int **_classids, float **_confidences, signed int **_boxes);
#endif

創(chuàng)建yolov5postprocess.cpp來對(duì)后處理函數(shù)進(jìn)行實(shí)現(xiàn)

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <mutex>
#include "yolotools.h"

// 這部分的代碼參考了https://github.com/ultralytics/yolov5/issues/239
void postprocess_yolov5(float *_data, int datanum, 
                        int rows, int classnum,
                        float x_factor, float y_factor, 
                        float thre_cof, float thre_score, float thre_nms,
                        int *_detected_num, signed int **_classids, float **_confidences, signed int **_boxes)
{
  float *data = (float*)_data;
  int dimensions = classnum + 5;
  CV_Assert(datanum == rows * dimensions);
  
  std::vector<cv::Rect> boxes;
  std::vector<int> class_ids;
  std::vector<float> confidences;
	
  // 這里是利用多線程,加速獲得目標(biāo)框,實(shí)際上,這部分的多線程,僅加速2-3ms。
  // 可以利用cv::setNumThreads(1);指定線程數(shù)
  std::mutex mtx;
  cv::parallel_for_(cv::Range(0, rows), [&](const cv::Range& range)
  {
    for (int r = range.start; r < range.end; r++) //
    {
	  float *usage_data = data + r * (classnum + 5);
      float confidence = usage_data[4];
      if (confidence >= thre_cof)
      {
        float *classes_scores  = usage_data + 5;
        cv::Mat scores(1, classnum, CV_32FC1, classes_scores);
        cv::Point class_id;
        double max_class_score;
        cv::minMaxLoc(scores, 0, &max_class_score, 0, &class_id);
        if (max_class_score > thre_score)
        {
          float x = usage_data[0], y = usage_data[1], w = usage_data[2], h = usage_data[3];
          int left = int((x - 0.5 * w) * x_factor);
          int top = int((y - 0.5 * h) * y_factor);
          int width = int(w * x_factor);
          int height = int(h * y_factor);

          mtx.lock();
          confidences.push_back(confidence);
          class_ids.push_back(class_id.x);
          boxes.push_back(cv::Rect(left, top, width, height));
          mtx.unlock();
        }
      }
    }
  });
  
  std::vector<int> nms_result;
  cv::dnn::NMSBoxes(boxes, confidences, thre_score, thre_nms, nms_result);

  *_detected_num = nms_result.size();
  *_classids = new signed int[*_detected_num];
  *_confidences = new float[*_detected_num];
  *_boxes = new signed int[*_detected_num * 4];
  for(int i = 0; i < *_detected_num; i++)
  {
    int idx = nms_result[i];
    (*_classids)[i] = class_ids[idx];
    (*_confidences)[i] = confidences[idx];
    (*_boxes)[i * 4] = boxes[idx].x;
    (*_boxes)[i * 4 + 1] = boxes[idx].y;
    (*_boxes)[i * 4 + 2] = boxes[idx].width;
    (*_boxes)[i * 4 + 3] = boxes[idx].height;
  }
}

void free_postprocess_yolov5(signed int **_classids, float **_confidences, signed int **_boxes)
{
  if (*_classids)
  {
    delete[] *_classids;
    *_classids = nullptr;
  }
  if (*_confidences)
  {
    delete[] *_confidences;
    *_confidences = nullptr;
  }
  if (*_boxes)
  {
    delete[] *_boxes;
    *_boxes = nullptr;
  }
}

3.3.2 寫Cython所需的Pyx文件

同級(jí)目錄下創(chuàng)建pyyolotools.pyx,切記文件名不要跟某個(gè)CPP重復(fù)了,因?yàn)閏ython會(huì)將pyyolotools.pyx轉(zhuǎn)為pyyolotools.cpp,如果有重復(fù)的話可能會(huì)導(dǎo)致文件被覆蓋掉。

import numpy as np
cimport numpy as np
from libc.string cimport memcpy

# 函數(shù)聲明
cdef extern from "yolotools.h":
    void postprocess_yolov5(float*, int, 
                            int, int, 
                            float, float, 
                            float, float, float,
                            int*, signed int**, float**, signed int**)
    void free_postprocess_yolov5(signed int**, float**, signed int**)

# 定義Python函數(shù),主要補(bǔ)充的就是將python數(shù)據(jù)轉(zhuǎn)換為C++指針,然后利用計(jì)算出的結(jié)果再轉(zhuǎn)換回去
def pypostprocess_yolov5(np.ndarray[np.float32_t, ndim=2] yolov5output, 
                        float fx, float fy,
                        float thre_cof, float thre_score, float thre_nms):
    cdef int rows = yolov5output.shape[0]
    cdef int dimensions = yolov5output.shape[1]
    
    cdef int classnum = dimensions - 5
    assert classnum > 5

    cdef int datanum = rows * dimensions

    cdef int detected_num = 0
    cdef signed int *pclassids
    cdef float *pconfidences
    cdef signed int *pboxes
    postprocess_yolov5(&yolov5output[0, 0], datanum,
                       rows, classnum, fx, fy, 
                       thre_cof, thre_score, thre_nms,
                       &detected_num, &pclassids, &pconfidences, &pboxes)
    if detected_num == 0:
        return None
    
    cdef np.ndarray[np.int32_t, ndim=1] classids = np.zeros((detected_num, ), dtype = np.int32)
    cdef np.ndarray[np.float32_t, ndim=1] confidence = np.zeros((detected_num, ), dtype = np.float32)
    cdef np.ndarray[np.int32_t, ndim=2] boxes = np.zeros((detected_num, 4), dtype = np.int32)

    memcpy(&classids[0], pclassids, sizeof(int) * detected_num)
    memcpy(&confidence[0], pconfidences, sizeof(float) * detected_num)
    memcpy(&boxes[0, 0], pboxes, sizeof(int) * detected_num * 4)

    free_postprocess_yolov5(&pclassids, &pconfidences, &pboxes);
    return (classids, confidence, boxes)

3.3.3 寫編譯Pyx所需的python代碼

創(chuàng)建setup.py文件,將下面代碼放進(jìn)去,配置好opencv的頭文件目錄、庫目錄、以及所需的庫文件。
Extension中配置封裝的函數(shù)所依賴的文件,然后在控制臺(tái)輸入python3 setup.py build_ext --inplace即可。

from setuptools import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np

opencv_include = '/usr/include/opencv4/'
opencv_lib_dirs = "/usr/lib/aarch64-linux-gnu/"
opencv_libs = ['opencv_core', 'opencv_highgui', 'opencv_imgproc', 'opencv_imgcodecs', 'opencv_dnn']

print('opencv_include: ', opencv_include)
print('opencv_lib_dirs: ', opencv_lib_dirs)
print('opencv_libs: ', opencv_libs)

# python3 setup.py build_ext --inplace

class custom_build_ext(build_ext):
    def build_extensions(self):
        build_ext.build_extensions(self)

# Obtain the numpy include directory.  This logic works across numpy versions.
try:
    numpy_include = np.get_include()
except AttributeError:
    numpy_include = np.get_numpy_include()


ext_modules = [
    Extension(
        "lib.pyyolotools",
        ["./yolov5postprocess.cpp",
         "./pyyolotools.pyx",],
        include_dirs = [numpy_include, opencv_include],
        language='c++',
        libraries=opencv_libs,
        library_dirs=[opencv_lib_dirs]
        ),
    ]

setup(
    name='pyyolotools',
    ext_modules=ext_modules,
    cmdclass={'build_ext': custom_build_ext},
)

print('Build done')

四 總結(jié)

上一個(gè)部署教程,主要是介紹如何利用Caffe來部署模型,這個(gè)部分,就是利用ONNX來部署。后續(xù)如果自己基于這個(gè)代碼進(jìn)行修改的話,也可以按照這個(gè)教程對(duì)自己的模型進(jìn)行量化上板。

此外,X3派作為個(gè)嵌入式板子,學(xué)會(huì)開發(fā)C++是非常重要的。但我個(gè)人認(rèn)為所有的任務(wù)都是C++是不現(xiàn)實(shí)的,我們可以利用Python高效完成項(xiàng)目開發(fā),對(duì)其中耗時(shí)較高的,封裝C++即可。

PS:各位千萬不要被推理耗時(shí)嚇到了,感覺耗時(shí)太高了,因?yàn)檫@個(gè)版本的模型轉(zhuǎn)換時(shí)候,后面一堆層是跑在CPU上的,各位在設(shè)計(jì)自己的網(wǎng)絡(luò)的時(shí)候也要注意下哈。文章來源地址http://www.zghlxwxcb.cn/news/detail-619039.html

到了這里,關(guān)于[BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • YOLOv5原理分析及部署教程

    YOLOv5原理分析及部署教程

    本文是nano自動(dòng)駕駛小車開發(fā)系列中關(guān)于環(huán)境感知部分的分享,介紹目標(biāo)檢測(cè)中的yolo算法。 我分別使用了OAK-D-Lite和普通USB攝像頭這兩種硬件在windows10下實(shí)現(xiàn)了yolov 5的復(fù)現(xiàn)。如果使用OAK的話,需要首先配置好OAK-SDK再使用。 ??????? ? 硬件:OAK-D-Lite、普通USB攝像頭 軟件

    2024年02月03日
    瀏覽(24)
  • 2021.11.01 c++下 opencv部署yolov5-6.0版本 (四)

    2021.11.01 c++下 opencv部署yolov5-6.0版本 (四)

    ----2022.10.10 更新yolov5-seg實(shí)例分割模型: 2022.09.29更新 c++下面使用opencv部署yolov5和yolov7實(shí)例分割模型(六)_愛晚乏客游的博客-CSDN博客 ?-----2022.07.25 更新了下yolov7的部署,有需要的自取 2022.07.25 C++下使用opencv部署yolov7模型(五)_愛晚乏客游的博客-CSDN博客 此篇文章針對(duì)yolov5的

    2024年02月04日
    瀏覽(26)
  • 【2023-Pytorch-檢測(cè)教程】手把手教你使用YOLOV5做電線絕緣子缺陷檢測(cè)

    【2023-Pytorch-檢測(cè)教程】手把手教你使用YOLOV5做電線絕緣子缺陷檢測(cè)

    隨著社會(huì)和經(jīng)濟(jì)的持續(xù)發(fā)展,電力系統(tǒng)的投資與建設(shè)也日益加速。在電力系統(tǒng)中,輸電線路作為電能傳輸?shù)妮d體,是最為關(guān)鍵的環(huán)節(jié)之一。而絕緣子作為輸電環(huán)節(jié)中的重要設(shè)備,在支撐固定導(dǎo)線,保障絕緣距離的方面有著重要作用。大多數(shù)高壓輸電線路主要架設(shè)在非城市內(nèi)地

    2023年04月11日
    瀏覽(19)
  • 【精選】OpenCV&YOLOv5的車流量統(tǒng)計(jì)系統(tǒng)(源碼&部署教程)

    【精選】OpenCV&YOLOv5的車流量統(tǒng)計(jì)系統(tǒng)(源碼&部署教程)

    隨著城市化進(jìn)程的加快和交通工具的普及,車輛數(shù)量的快速增長給城市交通管理帶來了巨大的挑戰(zhàn)。車流量檢測(cè)是交通管理的重要組成部分,它可以提供實(shí)時(shí)的交通狀況信息,幫助交通管理部門制定合理的交通策略,優(yōu)化交通流量,提高道路利用效率,減少交通擁堵和事故發(fā)

    2024年02月20日
    瀏覽(34)
  • YOLOV5-LITE實(shí)時(shí)目標(biāo)檢測(cè)(onnxruntime部署+opencv獲取攝像頭+NCNN部署)python版本和C++版本

    使用yolov5-lite自帶的export.py導(dǎo)出onnx格式,圖像大小設(shè)置320,batch 1 之后可以使用 onnxsim對(duì)模型進(jìn)一步簡化 onnxsim參考鏈接:onnxsim-讓導(dǎo)出的onnx模型更精簡_alex1801的博客-CSDN博客 這個(gè)版本的推理FPS能有11+FPS 這兩處換成自己的模型和訓(xùn)練的類別即可: ??? parser.add_argument(\\\'--modelpa

    2024年02月04日
    瀏覽(30)
  • 瑞芯微RK3568/RK3588平臺(tái)YOLOV5實(shí)時(shí)視頻算法的部署小白教程

    瑞芯微RK3568/RK3588平臺(tái)YOLOV5實(shí)時(shí)視頻算法的部署小白教程

    本文實(shí)現(xiàn)整體的部署流程比較小白,首先在PC上分別實(shí)現(xiàn)工程中的模型仿真推理、yolov5-pytorch仿真推理、自己訓(xùn)練yolov5模型仿真推理,完成仿真之后再在板端分別實(shí)現(xiàn)rk提供模型的板端推理、yolov5-pytorch板端推理、自己訓(xùn)練的yolov5模型板端推理,最后實(shí)現(xiàn)自己訓(xùn)練的yolov5模型實(shí)

    2024年02月06日
    瀏覽(221)
  • YOLOv5使用NCNN將模型部署到Android端教程(1)部署自己的訓(xùn)練模型到Android實(shí)現(xiàn)靜態(tài)圖片檢測(cè)

    YOLOv5使用NCNN將模型部署到Android端教程(1)部署自己的訓(xùn)練模型到Android實(shí)現(xiàn)靜態(tài)圖片檢測(cè)

    之前一直是在電腦端運(yùn)行YOLOv5,但在戶外調(diào)試的時(shí)候不太方便,因此考慮把YOLOv5的代碼移植到手機(jī)端。 這個(gè)部署的流程其實(shí)很簡單:原始pt權(quán)重中間onnx權(quán)重ncnn權(quán)重修改Android Studio源碼得到安卓APP結(jié)束。如果你感覺博客教程太長了,那么很有可能是中間的圖片太多,以及之前自

    2023年04月09日
    瀏覽(30)
  • 一文教你使用租賃的GPU平臺(tái)跑yolov5

    一文教你使用租賃的GPU平臺(tái)跑yolov5

    寫在前面 本篇文章是對(duì)筆者前幾天學(xué)習(xí)過程的一個(gè)記錄,鑒于這類文章較少,寫出來方便后來者。 本文側(cè)重于yolov5的快速使用,原理部分概括較少,希望你看完本文章后也能成功進(jìn)行目標(biāo)檢測(cè)。 GPU租賃平臺(tái):https://www.autodl.com/home yolov5官方代碼:https://github.com/ultralytics/yolo

    2024年02月05日
    瀏覽(69)
  • PyQt5 | 手把手教你YOLOv5添加PyQt頁面

    PyQt5 | 手把手教你YOLOv5添加PyQt頁面

    演示視頻:YOLOv5/v7添加 PyQT5 頁面 我的畢業(yè)有救了 !嗶哩嗶哩

    2024年02月01日
    瀏覽(21)
  • 手把手教你如何使用YOLOV5訓(xùn)練自己的數(shù)據(jù)集

    手把手教你如何使用YOLOV5訓(xùn)練自己的數(shù)據(jù)集

    YOLOV5是目前最火熱的目標(biāo)檢測(cè)算法之一。YOLOV5為一階段檢測(cè)算法因此它的速度非常之快??梢栽趶?fù)雜場景中達(dá)到60禎的實(shí)時(shí)檢測(cè)頻率。 接下來本文將詳細(xì)的講述如何使用YOLOV5去訓(xùn)練自己的數(shù)據(jù)集 YOLOV5中使用了Tensorboard和Wandb來可視化訓(xùn)練,其中Wandb配置可以看這篇文章: Wand

    2024年02月05日
    瀏覽(96)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包