使用OpenVINO完成PyTorch YOLOv5模型推理計算

下載并將YOLOv5模型轉(zhuǎn)換為onnx格式

YOLOv5 v6.1版本合并了輸出,更加容易解析輸出結(jié)果

參考https://docs.ultralytics.com/quick-start/艺糜,完成YOLOv5 開發(fā)環(huán)境搭建

使用命令將YOLOv5 Pytorch模型轉(zhuǎn)換為onnx模型:

python export.py --weights yolov5s.pt --include onnx

轉(zhuǎn)換結(jié)果
1647659625(1).png

遇到網(wǎng)絡(luò)原因瘟滨,無法從Github上下載YOLOv5權(quán)重時
網(wǎng)絡(luò)原因术幔,從Github上下載YOLOv5權(quán)重失敗

請copy yolov5權(quán)重下載鏈接,使用迅雷下載
使用訓(xùn)練解決下載YOLOv5權(quán)重問題

再次執(zhí)行Export命令君纫,成功!
轉(zhuǎn)換onnx模型成功

使用Netron查看yolov5s.onnx v6.1模型

yolov5s.onnx v6.1模型

可以看到:

  • 模型輸入節(jié)點,name:images; shape NCHW=[1,3,640,640]; type:float32
  • 模型輸出節(jié)點屠尊,name: output; shape [1,25200,85], type:float32

output整合了之前三層(v6.1之前版本是三個輸出節(jié)點)的原始輸出,每一行85個數(shù)值耕拷,前面5個數(shù)值分別是:

cx, cy, w, h, score 后面80個MSCOCO的分類得分

使用OpenCV DNN API完成推理

完整GitHub Repo 地址:https://gitee.com/ppov-nuc/yolov5_infer

import cv2
import numpy as np
import time
import yaml

# 載入COCO Label
with open('./coco.yaml','r', encoding='utf-8') as f:
    result = yaml.load(f.read(),Loader=yaml.FullLoader)
class_list = result['names']

# YOLOv5s輸入尺寸
INPUT_WIDTH = 640
INPUT_HEIGHT = 640

# 目標檢測函數(shù)讼昆,返回檢測結(jié)果
def detect(image, net):
    blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (INPUT_WIDTH, INPUT_HEIGHT), swapRB=True, crop=False)
    net.setInput(blob)
    preds = net.forward()
    return preds

# YOLOv5的后處理函數(shù),解析模型的輸出
def wrap_detection(input_image, output_data):
    class_ids = []
    confidences = []
    boxes = []
    #print(output_data.shape)
    rows = output_data.shape[0]

    image_width, image_height, _ = input_image.shape

    x_factor = image_width / INPUT_WIDTH
    y_factor = image_height / INPUT_HEIGHT

    for r in range(rows):
        row = output_data[r]
        confidence = row[4]
        if confidence >= 0.4:

            classes_scores = row[5:]
            _, _, _, max_indx = cv2.minMaxLoc(classes_scores)
            class_id = max_indx[1]
            if (classes_scores[class_id] > .25):
                confidences.append(confidence)

                class_ids.append(class_id)

                x, y, w, h = row[0].item(), row[1].item(), row[2].item(), row[3].item()
                left = int((x - 0.5 * w) * x_factor)
                top = int((y - 0.5 * h) * y_factor)
                width = int(w * x_factor)
                height = int(h * y_factor)
                box = np.array([left, top, width, height])
                boxes.append(box)

    indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.25, 0.45)

    result_class_ids = []
    result_confidences = []
    result_boxes = []

    for i in indexes:
        result_confidences.append(confidences[i])
        result_class_ids.append(class_ids[i])
        result_boxes.append(boxes[i])

    return result_class_ids, result_confidences, result_boxes

# 按照YOLOv5要求骚烧,先將圖像長:寬 = 1:1浸赫,多余部分填充黑邊
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


# 載入yolov5s.onnx模型
model_path = "./yolov5s.onnx"
# Read yolov5s.onnx model with OpenCV API
net = cv2.dnn.readNetFromONNX(model_path)

# 開啟Webcam,并設(shè)置為1280x720
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

# 調(diào)色板
colors = [(255, 255, 0), (0, 255, 0), (0, 255, 255), (255, 0, 0)]

# 開啟檢測循環(huán)
while True:
    start = time.time()
    _, frame = cap.read()
    if frame is None:
        print("End of stream")
        break
    # 將圖像按最大邊1:1放縮
    inputImage = format_yolov5(frame)
    # 執(zhí)行推理計算
    outs = detect(inputImage, net)
    # 拆解推理結(jié)果
    class_ids, confidences, boxes = wrap_detection(inputImage, outs[0])

    # 顯示檢測框bbox
    for (classid, confidence, box) in zip(class_ids, confidences, boxes):
        color = colors[int(classid) % len(colors)]
        cv2.rectangle(frame, box, color, 2)
        cv2.rectangle(frame, (box[0], box[1] - 20), (box[0] + box[2], box[1]), color, -1)
        cv2.putText(frame, class_list[classid], (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 0, 0))
    
    # 顯示推理速度FPS
    end = time.time()
    inf_end = end - start
    fps = 1 / inf_end
    fps_label = "FPS: %.2f" % fps
    cv2.putText(frame, fps_label, (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    print(fps_label+ "; Detections: " + str(len(class_ids)))
    cv2.imshow("output", frame)

    if cv2.waitKey(1) > -1:
        print("finished by user")
        break

使用OpenVINO API完成推理

import cv2
import numpy as np
import time
import yaml
from openvino.inference_engine import IECore # the version of openvino <= 2021.4.2

# 載入COCO Label
with open('./coco.yaml','r', encoding='utf-8') as f:
    result = yaml.load(f.read(),Loader=yaml.FullLoader)
class_list = result['names']

# YOLOv5s輸入尺寸
INPUT_WIDTH = 640
INPUT_HEIGHT = 640

# 目標檢測函數(shù)赃绊,返回檢測結(jié)果
def detect(image, net):
    blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (INPUT_WIDTH, INPUT_HEIGHT), swapRB=True, crop=False)
    result = net.infer({"images": blob})
    preds = result["output"]
    return preds

# YOLOv5的后處理函數(shù)既峡,解析模型的輸出
def wrap_detection(input_image, output_data):
    class_ids = []
    confidences = []
    boxes = []
    #print(output_data.shape)
    rows = output_data.shape[0]

    image_width, image_height, _ = input_image.shape

    x_factor = image_width / INPUT_WIDTH
    y_factor = image_height / INPUT_HEIGHT

    for r in range(rows):
        row = output_data[r]
        confidence = row[4]
        if confidence >= 0.4:

            classes_scores = row[5:]
            _, _, _, max_indx = cv2.minMaxLoc(classes_scores)
            class_id = max_indx[1]
            if (classes_scores[class_id] > .25):
                confidences.append(confidence)

                class_ids.append(class_id)

                x, y, w, h = row[0].item(), row[1].item(), row[2].item(), row[3].item()
                left = int((x - 0.5 * w) * x_factor)
                top = int((y - 0.5 * h) * y_factor)
                width = int(w * x_factor)
                height = int(h * y_factor)
                box = np.array([left, top, width, height])
                boxes.append(box)

    indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.25, 0.45)

    result_class_ids = []
    result_confidences = []
    result_boxes = []

    for i in indexes:
        result_confidences.append(confidences[i])
        result_class_ids.append(class_ids[i])
        result_boxes.append(boxes[i])

    return result_class_ids, result_confidences, result_boxes

# 按照YOLOv5要求,先將圖像長:寬 = 1:1碧查,多余部分填充黑邊
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


# 載入yolov5s onnx模型
model_path = "./yolov5s.onnx"
# Read yolov5s onnx model with OpenVINO API
ie = IECore()
exec_net = ie.load_network(network=model_path, device_name="CPU")

# 開啟Webcam运敢,并設(shè)置為1280x720
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

# 調(diào)色板
colors = [(255, 255, 0), (0, 255, 0), (0, 255, 255), (255, 0, 0)]

# 開啟檢測循環(huán)
while True:
    start = time.time()
    _, frame = cap.read()
    if frame is None:
        print("End of stream")
        break
    # 將圖像按最大邊1:1放縮
    inputImage = format_yolov5(frame)
    # 執(zhí)行推理計算
    outs = detect(inputImage, exec_net)
    # 拆解推理結(jié)果
    class_ids, confidences, boxes = wrap_detection(inputImage, outs[0])

    # 顯示檢測框bbox
    for (classid, confidence, box) in zip(class_ids, confidences, boxes):
        color = colors[int(classid) % len(colors)]
        cv2.rectangle(frame, box, color, 2)
        cv2.rectangle(frame, (box[0], box[1] - 20), (box[0] + box[2], box[1]), color, -1)
        cv2.putText(frame, class_list[classid], (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, .5, (0, 0, 0))
    
    # 顯示推理速度FPS
    end = time.time()
    inf_end = end - start
    fps = 1 / inf_end
    fps_label = "FPS: %.2f" % fps
    cv2.putText(frame, fps_label, (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    print(fps_label+ "; Detections: " + str(len(class_ids)))
    cv2.imshow("output", frame)

    if cv2.waitKey(1) > -1:
        print("finished by user")
        break

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市么夫,隨后出現(xiàn)的幾起案子者冤,更是在濱河造成了極大的恐慌,老刑警劉巖档痪,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涉枫,死亡現(xiàn)場離奇詭異,居然都是意外死亡腐螟,警方通過查閱死者的電腦和手機愿汰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乐纸,“玉大人衬廷,你說我怎么就攤上這事∑睿” “怎么了吗跋?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我跌宛,道長酗宋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任疆拘,我火速辦了婚禮蜕猫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哎迄。我一直安慰自己回右,他們只是感情好,可當我...
    茶點故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布漱挚。 她就那樣靜靜地躺著翔烁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棱烂。 梳的紋絲不亂的頭發(fā)上租漂,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天,我揣著相機與錄音颊糜,去河邊找鬼。 笑死秃踩,一個胖子當著我的面吹牛衬鱼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播憔杨,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼鸟赫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了消别?” 一聲冷哼從身側(cè)響起抛蚤,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寻狂,沒想到半個月后岁经,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蛇券,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年缀壤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纠亚。...
    茶點故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡塘慕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蒂胞,到底是詐尸還是另有隱情图呢,我是刑警寧澤,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布,位于F島的核電站蛤织,受9級特大地震影響赴叹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瞳筏,卻給世界環(huán)境...
    茶點故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一稚瘾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姚炕,春花似錦摊欠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掸刊,卻和暖如春免糕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背忧侧。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工石窑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蚓炬。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓松逊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肯夏。 傳聞我的和親對象是個殘疾皇子经宏,可洞房花燭夜當晚...
    茶點故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容