戰(zhàn))
簡介面向煤礦智能化巡檢場景這份資源提供基于YOLOv8的傳送帶矸石與錨桿異物檢測方案包含3000多張已標(biāo)注圖像、訓(xùn)練好的模型權(quán)重和PyQt可視化界面適合算法工程師、礦山信息化人員直接部署或二次訓(xùn)練。數(shù)據(jù)集已劃分train/val/test并配好data.yaml標(biāo)簽與YOLO系列訓(xùn)練要求一致v5、v7、v8、v9等算法均可直接調(diào)用附帶的環(huán)境配置與運(yùn)行步驟PDF能幫助新手快速跑通檢測流程。資源包共2000個文件以1991個XML標(biāo)注文件為主體另有4個Markdown說明、3個PDF教程和2個Python界面腳本整體323.4MB目錄結(jié)構(gòu)清晰便于按模塊查閱。已有235人學(xué)習(xí)下載無論是做煤礦異物檢測課題驗(yàn)證還是落地皮帶運(yùn)輸場景的實(shí)時告警這套數(shù)據(jù)與代碼都能有效縮短從模型訓(xùn)練到界面演示的周期。1. 煤礦傳送帶上的矸石和錨桿為什么值得專門訓(xùn)一個YOLOv8模型井下皮帶運(yùn)輸系統(tǒng)里煤流中混進(jìn)矸石是常態(tài)錨桿這類鐵器一旦混入輕則卡壞破碎機(jī)重則劃傷皮帶導(dǎo)致停產(chǎn)??咳斯ざ⒈O(jiān)控屏視線疲勞后誤報漏報幾乎必然。這個項(xiàng)目的做法是用YOLOv8在皮帶監(jiān)控畫面上實(shí)時框出矸石和錨桿再套一個PyQt界面把檢測結(jié)果變成工人能直接操作的工具。3000多張現(xiàn)場圖像撐起來的檢測模型核心價值不是能識別而是在現(xiàn)場光照、煤塵、遮擋下還能穩(wěn)定識別。適合誰一類是煤礦智能化改造中的算法工程師需要一套能落地的檢測方案另一類是剛接觸目標(biāo)檢測、想用真實(shí)工業(yè)數(shù)據(jù)練手的開發(fā)者。前者能直接復(fù)用數(shù)據(jù)集組織和訓(xùn)練流程后者能看懂從標(biāo)注到界面封裝的完整鏈路。這篇筆記不繞彎子直接講數(shù)據(jù)怎么整理、參數(shù)怎么設(shè)、界面怎么寫、坑在哪。2. 從數(shù)據(jù)集到標(biāo)注格式3000多張煤礦圖像的整理與清洗2.1 數(shù)據(jù)采集場景與類別定義矸石、錨桿到底長什么樣矸石和煤在外觀上都是黑色塊體但表面光澤、紋理和形狀有明顯差異。矸石通常棱角分明、表面粗糙、反光弱煤塊則有油潤感、斷面較亮。錨桿是細(xì)長金屬桿件在圖像上常呈現(xiàn)為一條亮色長條有時伴隨端部螺紋或托盤。類別定義不要貪多常見做法是兩類gankuang矸石和 maogan錨桿煤塊不單獨(dú)標(biāo)注作為背景讓模型去區(qū)分。采集時要覆蓋不同皮帶速度、不同煤流量、井下白光和暖光兩種光照。圖片分辨率建議不低于1080P因?yàn)殄^桿是小目標(biāo)分辨率不夠后期很難補(bǔ)。我一般會讓現(xiàn)場人員分批次采集每天不同時段拍一段再從視頻流里抽幀避免相似幀過多導(dǎo)致訓(xùn)練集和驗(yàn)證集信息重疊。另外要注意類別的數(shù)量分布如果錨桿樣本只有矸石的三分之一訓(xùn)練出來錨桿recall必然偏低。遇到這種情況優(yōu)先補(bǔ)采集而不是做簡單復(fù)制增強(qiáng)復(fù)制出來的樣本只是讓模型記住同一個目標(biāo)的不同位置對泛化沒有幫助。2.2 標(biāo)注工具選擇與YOLO格式轉(zhuǎn)換腳本標(biāo)注工具首選LabelImg矩形框夠用、操作簡單導(dǎo)出Pascal VOC格式的XML。如果現(xiàn)場數(shù)據(jù)里有大量密集小目標(biāo)可以用開源的半自動標(biāo)注工具先跑一個預(yù)訓(xùn)練模型生成初稿再人工修正。不過初始版本我還是推薦全手動標(biāo)注3000多張圖一個人兩天到三天能完成質(zhì)量最可控。錨桿這類目標(biāo)比較特殊標(biāo)注時要順著桿件方向拉框不要為了省事畫一個正方形把周圍背景都包進(jìn)去。標(biāo)注完成后需要把XML轉(zhuǎn)成YOLO需要的txt格式每行一個目標(biāo)class_id cx cy w h坐標(biāo)全部歸一化。轉(zhuǎn)換腳本如下import xml.etree.ElementTree as ET from pathlib import Path # 修改為你的標(biāo)注目錄和圖片目錄 xml_dir Path(./annotations) out_dir Path(./labels) out_dir.mkdir(exist_okTrue) # 類別順序要和后續(xù)data.yaml里的names保持一致 class_map {gankuang: 0, maogan: 1} for xml_path in xml_dir.glob(*.xml): tree ET.parse(xml_path) root tree.getroot() # 讀取圖片寬高用于坐標(biāo)歸一化 img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_map: continue bbox obj.find(bndbox) x1 float(bbox.find(xmin).text) y1 float(bbox.find(ymin).text) x2 float(bbox.find(xmax).text) y2 float(bbox.find(ymax).text) # 轉(zhuǎn)成YOLO格式歸一化的中心點(diǎn)坐標(biāo)和寬高 cx (x1 x2) / 2 / img_w cy (y1 y2) / 2 / img_h w (x2 - x1) / img_w h (y2 - y1) / img_h lines.append(f{class_map[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) # 輸出txt和圖片同名放在labels目錄 out_path out_dir / (xml_path.stem .txt) out_path.write_text(\n.join(lines))腳本邏輯很簡單遍歷XML讀寬高把每個目標(biāo)的絕對坐標(biāo)歸一化到0到1之間。參數(shù)上有兩個容易翻車的點(diǎn)一是class_map的順序必須和訓(xùn)練配置文件data.yaml里的names一致順序錯了模型訓(xùn)練出來類別全對不上二是歸一化坐標(biāo)保留6位小數(shù)足夠但不要用科學(xué)計(jì)數(shù)法否則個別訓(xùn)練框架解析會出錯。轉(zhuǎn)換完成后要做一次抽檢把txt坐標(biāo)畫回原圖肉眼確認(rèn)框的位置和大小沒有偏差。這一步雖然繁瑣但能攔住八成標(biāo)注錯位問題尤其是XML里xmax寫反、width和height寫顛倒這樣的低級錯誤。提示抽檢建議寫個小腳本把原圖和標(biāo)簽畫成一張對比圖每20張拼一屏快速過目比一張張打開快了不是一點(diǎn)半點(diǎn)。2.3 數(shù)據(jù)集劃分與增強(qiáng)策略讓3000多張圖發(fā)揮出上萬張的效果劃分?jǐn)?shù)據(jù)集時不能直接把所有圖隨機(jī)打散因?yàn)橥灰曨l抽出的幀高度相似。常見做法是按視頻片段分組一個片段的幀要么全進(jìn)訓(xùn)練集、要么全進(jìn)驗(yàn)證集否則驗(yàn)證集指標(biāo)虛高模型上線后直接現(xiàn)原形。比例上train:val:test按8:1:1測試集最好是現(xiàn)場換一個班次、換一條皮帶采集的新視頻才真正算得上看不見的數(shù)據(jù)。增強(qiáng)策略上YOLOv8自帶的mosaic增強(qiáng)在訓(xùn)練前期很有效能模擬多目標(biāo)堆疊場景。井下場景我額外開啟了輕度HSV擾動hue ±0.015、sat ±0.5、val ±0.4因?yàn)楝F(xiàn)場不同時段皮帶燈光的色溫漂移明顯。但要注意井下煤塵大、圖像對比度低對比度增強(qiáng)不要開太大否則模型會把暗部的煤塊誤學(xué)成矸石紋理。翻轉(zhuǎn)增強(qiáng)對矸石這種不規(guī)則塊體要慎用水平翻轉(zhuǎn)還好垂直翻轉(zhuǎn)會讓模型學(xué)到矸石會飄在皮帶上空這種離譜特征。3. YOLOv8訓(xùn)練參數(shù)與關(guān)鍵命令讓3000張圖訓(xùn)出穩(wěn)定模型3.1 環(huán)境搭建與數(shù)據(jù)集配置文件訓(xùn)練環(huán)境用conda隔離Python 3.10配合PyTorch 2.x即可。安裝步驟分兩步先按顯卡驅(qū)動裝對應(yīng)CUDA版本的PyTorch再裝YOLOv8的ultralytics包。如果順序反了pip很可能拉一個CPU版本的PyTorch進(jìn)來訓(xùn)練速度差一個數(shù)量級而且不容易察覺——訓(xùn)練能跑就是慢得離譜。conda create -n yolo8 python3.10 -y conda activate yolo8 # 先裝GPU版PyTorch再裝YOLOv8檢測框架 pip install torch torchvision pip install ultralytics python -c import torch; print(torch.cuda.is_available())最后一行print輸出True說明GPU可用。如果輸出False先別急著重裝用nvidia-smi看驅(qū)動版本和CUDA版本的匹配情況最常見的問題是驅(qū)動太老不支持新CUDA。數(shù)據(jù)集配置文件data.yaml放在項(xiàng)目根目錄path: ./dataset # 數(shù)據(jù)集根目錄 train: images/train # 訓(xùn)練圖片目錄 val: images/val # 驗(yàn)證圖片目錄 test: images/test # 測試圖片目錄用于最終驗(yàn)證 nc: 2 # 類別數(shù)量 names: [gankuang, maogan] # 類別名稱順序必須與標(biāo)注一致這里的path可以用絕對路徑避免在Windows上因?yàn)楸P符問題找不到數(shù)據(jù)集。train和val是相對path的目錄圖片目錄和標(biāo)簽?zāi)夸浀膶?yīng)關(guān)系是YOLO內(nèi)部約定images/train里的每張圖對應(yīng)labels/train里同名txt。這個目錄結(jié)構(gòu)不要自己改改了訓(xùn)練時標(biāo)簽全部加載不到。data.yaml里我把test也顯式寫出來了因?yàn)榈?.3節(jié)的驗(yàn)證命令要依賴這個字段。3.2 訓(xùn)練參數(shù)詳解與首次實(shí)驗(yàn)設(shè)置訓(xùn)練命令本身不長但參數(shù)取舍很關(guān)鍵。井下皮帶場景我第一次訓(xùn)練用的是yolov8m因?yàn)殄^桿是小目標(biāo)m型號的特征提取能力比n和s強(qiáng)而x型號在3000多張圖的數(shù)據(jù)量下容易過擬合。預(yù)處理尺寸imgsz用了960而不是默認(rèn)640這個選擇直接影響后面所有調(diào)試的基準(zhǔn)。yolo detect train \ datadata.yaml \ modelyolov8m.yaml \ epochs200 \ imgsz960 \ batch16 \ device0 \ optimizerSGD \ lr00.01 \ weight_decay0.0005 \ patience30 \ project./runs/train \ nameconveyor_maogan參數(shù)說明epochs200對于3000多張圖偏多但配合patience30早停不會浪費(fèi)太多時間optimizerSGD在數(shù)據(jù)集不大的時候比AdamW泛化更穩(wěn)收斂也更容易控制imgsz960是為了照顧錨桿這類小目標(biāo)但顯存壓力會明顯上升如果顯卡只有8G顯存batch降到8、imgsz降到832是合理折中。weight_decay保持默認(rèn)的0.0005就好不用刻意調(diào)大井下的圖像噪聲已經(jīng)夠多了。訓(xùn)練時日志里要盯三個東西train/box_loss是否平滑下降、metrics/precision和metrics/recall是否同步上漲。如果precision上去了recall掉下來說明模型開始把矸石框得保守需要檢查標(biāo)注是不是有大量漏標(biāo)——漏標(biāo)的樣本會被當(dāng)成背景模型學(xué)到的是這部分不算目標(biāo)recall自然上不去。另一個常見的現(xiàn)象是loss在訓(xùn)練中段出現(xiàn)一個臺階式下跌這通常是mosaic增強(qiáng)在最后10個epoch自動關(guān)閉導(dǎo)致的不是bug。3.3 從結(jié)果目錄里挑出真正能用的權(quán)重訓(xùn)練結(jié)束后runs/train/conveyor_maogan/weights下會有兩個文件best.pt和last.pt。很多新手直接拿last.pt用這是錯的。last.pt是最后一個epoch的權(quán)重如果早停觸發(fā)前模型已經(jīng)在過擬合階段它反而比中間某個epoch更差best.pt是根據(jù)驗(yàn)證集綜合指標(biāo)選出來的最優(yōu)權(quán)重默認(rèn)評判標(biāo)準(zhǔn)是mAP50-95但對我來說recall更關(guān)鍵——漏檢一個錨桿可能就意味著一次皮帶事故。所以我一般會額外跑一次驗(yàn)證用best.pt在測試集上輸出詳細(xì)指標(biāo)并且按類別分開看yolo detect val \ modelruns/train/conveyor_maogan/weights/best.pt \ datadata.yaml \ splittest \ imgsz960 \ save_jsonTrue注意splittest要求data.yaml里顯式定義了test字段否則會退回驗(yàn)證集。save_jsonTrue會生成predictions.json里面每個檢測框都有score和class_id后續(xù)調(diào)置信度閾值全靠它。驗(yàn)證結(jié)果里有一個混淆矩陣.png打開看一眼如果錨桿大量被預(yù)測成矸石說明兩類特征在細(xì)長形狀和暗色紋理上有重疊需要回到標(biāo)注環(huán)節(jié)再摳細(xì)節(jié)而不是盲目調(diào)參。如果box_loss正常但分類損失下不去優(yōu)先檢查數(shù)據(jù)集的類別標(biāo)簽是否貼錯這種錯誤用混淆矩陣一眼就能定位。4. PyQt可視化界面把檢測模型封裝成現(xiàn)場能用的工具4.1 界面布局與功能設(shè)計(jì)模型訓(xùn)好了交付物不能是命令行里的一串輸出現(xiàn)場工人要的是一個打開的窗口、按一個按鈕就能看的界面。PyQt做這件事很合適界面開發(fā)快OpenCV的圖像幀可以直接轉(zhuǎn)成QImage顯示不需要額外的圖像庫。界面布局我一般分四塊左側(cè)是實(shí)時視頻顯示區(qū)右側(cè)上方是檢測結(jié)果統(tǒng)計(jì)當(dāng)前幀矸石數(shù)量、錨桿數(shù)量右側(cè)下方是操作按鈕和置信度閾值滑塊底部是報警狀態(tài)欄。關(guān)鍵的一點(diǎn)是把推理放進(jìn)QThread子線程否則視頻卡頓和界面假死會同時出現(xiàn)這個問題第5章會展開。閾值滑塊為什么要放在界面上因?yàn)楝F(xiàn)場不同時段煤流量差異很大煤多的時候矸石被遮擋、置信度普遍偏低煤少的時候誤檢增多操作員需要在不改代碼的情況下實(shí)時調(diào)整。4.2 核心代碼加載模型、推理與結(jié)果繪制界面核心代碼我拆成兩個文件main_window.py負(fù)責(zé)界面detector.py負(fù)責(zé)推理。這里給出detector.py的關(guān)鍵部分from ultralytics import YOLO import cv2 class BeltDetector: def __init__(self, model_pathbest.pt, conf0.45): # 加載訓(xùn)練好的模型只跑推理 self.model YOLO(model_path) self.conf conf self.class_names [gankuang, maogan] # 矸石用紅色框錨桿用黃色框便于現(xiàn)場一眼區(qū)分 self.colors {gankuang: (0, 0, 255), maogan: (0, 255, 255)} def detect_frame(self, frame): # 模型推理agnostic_nmsTrue避免同類框互相壓制 results self.model(frame, confself.conf, imgsz960, agnostic_nmsTrue, verboseFalse) dets results[0] boxes dets.boxes if boxes is None: return frame, 0, 0 gangue_count 0 bolt_count 0 for box in boxes: x1, y1, x2, y2 map(int, box.xyxy[0].tolist()) cls_id int(box.cls[0]) score float(box.conf[0]) name self.class_names[cls_id] color self.colors[name] # 畫框和標(biāo)簽 cv2.rectangle(frame, (x1, y1), (x2, y2), color, 2) label f{name} {score:.2f} cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) if cls_id 0: gangue_count 1 else: bolt_count 1 return frame, gangue_count, bolt_count邏輯說明YOLO(model_path)加載權(quán)重后每次調(diào)用直接把BGR幀傳給模型內(nèi)部會做預(yù)處理和NMS。agnostic_nmsTrue的意思是所有類別一起做非極大值抑制防止同一個錨桿同時被兩個類別框住。返回的boxes里xyxy是絕對像素坐標(biāo)直接用于畫框不需要還原歸一化坐標(biāo)。參數(shù)上要注意兩點(diǎn)一是imgsz960必須和訓(xùn)練時一致模型雖然支持任意尺寸輸入但輸入尺寸跳變會讓小目標(biāo)檢測結(jié)果明顯變差二是conf閾值不要寫死在代碼里界面的滑塊要能實(shí)時改現(xiàn)場調(diào)試時不同的皮帶煤流量差異很大閾值需要隨時微調(diào)。4.3 實(shí)時視頻流接入與報警聯(lián)動視頻流接入用OpenCV的VideoCapture打開攝像頭或RTSP流但在Qt里不能直接在QTimer回調(diào)里讀幀加推理否則界面刷新會卡到?jīng)]法看。正確做法是開一個QThread線程里循環(huán)讀幀、推理、把結(jié)果幀和計(jì)數(shù)信號發(fā)回主線程from PyQt5.QtCore import QThread, pyqtSignal import cv2 class VideoThread(QThread): # 每一幀檢測結(jié)果通過信號發(fā)給主線程更新界面 frame_ready pyqtSignal(object, int, int) def __init__(self, detector, video_source0): super().__init__() self.detector detector self.video_source video_source self.running True def run(self): cap cv2.VideoCapture(self.video_source) while self.running: ret, frame cap.read() if not ret: # 現(xiàn)場RTSP流斷線常見斷開后等一秒重連 self.msleep(1000) cap cv2.VideoCapture(self.video_source) continue result_frame, gangue, bolts self.detector.detect_frame(frame) # 信號里傳圖像幀和兩個計(jì)數(shù) self.frame_ready.emit(result_frame, gangue, bolts) cap.release() def stop(self): self.running False self.wait()主線程槽函數(shù)里把frame_ready收到的幀轉(zhuǎn)成QImage顯示當(dāng)bolts 0時觸發(fā)報警狀態(tài)欄變紅、播放提示音。這里有個性能細(xì)節(jié)detect_frame返回的幀直接用不要再做一次拷貝OpenCV畫框是原地修改QImage構(gòu)造時可以做淺拷貝顯示深拷貝會讓幀率掉一半以上。RTSP斷線重連寫進(jìn)run循環(huán)而不是讓線程退出現(xiàn)場攝像頭網(wǎng)絡(luò)抖動很常見線程一退界面就黑屏操作員只能重啟程序體驗(yàn)很差。5. 煤礦傳送帶檢測的5個典型踩坑與排查記錄這些坑不是從手冊上看來的是現(xiàn)場一個一個踩出來的。下面五條按出現(xiàn)頻率排序每一條都按現(xiàn)象、原因、解決三層說清楚你在自己項(xiàng)目里大概率會遇到至少三條。5.1 矸石誤檢率居高不下框滿天飛現(xiàn)象驗(yàn)證集mAP有0.92上線到現(xiàn)場視頻里誤檢率超過30%煤塊、皮帶接頭、托輥全被框成矸石。原因訓(xùn)練集里矸石標(biāo)注框太松很多框把矸石周圍的煤也包進(jìn)去了模型學(xué)到的是大塊暗色區(qū)域而不是矸石紋理。另外驗(yàn)證集和訓(xùn)練集來自同一批視頻抽幀指標(biāo)虛高掩蓋了問題。解決重新規(guī)范標(biāo)注標(biāo)準(zhǔn)標(biāo)注框四邊必須貼住矸石邊緣寧可漏一點(diǎn)也不能多包。處理完后再看訓(xùn)練集里置信度Top的誤檢圖凡是框住煤塊的樣本檢查它附近是否存在漏標(biāo)——漏標(biāo)的矸石會讓模型認(rèn)為這個長相不算矸石這也是誤檢的隱性來源。5.2 錨桿目標(biāo)太小中遠(yuǎn)距離頻繁漏檢現(xiàn)象矸石全檢出來了錨桿在遠(yuǎn)處畫面里只有十幾個像素寬recall只有0.4。原因默認(rèn)imgsz640對錨桿來說分辨率不夠一個十幾像素的目標(biāo)被縮放后特征基本消失。解決訓(xùn)練和推理統(tǒng)一提升到imgsz960同時錨桿單獨(dú)算一次recall不要只看總mAP。如果顯存不夠另一個做法是按皮帶區(qū)域把畫面裁剪成兩段分別檢測相當(dāng)于用切圖換分辨率。我在現(xiàn)場兩種都試過960直接推理比切圖省事且更穩(wěn)切圖引入的拼接邊界問題反而增加調(diào)試成本。5.3 PyQt界面推理時窗口假死現(xiàn)象打開視頻后窗口轉(zhuǎn)圈拖拽窗口無響應(yīng)幾秒后系統(tǒng)提示程序未響應(yīng)。原因把cap.read()和模型推理寫在了主線程推理一幀要80到150毫秒主線程被阻塞Qt事件循環(huán)無法處理重繪和鼠標(biāo)消息。解決嚴(yán)格按4.3的QThread方案主線程只負(fù)責(zé)接收信號刷新界面。注意線程里不要碰任何QWidget控件所有界面更新必須通過信號發(fā)回主線程這是Qt線程模型的鐵律違反它會出現(xiàn)比假死更詭異的偶發(fā)崩潰。5.4 光照突變導(dǎo)致連續(xù)漏檢現(xiàn)象皮帶啟動瞬間燈光閃一下或者礦車經(jīng)過擋住光源之后連續(xù)十幾幀檢測不到任何目標(biāo)。原因模型對訓(xùn)練集的光照分布過擬合訓(xùn)練時圖像白平衡和亮度分布比較集中沒有覆蓋燈閃這種瞬態(tài)變化。解決給訓(xùn)練集增加亮度抖動增強(qiáng)同時在采集階段專門錄幾段燈閃和遮擋的視頻加入訓(xùn)練。推理端做一個簡單的自適應(yīng)檢測前先用createCLAHE做一次光照均衡但參數(shù)要控制好增強(qiáng)過頭會把暗色煤塊提亮成矸石紋理反而增加誤檢。5.5 工控機(jī)上推理速度從30幀掉到8幀現(xiàn)象開發(fā)機(jī)上GPU跑得飛快部署到現(xiàn)場工控機(jī)后幀率慘不忍睹CPU占用拉滿。原因工控機(jī)沒有獨(dú)立顯卡模型在CPU上用FP32推理960分辨率下單幀要120毫秒以上。解決兩條路。一是換小模型從yolov8m降到y(tǒng)olov8s甚至n3000多張數(shù)據(jù)量訓(xùn)練n型號精度損失控制在2到3個點(diǎn)速度翻三倍二是現(xiàn)場有NVIDIA顯卡就導(dǎo)出TensorRT的engine格式FP16推理在960分辨率下能跑25幀以上。如果不能換硬件優(yōu)先把imgsz降到640錨桿漏檢用按ROI裁剪來補(bǔ)償。6. 現(xiàn)場驗(yàn)證方法與參數(shù)調(diào)優(yōu)讓模型在皮帶上長期扛住權(quán)重和界面都做完之后別急著交付。我習(xí)慣做三件事第一拿一段真實(shí)現(xiàn)場監(jiān)控視頻做離線回放驗(yàn)證時間跨度超過4小時覆蓋白班、夜班和交接班時段統(tǒng)計(jì)每小時的誤檢數(shù)和漏檢數(shù)——這兩個數(shù)字比mAP更能讓現(xiàn)場負(fù)責(zé)人放心。第二看按類別拆分的指標(biāo)錨桿的recall必須單獨(dú)記錄因?yàn)樗苯雨P(guān)系到設(shè)備安全。第三把測試集里所有漏檢圖導(dǎo)出來逐張判斷是標(biāo)注漏了還是模型確實(shí)沒識別兩個原因的修法完全不同。參數(shù)調(diào)優(yōu)上現(xiàn)場調(diào)試階段我會把置信度閾值做成界面上的滑塊讓操作員自己微調(diào)。常見做法是矸石閾值保持0.5以上減少誤報錨桿閾值降到0.3保證召回。如果錨桿還是漏檢查NMS的IoU閾值默認(rèn)0.7在錨桿密集堆積時會互相壓制降到0.5能讓相鄰錨桿各自保留。還有一個容易被忽略的地方視頻流分辨率如果高于訓(xùn)練分辨率比如訓(xùn)練用了960但攝像頭輸出1080P推理時模型內(nèi)部會先縮放檢測框坐標(biāo)是縮放后的畫框前要按縮放比例映射回原圖否則框會整體偏移。這套方案做完我在現(xiàn)場最深的體會是模型訓(xùn)練只占三分之一的精力數(shù)據(jù)規(guī)范和界面交互占另外三分之二。3000多張圖不算多但把標(biāo)注做規(guī)范、把增強(qiáng)做貼合、把界面做成工人愿意用的樣子它就能穩(wěn)定扛住現(xiàn)場運(yùn)行。希望這些踩坑記錄能幫你在做類似項(xiàng)目時少走幾步彎路祝順利。本文還有配套的精品資源點(diǎn)擊獲取