中海園林建設(shè)有限公司網(wǎng)站wordpress目錄索引插件
鶴壁市浩天電氣有限公司
2026/01/24 14:02:05
中海園林建設(shè)有限公司網(wǎng)站,wordpress目錄索引插件,網(wǎng)站制作大概需要多少錢,誠訊網(wǎng)站設(shè)計(jì)YOLOv5模型在Jetson設(shè)備上的TensorRT部署
在邊緣計(jì)算場景中#xff0c;如何讓一個(gè)訓(xùn)練好的目標(biāo)檢測模型真正“落地”運(yùn)行#xff0c;是每個(gè)AI工程師繞不開的課題。尤其是在 NVIDIA Jetson Nano、Xavier NX、Orin 這類資源受限但又需要實(shí)時(shí)響應(yīng)的嵌入式平臺(tái)上#xff0c;性能…YOLOv5模型在Jetson設(shè)備上的TensorRT部署在邊緣計(jì)算場景中如何讓一個(gè)訓(xùn)練好的目標(biāo)檢測模型真正“落地”運(yùn)行是每個(gè)AI工程師繞不開的課題。尤其是在NVIDIA Jetson Nano、Xavier NX、Orin這類資源受限但又需要實(shí)時(shí)響應(yīng)的嵌入式平臺(tái)上性能與功耗的平衡變得異常關(guān)鍵。YOLOYou Only Look Once系列模型因其速度快、精度高早已成為工業(yè)界首選的目標(biāo)檢測方案。雖然YOLOv5并非Ultralytics官方正式命名版本實(shí)為社區(qū)廣泛采用的實(shí)現(xiàn)但它憑借簡潔的代碼結(jié)構(gòu)、高效的訓(xùn)練流程和出色的推理表現(xiàn)迅速成為實(shí)際項(xiàng)目中最常用的框架之一。更令人振奮的是如今我們已擁有成熟的工具鏈支持從 PyTorch 模型導(dǎo)出到 TensorRT 引擎編譯再到 Jetson 上 C/Python 的端到端調(diào)用整個(gè)部署路徑已經(jīng)非常清晰。本文將以YOLOv5 在 Jetson 系列設(shè)備上通過 TensorRT 加速推理為主線手把手帶你完成從模型導(dǎo)出到實(shí)時(shí)視頻流處理的全流程并結(jié)合當(dāng)前流行的預(yù)裝開發(fā)鏡像進(jìn)行適配說明。環(huán)境準(zhǔn)備硬件選型與系統(tǒng)配置要跑通這套部署流程首先得有一塊能打的“板子”。推薦硬件平臺(tái)Jetson Nano (4GB)適合入門驗(yàn)證可運(yùn)行小尺寸YOLOv5s模型Jetson Xavier NX算力更強(qiáng)支持多路攝像頭或更高幀率Jetson Orin旗艦級(jí)性能輕松駕馭YOLOv5l/x甚至更大變體其他必備外設(shè)至少32GB TF卡建議64GB以上以避免空間不足5V/4A直流電源Nano必須跳線供電才能穩(wěn)定運(yùn)行散熱風(fēng)扇或金屬散熱片防止過熱降頻導(dǎo)致性能驟降USB無線網(wǎng)卡Nano無內(nèi)置Wi-Fi顯示器 鍵盤鼠標(biāo)用于初始系統(tǒng)配置?? 特別提醒不要試圖在虛擬機(jī)里完成最終部署CUDA 和 TensorRT 對(duì)底層驅(qū)動(dòng)高度依賴跨平臺(tái)模擬極易出現(xiàn)兼容性問題浪費(fèi)大量調(diào)試時(shí)間。軟件環(huán)境要求主流 Jetson 開發(fā)基于JetPack SDK它集成了 L4TLinux for Tegra、CUDA、cuDNN、TensorRT 等核心組件。推薦使用以下版本組合組件推薦版本JetPack5.1 或 5.0.2CUDA12.x / 11.4cuDNN9.xTensorRT8.6OpenCV4.5Python3.8 ~ 3.10你可以通過以下命令查看當(dāng)前系統(tǒng)的 L4T 版本信息sudo apt install lsb-release cat /etc/nv_tegra_release確認(rèn) JetPack 版本后再選擇對(duì)應(yīng)的依賴庫版本避免因版本錯(cuò)配導(dǎo)致構(gòu)建失敗。模型導(dǎo)出生成可用于 TensorRT 的中間文件YOLOv5 提供了export.py工具可以直接將.pt權(quán)重轉(zhuǎn)換為 ONNX、TorchScript 或原生的TensorRT Engine (.engine)文件。這里介紹兩種常用方式。方法一直接導(dǎo)出.engine文件推薦如果你是在具備完整 CUDA/TensorRT 環(huán)境的主機(jī)上操作比如帶 GPU 的 x86 PC可以一步到位生成優(yōu)化后的引擎文件。進(jìn)入 YOLOv5 項(xiàng)目目錄cd /root/ultralytics/yolov5執(zhí)行導(dǎo)出命令yolo export modelbest.pt formatengine imgsz640 device0參數(shù)說明model: 訓(xùn)練好的權(quán)重路徑如runs/train/exp/weights/best.ptformatengine: 輸出格式為 TensorRT 引擎imgsz640: 輸入圖像尺寸需為 32 的倍數(shù)device0: 使用 GPU 編譯引擎成功后會(huì)生成best.engine文件該文件已完成量化、層融合等優(yōu)化可直接拷貝至 Jetson 設(shè)備加載。? 優(yōu)勢無需手動(dòng)構(gòu)建插件省去復(fù)雜編譯步驟? 缺點(diǎn)必須在同一架構(gòu)aarch64且有 GPU 的環(huán)境下運(yùn)行否則無法生成有效引擎方法二生成.wts文件跨平臺(tái)通用方案若你在 x86 主機(jī)訓(xùn)練模型卻要在 aarch64 架構(gòu)的 Jetson 上部署則應(yīng)采用生成.wts文件 在 Jetson 上本地 build engine的方式。步驟 1生成.wts權(quán)重文件下載 tensorrtx 倉庫中的 YOLOv5 支持代碼git clone https://github.com/wang-xinyu/tensorrtx.git復(fù)制gen_wts.py到你的 YOLOv5 目錄下cp tensorrtx/yolov5/gen_wts.py yolov5/ cd yolov5 python3 gen_wts.py -w best.pt這會(huì)在當(dāng)前目錄生成best.wts文件其中包含所有層名與對(duì)應(yīng)權(quán)重便于后續(xù)在 Jetson 上重建網(wǎng)絡(luò)并插入?yún)?shù)。然后將其傳輸?shù)?Jetson 設(shè)備scp best.wts userjetson-ip:/home/user/tensorrtx/yolov5/Jetson 端部署構(gòu)建 TensorRT 引擎現(xiàn)在我們切換到 Jetson 設(shè)備開始真正的“本地化”構(gòu)建過程。安裝必要依賴確保已安裝基礎(chǔ)庫和 Python 包sudo apt update sudo apt install python3-pip libopencv-dev python3-opencv libssl-dev pip3 install pycuda numpy驗(yàn)證 TensorRT 是否可用import tensorrt as trt print(trt.__version__)如果沒有報(bào)錯(cuò)說明環(huán)境正常。編譯 YOLOv5-TensorRT 示例程序進(jìn)入tensorrtx/yolov5目錄cd ~/tensorrtx/yolov5修改類別數(shù)量與輸入尺寸打開yololayer.h文件調(diào)整以下宏定義#define CLASS_NUM 80 // 根據(jù)你的數(shù)據(jù)集類別數(shù)修改 #define INPUT_W 640 // 與訓(xùn)練時(shí)一致 #define INPUT_H 640例如如果你訓(xùn)練的是自定義四分類模型人、車、狗、貓則改為#define CLASS_NUM 4?? 務(wù)必保持與訓(xùn)練配置完全一致否則輸出解析將出錯(cuò)構(gòu)建工程mkdir build cd build cmake .. make -j$(nproc)如果提示找不到libmyplugins.so請先執(zhí)行一次-s參數(shù)來生成 engine 和插件庫sudo ./yolov5 -s ../best.wts best.engine s該命令含義如下# sudo ./yolov5 -s [.wts] [.engine] [model_type] # 示例 sudo ./yolov5 -s ../best.wts best.engine s支持的模型類型包括s,m,l,x,s6,m6,l6,x6也可使用自定義寬度/深度因子sudo ./yolov5 -s ../custom.wts custom.engine c 0.33 0.50其中c表示 custom0.33是 depth_multiple0.50是 width_multiple。構(gòu)建成功后你會(huì)得到兩個(gè)關(guān)鍵產(chǎn)物best.engine序列化的 TensorRT 推理引擎libmyplugins.so自定義插件庫含 YOLO 層實(shí)現(xiàn)這兩個(gè)文件將在后續(xù)推理中被同時(shí)加載。推理測試C 與 Python 雙模式調(diào)用C 測試圖片推理將待測圖片放入samples/文件夾cp ../data/images/bus.jpg samples/運(yùn)行推理sudo ./yolov5 -d best.engine ../samples結(jié)果圖片將保存為output*.jpg。若沒有檢測框輸出請檢查CONF_THRESH和NMS_THRESH是否設(shè)置過高默認(rèn) 0.5 和 0.4類別數(shù)是否匹配圖片路徑是否正確Python 調(diào)用更適合集成應(yīng)用為了方便后續(xù)接入 ROS、Flask API 或攝像頭流推薦使用 Python 調(diào)用引擎。編輯yolov5_trt.py文件進(jìn)行以下關(guān)鍵修改1禁用 Torch 相關(guān)模塊注釋掉對(duì)torch和torchvision的引用避免在 Jetson 上額外安裝這些重型包# import torch # import torchvision2統(tǒng)一輸入尺寸確保與訓(xùn)練和導(dǎo)出時(shí)一致INPUT_W 640 INPUT_H 6403替換 NMS 實(shí)現(xiàn)為 NumPy 版本刪除對(duì)torchvision.ops.nms的調(diào)用改用純 NumPy 實(shí)現(xiàn)的非極大值抑制函數(shù)def nms(self, boxes, scores, iou_threshold0.4): x1 boxes[:, 0] y1 boxes[:, 1] x2 boxes[:, 2] y2 boxes[:, 3] areas (x2 - x1 1) * (y2 - y1 1) order scores.argsort()[::-1] keep [] while order.size 0: i order[0] keep.append(i) xx1 np.maximum(x1[i], x1[order[1:]]) yy1 np.maximum(y1[i], y1[order[1:]]) xx2 np.minimum(x2[i], x2[order[1:]]) yy2 np.minimum(y2[i], y2[order[1:]]) w np.maximum(0.0, xx2 - xx1 1) h np.maximum(0.0, yy2 - yy1 1) inter w * h ovr inter / (areas[i] areas[order[1:]] - inter) inds np.where(ovr iou_threshold)[0] order order[inds 1] return keep并在post_process中調(diào)用它indices self.nms(boxes, scores, IOU_THRESHOLD) result_boxes boxes[indices] result_scores scores[indices] result_classid classid[indices]4設(shè)置自定義類別標(biāo)簽CLASSES [person, bicycle, car, motorcycle] # 替換為你自己的類別完整 Python 推理腳本示例import cv2 import numpy as np import time import ctypes import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit # 加載自定義插件庫 PLUGIN_LIBRARY libmyplugins.so ctypes.CDLL(PLUGIN_LIBRARY) # 參數(shù)設(shè)置 ENGINE_PATH best.engine IMAGE_PATH samples/bus.jpg INPUT_W, INPUT_H 640, 640 CONF_THRESH 0.4 IOU_THRESHOLD 0.5 CLASSES [person, bicycle, car, motorcycle] class YOLOv5TRT: def __init__(self, engine_path): self.logger trt.Logger(trt.Logger.INFO) with open(engine_path, rb) as f: runtime trt.Runtime(self.logger) self.engine runtime.deserialize_cuda_engine(f.read()) self.context self.engine.create_execution_context() self.stream cuda.Stream() # 分配內(nèi)存緩沖區(qū) self.host_inputs [] self.cuda_inputs [] self.host_outputs [] self.cuda_outputs [] for binding in self.engine: size trt.volume(self.engine.get_binding_shape(binding)) * self.engine.max_batch_size dtype trt.nptype(self.engine.get_binding_dtype(binding)) host_mem cuda.pagelocked_empty(size, dtype) cuda_mem cuda.mem_alloc(host_mem.nbytes) if self.engine.binding_is_input(binding): self.host_inputs.append(host_mem) self.cuda_inputs.append(cuda_mem) else: self.host_outputs.append(host_mem) self.cuda_outputs.append(cuda_mem) def infer(self, image): # 預(yù)處理BGR → RGB → resize → transpose → normalize input_image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) input_image cv2.resize(input_image, (INPUT_W, INPUT_H)) input_image np.transpose(input_image, (2, 0, 1)).astype(np.float32) / 255.0 input_image np.ascontiguousarray(input_image) np.copyto(self.host_inputs[0], input_image.ravel()) # Host to Device cuda.memcpy_htod_async(self.cuda_inputs[0], self.host_inputs[0], self.stream) # 執(zhí)行異步推理 self.context.execute_async_v2( bindings[int(d) for d in self.cuda_inputs self.cuda_outputs], stream_handleself.stream.handle ) # Device to Host cuda.memcpy_dtoh_async(self.host_outputs[0], self.cuda_outputs[0], self.stream) self.stream.synchronize() output self.host_outputs[0] num_dets int(output[0]) det_data output[1:].reshape(-1, 6)[:num_dets] boxes det_data[:, :4] scores det_data[:, 4] class_ids det_data[:, 5].astype(int) # 置信度過濾 conf_mask scores CONF_THRESH boxes boxes[conf_mask] scores scores[conf_mask] class_ids class_ids[conf_mask] # 坐標(biāo)還原到原始圖像尺度 scale_x image.shape[1] / INPUT_W scale_y image.shape[0] / INPUT_H boxes[:, 0::2] * scale_x boxes[:, 1::2] * scale_y # NMS 后處理 indices self.nms(boxes, scores, IOU_THRESHOLD) return boxes[indices], scores[indices], class_ids[indices] staticmethod def nms(boxes, scores, threshold): x1 boxes[:, 0]; y1 boxes[:, 1]; x2 boxes[:, 2]; y2 boxes[:, 3] areas (x2 - x1 1) * (y2 - y1 1) order scores.argsort()[::-1] keep [] while order.size 0: i order[0] keep.append(i) xx1 np.maximum(x1[i], x1[order[1:]]) yy1 np.maximum(y1[i], y1[order[1:]]) xx2 np.minimum(x2[i], x2[order[1:]]) yy2 np.minimum(y2[i], y2[order[1:]]) w np.maximum(0.0, xx2 - xx1 1) h np.maximum(0.0, yy2 - yy1 1) inter w * h ovr inter / (areas[i] areas[order[1:]] - inter) inds np.where(ovr threshold)[0] order order[inds 1] return keep # 繪圖函數(shù) def draw_boxes(img, boxes, scores, class_ids, class_names): for i in range(len(boxes)): x1, y1, x2, y2 map(int, boxes[i]) label f{class_names[class_ids[i]]}: {scores[i]:.2f} color (0, 255, 0) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) return img # 主函數(shù) if __name__ __main__: detector YOLOv5TRT(ENGINE_PATH) image cv2.imread(IMAGE_PATH) start time.time() boxes, scores, class_ids detector.infer(image) print(fInference time: {(time.time() - start)*1000:.2f} ms) result_img draw_boxes(image, boxes, scores, class_ids, CLASSES) cv2.imwrite(result_detection.jpg, result_img) print(Detection result saved to result_detection.jpg)運(yùn)行后即可看到帶有檢測框的結(jié)果圖。視頻與攝像頭實(shí)時(shí)推理只需稍作擴(kuò)展就能實(shí)現(xiàn)視頻或攝像頭實(shí)時(shí)檢測。視頻文件推理def detect_video(video_path): cap cv2.VideoCapture(video_path) out cv2.VideoWriter( output.avi, cv2.VideoWriter_fourcc(*MJPG), 30, (int(cap.get(3)), int(cap.get(4))) ) while cap.isOpened(): ret, frame cap.read() if not ret: break boxes, scores, class_ids detector.infer(frame) result_frame draw_boxes(frame, boxes, scores, class_ids, CLASSES) out.write(result_frame) cv2.imshow(YOLOv5-TensorRT, result_frame) if cv2.waitKey(1) ord(q): break cap.release() out.release() cv2.destroyAllWindows()CSI 攝像頭支持Jetson 原生對(duì)于 Jetson 原生 CSI 攝像頭如 Raspberry Pi Camera V2可通過jetcam庫直接訪問from jetcam.csi_camera import CSICamera camera CSICamera(width640, height480, capture_fps30) while True: frame camera.read() boxes, scores, class_ids detector.infer(frame) result_frame draw_boxes(frame, boxes, scores, class_ids, CLASSES) cv2.imshow(CSI Camera, result_frame) if cv2.waitKey(1) ord(q): break cv2.destroyAllWindows()這種方式延遲低、穩(wěn)定性好非常適合做邊緣 AI 產(chǎn)品原型。關(guān)于 YOLO-V8 鏡像的特別說明盡管本文聚焦于 YOLOv5但現(xiàn)實(shí)中很多開發(fā)者使用的是預(yù)裝好的YOLO-V8 開發(fā)鏡像—— 這類鏡像通?;?Docker 或 SD 卡燒錄形式分發(fā)特點(diǎn)包括預(yù)裝 PyTorch、Ultralytics、OpenCV、TensorRT提供 Jupyter Notebook 開發(fā)界面內(nèi)置ultralytics項(xiàng)目目錄支持一鍵訓(xùn)練與導(dǎo)出你可以在其中直接運(yùn)行 YOLOv5 的訓(xùn)練與導(dǎo)出任務(wù)cd /root/ultralytics yolo taskdetect modetrain modelyolov5s.yaml datacoco.yaml epochs100 imgsz640 yolo export modelruns/detect/train/weights/best.pt formatengine再將生成的.engine或.wts文件拷出用于 Jetson 部署。這類鏡像大大降低了環(huán)境配置門檻尤其適合新手快速上手。不過要注意其內(nèi)部 Python 環(huán)境可能與標(biāo)準(zhǔn) JetPack 存在差異在部署時(shí)仍需驗(yàn)證 TensorRT 兼容性。整個(gè)流程走下來你會(huì)發(fā)現(xiàn)雖然涉及不少底層細(xì)節(jié)——比如插件編譯、內(nèi)存管理、NMS 實(shí)現(xiàn)等——但一旦打通就能在 Jetson 上實(shí)現(xiàn)10~30 FPS 的實(shí)時(shí)檢測能力足以支撐大多數(shù)智能安防、機(jī)器人導(dǎo)航、工業(yè)質(zhì)檢等邊緣 AI 場景。更重要的是這種“訓(xùn)練-導(dǎo)出-部署”的標(biāo)準(zhǔn)化路徑也為后續(xù)升級(jí)到 YOLOv8、打包成 Flask API 或集成進(jìn) ROS 節(jié)點(diǎn)打下了堅(jiān)實(shí)基礎(chǔ)。下一步不妨嘗試把模型封裝成 REST 接口或是加入跟蹤算法實(shí)現(xiàn)多目標(biāo)追蹤你會(huì)發(fā)現(xiàn)真正的 AI 落地之旅才剛剛開始。