
簡介本資源面向計算機視覺開發(fā)者與視頻監(jiān)控、智能交通、工業(yè)自動化方向的工程人員提供一套可直接運行的YOLOv8實時RTSP流目標檢測項目源碼。資源包共467個文件約169.25MB以145個py源碼與215個pyc編譯文件為主體輔以80個yaml模型配置、6個pt權(quán)重文件并包含少量jpg測試圖、sh啟動腳本、js/css/html前端頁面及mp4演示視頻覆蓋從模型推理到可視化展示的完整鏈路。項目圍繞RTSP視頻流獲取、幀預(yù)處理、YOLOv8推理、檢測結(jié)果處理與前端反饋等環(huán)節(jié)組織代碼并借助yoloapi-camera等工具包簡化集成便于讀者理解實時目標檢測的工程化落地方式。目前已有220人學(xué)習下載適合希望將YOLOv8部署到實際視頻流場景、需要參考完整目錄結(jié)構(gòu)與推理流程的中高級開發(fā)者。1. 從一條 RTSP 流到 YOLOv8 檢測框這套方案到底能解決什么很多做視頻分析的團隊都遇到過同一個尷尬攝像頭就在那兒RTSP 地址也拿到了可要把「實時畫面」變成「帶框的結(jié)構(gòu)化結(jié)果」中間那一段總是拼不起來。要么是 OpenCV 拉流卡成幻燈片要么是檢測框和畫面不同步要么是跑一晚上進程就悄悄掛了。這套「YOLOv8 基于 RTSP 流目標檢測」的方案解決的就是這條鏈路——把網(wǎng)絡(luò)攝像頭的 RTSP 視頻流穩(wěn)定拉下來逐幀喂給 YOLOv8再把檢測結(jié)果實時畫回畫面或推給下游業(yè)務(wù)。它適合三類人一是做安防、園區(qū)、工地視頻分析的工程師手里有???、大華這類網(wǎng)絡(luò)攝像頭二是想把 YOLOv8 從「跑單張圖」推進到「跑實時流」的算法同學(xué)三是需要在 RK3588、GTX1660Ti 這類邊緣或入門顯卡上落地檢測的部署人員。核心關(guān)鍵詞就三個YOLOv8、RTSP、目標檢測。下面按「資源是什么 → 怎么用 → 坑在哪」的順序拆開講每一步都能照著復(fù)現(xiàn)。2. RTSP 拉流與 YOLOv8 推理的銜接先搞懂數(shù)據(jù)怎么流動2.1 為什么不能直接 cv2.VideoCapture 一把梭新手最常見的寫法是cv2.VideoCapture(rtsp://...)然后循環(huán)read()。單機測試能跑一上生產(chǎn)就翻車。原因在于 RTSP 底層是 RTP 傳輸默認走 UDP網(wǎng)絡(luò)一抖動就丟包OpenCV 的 FFmpeg 后端會把丟的幀攢在緩沖區(qū)里于是你看到的畫面越來越滯后最后延遲能到十幾秒。更麻煩的是read()返回 False 時很多人直接 break進程就退了可攝像頭其實只是瞬斷了一下。常見做法是把 RTSP 傳輸層強制切成 TCP。TCP 有重傳延遲可控代價是帶寬略高、首幀稍慢但對檢測場景完全值得。設(shè)置方式是在 URL 后面拼參數(shù)或者通過環(huán)境變量指定 FFmpeg 的傳輸協(xié)議。這一步不做后面所有優(yōu)化都是白搭。2.2 拉流、推理、渲染三段解耦把整條鏈路拆成三個獨立環(huán)節(jié)是讓它穩(wěn)定的關(guān)鍵。拉流線程只負責從 RTSP 取最新幀放進一個「只保留最新一幀」的隊列推理線程從隊列取幀跑 YOLOv8渲染/輸出線程負責畫框和推流。這樣即使推理慢也不會拖累拉流隊列里永遠是最新畫面不會累積延遲。import cv2 import threading import queue from ultralytics import YOLO # 只保留最新幀的隊列maxsize1 是關(guān)鍵 frame_queue queue.Queue(maxsize1) stop_flag threading.Event() def rtsp_reader(rtsp_url): # 強制 TCP 傳輸避免 UDP 丟包導(dǎo)致的延遲累積 cap cv2.VideoCapture(rtsp_url, cv2.CAP_FFMPEG) cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 減小內(nèi)部緩沖 while not stop_flag.is_set(): ret, frame cap.read() if not ret: # 不要 break重連即可 cap.release() cap cv2.VideoCapture(rtsp_url, cv2.CAP_FFMPEG) continue if frame_queue.full(): try: frame_queue.get_nowait() # 丟掉舊幀 except queue.Empty: pass frame_queue.put(frame) cap.release()這段代碼里三個參數(shù)值得說清楚。cv2.CAP_FFMPEG顯式指定后端避免 OpenCV 選到不支持的實現(xiàn)CAP_PROP_BUFFERSIZE1把 OpenCV 內(nèi)部緩沖壓到最小這是降延遲的關(guān)鍵maxsize1的隊列配合「滿了就丟舊幀」的邏輯保證推理端拿到的永遠是最新畫面。斷流時重建VideoCapture而不是退出是長時間運行的必要處理。2.3 YOLOv8 推理線程與模型加載推理線程單獨起模型只加載一次。YOLOv8 用 ultralytics 庫YOLO(yolov8n.pt)這種寫法會自動下載預(yù)訓(xùn)練權(quán)重。生產(chǎn)環(huán)境建議提前把權(quán)重下好放本地避免每次啟動都聯(lián)網(wǎng)。推理時用streamTrue或者直接對單幀predict注意verboseFalse關(guān)掉日志刷屏。def inference_worker(model_path, conf_thres0.4): model YOLO(model_path) # 權(quán)重提前放本地 while not stop_flag.is_set(): try: frame frame_queue.get(timeout1) except queue.Empty: continue # 單幀推理conf 控制置信度閾值 results model.predict(frame, confconf_thres, verboseFalse) annotated results[0].plot() # 直接畫出檢測框 cv2.imshow(YOLOv8-RTSP, annotated) if cv2.waitKey(1) 0xFF ord(q): stop_flag.set() breakconf0.4是置信度閾值太低會滿屏誤檢太高會漏掉小目標實際按場景調(diào)。results[0].plot()返回帶框的 numpy 數(shù)組直接能顯示或推流。verboseFalse關(guān)掉每幀的推理日志否則控制臺會被刷爆。模型選型上yolov8n最快適合邊緣設(shè)備yolov8s/m精度更高但吃顯存GTX1660Ti 跑yolov8s基本能到實時。3. 把 RTSP 地址配對、把模型跑起來參數(shù)與配置實操3.1 ??怠⒋笕A攝像頭的 RTSP 地址格式RTSP 地址拼錯是最高頻的翻車點。??档母袷绞莚tsp://用戶名:密碼IP:554/Streaming/Channels/101其中101表示通道 1 的主碼流102是子碼流。大華是rtsp://用戶名:密碼IP:554/cam/realmonitor?channel1subtype0subtype0主碼流1子碼流。做檢測建議用子碼流分辨率低、碼率小推理壓力小檢測框坐標再按比例映射回主碼流即可。品牌主碼流地址子碼流地址???Streaming/Channels/101/Streaming/Channels/102大華subtype0subtype1密碼里如果有或:這類特殊字符必須做 URL 編碼否則地址解析會出錯這個坑很多人踩過。測試階段可以先用 VLC 或 ffplay 驗證地址通不通ffplay -rtsp_transport tcp rtsp://...能出畫面再往代碼里塞。3.2 環(huán)境搭建與依賴版本ultralytics 對 PyTorch 版本有要求裝錯版本會報各種玄學(xué)錯誤。穩(wěn)妥的做法是先裝對應(yīng) CUDA 的 PyTorch再裝 ultralytics。CPU 也能跑但 RTSP 實時檢測基本離不開 GPU。# 先按顯卡 CUDA 版本裝 PyTorch這里以 CUDA 11.8 為例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 再裝 ultralytics 和 opencv pip install ultralytics opencv-python # 驗證 GPU 是否可用 python -c import torch; print(torch.cuda.is_available())最后一行必須打印True如果是False說明 PyTorch 裝成了 CPU 版推理會慢到?jīng)]法用。opencv-python用默認版即可它自帶 FFmpeg 后端能解 RTSP。如果要用 GStreamer 硬解得裝opencv-python的定制版普通場景沒必要。3.3 分辨率、幀率與跳幀策略攝像頭主碼流常見 1920×108025fps子碼流 704×57625fps。YOLOv8 推理時會把輸入縮放到 640所以喂進去的幀分辨率再高也不會提升精度反而浪費解碼算力。用子碼流是性價比最高的選擇。如果推理速度跟不上 25fps不要硬扛主動跳幀——每 2 幀或 3 幀推理一次中間幀復(fù)用上一次的檢測框視覺上幾乎看不出差別但負載直接減半。frame_count 0 last_results None while True: frame_count 1 if frame_count % 2 ! 0: # 奇數(shù)幀跳過推理 if last_results is not None: annotated last_results[0].plot() continue results model.predict(frame, conf0.4, verboseFalse) last_results results跳幀的代價是快速移動目標可能出現(xiàn)框「拖影」但對大多數(shù)安防場景夠用。判斷能不能跳幀的標準很簡單看你的業(yè)務(wù)對延遲和漏檢的容忍度寧可跳幀也別讓隊列堆積。4. 避坑與排查RTSP YOLOv8 最常見的五個翻車現(xiàn)場4.1 畫面延遲越跑越大現(xiàn)象是剛啟動正常跑幾分鐘后畫面比實時慢十幾秒。原因是 UDP 丟包后 FFmpeg 緩沖累積加上隊列沒做「丟舊幀」。解決分兩步RTSP 傳輸強制 TCP隊列設(shè)maxsize1并在滿時丟棄舊幀。這兩條一起做延遲能穩(wěn)定在 1 秒內(nèi)。4.2 進程跑幾小時就退出現(xiàn)象是無人值守時進程莫名消失。多數(shù)是cap.read()返回 False 后代碼 break 了或者異常沒捕獲。解決是把拉流放在獨立線程斷流時重建VideoCapture而不是退出外層再套一層 try/except 兜底。長時間運行還要定期檢查線程存活掛了就重啟。4.3 檢測框和畫面錯位現(xiàn)象是框畫在了錯誤位置。常見于用了子碼流推理、卻把框畫在主碼流上兩者分辨率不一致。解決是記錄推理幀的寬高畫框前按比例縮放坐標或者干脆推理和顯示用同一路流。另一個原因是plot()返回的圖和你顯示的窗口尺寸不匹配imshow前統(tǒng)一 resize。4.4 GPU 顯存越用越多直到 OOM現(xiàn)象是跑一段時間報 CUDA out of memory。原因是每幀predict產(chǎn)生的中間張量沒及時釋放或者results被長期持有。解決是不要在循環(huán)外保存results對象跳幀復(fù)用時只存plot()后的 numpy 圖不存整個 Results。必要時每隔一段時間torch.cuda.empty_cache()。4.5 置信度閾值調(diào)不對現(xiàn)象是漏檢或誤檢嚴重。conf默認 0.25 偏低安防場景一般 0.4~0.5。但閾值不是越高越好小目標本身置信度就低調(diào)太高直接漏掉。正確做法是先用一段錄像離線跑畫出不同conf下的漏檢/誤檢曲線再定閾值。別在實時流上憑感覺調(diào)那是血淚經(jīng)驗。5. 進階多路 RTSP 并發(fā)與邊緣部署的取舍單路跑通之后真正的考驗是多路。一臺 GTX1660Ti 跑yolov8n單路 1080p 能到 60fps 以上理論上能帶 4~6 路但實際受解碼和內(nèi)存帶寬限制穩(wěn)妥是 3~4 路。多路的核心是「一路一線程 共享模型」模型只加載一次多個推理線程共用但要注意 PyTorch 的線程安全和顯存競爭常見做法是加鎖或者用批處理把多路幀拼成一個 batch 一起推理。# 多路幀拼 batch 推理提升 GPU 利用率 frames [q.get() for q in frame_queues] # 每路取一幀 results model.predict(frames, conf0.4, verboseFalse) # 一次推理多幀 for i, r in enumerate(results): frame_queues_out[i].put(r.plot())批處理能把 GPU 利用率拉滿但會引入「最慢一路拖累所有路」的問題某路卡頓會讓整個 batch 等待。折中方案是設(shè)超時湊不齊就先用現(xiàn)有的幀推理。邊緣設(shè)備如 RK3588 部署 YOLOv8思路完全不同——要用 RKNN 工具鏈把模型轉(zhuǎn)成 NPU 能跑的格式RTSP 解碼走硬件 MPP這套流程和 GPU 版差異很大別指望一套代碼通吃。驗證部署是否達標我一般看三個指標端到端延遲從攝像頭到畫框、單路幀率、連續(xù)運行 24 小時的進程存活率。延遲用打時間戳的方式測幀率用cv2.getTickCount統(tǒng)計存活率就掛個日志看有沒有斷。從那以后我每次上線前都強制跑一遍 24 小時壓測寧可上線前多等一天也不想半夜被叫起來重啟進程。希望幫到你。本文還有配套的精品資源點擊獲取