據(jù)集構(gòu)建全攻略:從采集到部署)
簡(jiǎn)介智慧物流車道線分割數(shù)據(jù)集面向自動(dòng)駕駛、智能導(dǎo)航與物流路徑規(guī)劃開發(fā)者提供五百余張覆蓋不同照明環(huán)境的車道線原始圖像并劃分出訓(xùn)練集與驗(yàn)證集便于直接用于語義分割模型的訓(xùn)練和效果評(píng)估。壓縮包共含一千四百八十二個(gè)文件主要包括圖片、標(biāo)注文本和配置文件分別承載原始畫面、標(biāo)注信息與訓(xùn)練參數(shù)整體大小約一百五十五點(diǎn)八六兆字節(jié)結(jié)構(gòu)簡(jiǎn)潔易于索引。目前已有二百九十九人前來學(xué)習(xí)。借助該數(shù)據(jù)集使用者可快速搭建車道線分割實(shí)驗(yàn)驗(yàn)證算法在夜間、強(qiáng)光等復(fù)雜光照下的魯棒性也能結(jié)合定位與路徑規(guī)劃模塊在智慧物流場(chǎng)景中實(shí)現(xiàn)車道級(jí)行駛決策兼顧模型調(diào)試與工程落地需求。1. 車道線分割數(shù)據(jù)集為什么是智慧物流的剛需智慧物流場(chǎng)景里的自動(dòng)駕駛和城市領(lǐng)航輔助駕駛完全不是一回事。在園區(qū)、倉庫、港口和機(jī)場(chǎng)貨運(yùn)區(qū)車道線往往不是標(biāo)準(zhǔn)公路標(biāo)線而是C型線、磁釘指示、反光道釘、臨時(shí)圍欄線甚至?xí)蚴┕ゎl繁改動(dòng)。高精度地圖在這種動(dòng)態(tài)環(huán)境下維護(hù)成本極高所以主流方案是讓車端實(shí)時(shí)視覺分割出車道線再與規(guī)劃模塊對(duì)接。車道線分割數(shù)據(jù)集就是專門為這類低速、封閉、結(jié)構(gòu)化但多變的場(chǎng)景準(zhǔn)備的訓(xùn)練語料。它和Cityscapes、KITTI類自動(dòng)駕駛數(shù)據(jù)集的最大區(qū)別在于類別少但語義明確背景雜且光照極端倉庫內(nèi)低照度、室外逆光車道線形態(tài)不穩(wěn)定磨損、被托盤遮擋、被落葉覆蓋。如果你直接拿公開的公路上車道線數(shù)據(jù)集下載來訓(xùn)練部署到物流園區(qū)后幾乎必然出現(xiàn)漏檢和誤檢。內(nèi)容面向三類人正在給無人叉車做感知的算法工程師、需要自己造數(shù)據(jù)集的數(shù)據(jù)標(biāo)注團(tuán)隊(duì)、以及負(fù)責(zé)模型選型和評(píng)估的技術(shù)負(fù)責(zé)人。下文不打算只給概念而是從數(shù)據(jù)采集、標(biāo)注、增強(qiáng)、訓(xùn)練到評(píng)估把一條完整可落地的路徑拆開講每一步都給參數(shù)和命令并指出最容易被忽略的坑。2. 構(gòu)建智慧物流車道線分割數(shù)據(jù)集場(chǎng)景采集與標(biāo)注規(guī)范2.1 先圈定道路模型園區(qū)道路、倉庫通道與港口的差異不同物流子場(chǎng)景的“車道線”定義差異極大。我在實(shí)際項(xiàng)目里會(huì)把道路模型分成三類園區(qū)外部道路露天有雨水、逆光、樹影車道線多為黃色或白色油漆線磨損后可能出現(xiàn)不連續(xù)。倉庫內(nèi)部通道低照度、反光地面地坪漆、有貨架陰影車道線可能是線槽、膠帶或深色地標(biāo)有的直接是地面拼接縫。港口和機(jī)場(chǎng)貨運(yùn)區(qū)以C型線反光道釘和定制圖形為主線條尺寸大但容易受到集裝箱陰影和夜間燈光的影響。很多團(tuán)隊(duì)圖省事直接下載KITTI或Cityscapes上的車道線分割數(shù)據(jù)集來當(dāng)訓(xùn)練集但那些數(shù)據(jù)的語義定義、拍攝視角、線形規(guī)則和智慧物流場(chǎng)景差異極大遷移之后通常要重新標(biāo)注大量現(xiàn)場(chǎng)數(shù)據(jù)。因此在采集標(biāo)注之前先寫一份“車道線類別定義”文檔。我一般用以下五類類別名語義標(biāo)注要求line_lane正常車道線實(shí)線/虛線多邊形貼合線邊緣虛線段單獨(dú)標(biāo)注line_stop停車線 / 等待線封閉多邊形橫穿車道的區(qū)域全部覆蓋line_arrow導(dǎo)向箭頭直行、轉(zhuǎn)彎沿箭頭輪廓標(biāo)注不要只框一個(gè)矩形line_curb路緣 / 隔離線含路緣石頂部或側(cè)面標(biāo)注為線狀區(qū)域line_block臨時(shí)圍欄線 / 禁止區(qū)域線施工錐桶連成的臨時(shí)線形態(tài)多為條狀這樣的類別定義是給標(biāo)注團(tuán)隊(duì)的后面訓(xùn)練時(shí)還可以合并成二分類車道線/背景但采集時(shí)多保留語義訓(xùn)練時(shí)再?zèng)Q定是否壓縮。2.2 采集設(shè)備選型與標(biāo)定參數(shù)相機(jī)安裝高度、俯仰角與幀率常見做法是前視單目攝像頭外加一個(gè)魚眼鏡頭覆蓋車側(cè)盲區(qū)。相機(jī)的安裝位置和角度直接影響車道線的投影形態(tài)。下面是我用過的參數(shù)范圍表參數(shù)推薦范圍說明安裝高度1.5 ~ 2.5 m低于1.5 m近處畸變大高于2.5 m遠(yuǎn)處線容易被車頭遮擋俯仰角2° ~ 8°下俯角度越大近處可視性越好但遠(yuǎn)處分割不完整水平偏角0° ± 2°盡量正對(duì)車頭方向避免側(cè)向透視導(dǎo)致線與線混淆幀率15 ~ 30 fps低速物流車15 fps夠用高速牽引車建議30 fps分辨率1280×720 或 1920×1080分割任務(wù)建議不低于720p否則虛線段的個(gè)體像素太少采集時(shí)要覆蓋一個(gè)完整“運(yùn)營日”早晨逆光、中午強(qiáng)光、夜間場(chǎng)燈、雨天路面積水反光。這四種光照下同樣一條白色車道線的像素表現(xiàn)完全不同數(shù)據(jù)集里每類光照至少占20%否則訓(xùn)練后模型會(huì)偏向某一時(shí)刻的光照條件。2.3 用labelme或X-AnyLabeling做多邊形標(biāo)注的步驟標(biāo)注工具我常用labelme因?yàn)樗荍SON格式方便后續(xù)轉(zhuǎn)成掩膜。步驟是安裝 labelme啟動(dòng)命令pip install labelme labelme --labels labels.txt --nodatalabels.txt里按行寫好類別_background_、line_lane、line_stop、line_arrow、line_curb、line_block。--nodata讓標(biāo)注文件不嵌入原始圖像數(shù)據(jù)減小JSON體積。用“多邊形”工具描邊每條車道線畫一個(gè)多邊形。對(duì)于虛線每條線段單獨(dú)描一次不要跨兩個(gè)線段畫一個(gè)長條。保存后生成與圖片同名的.json文件再用labelme_json_to_dataset或者自己的腳本導(dǎo)出可視化的疊加圖用來做快速目檢。這里有一個(gè)容易被忽略的點(diǎn)物流園區(qū)地面往往有接縫、螺栓、色差這些不是車道線但會(huì)讓標(biāo)注者猶豫。我通常會(huì)在標(biāo)注規(guī)范里明確“非涂裝線一律不標(biāo)”并且給每個(gè)新標(biāo)注員做一份包含10張疑難圖的測(cè)試卷標(biāo)注準(zhǔn)確率低于90%不能正式上崗。2.4 標(biāo)注質(zhì)量控制雙人交叉檢查與抽樣復(fù)審單一標(biāo)注員的漏標(biāo)是數(shù)據(jù)集質(zhì)量的主要風(fēng)險(xiǎn)。我用的流程是第一個(gè)標(biāo)注員完成一批圖片后第二個(gè)標(biāo)注員在不知道第一個(gè)結(jié)果的情況下重新標(biāo)注其中10%的圖片再用“IoU一致性”來比較兩個(gè)人的標(biāo)注。公式是相同類別下兩個(gè)多邊形區(qū)域的IoU大于0.7認(rèn)為該對(duì)象標(biāo)注一致。IoU在0.3~0.7的交給審核人手動(dòng)調(diào)整。小于0.3的直接判為無效圖片退回重標(biāo)。這個(gè)規(guī)則對(duì)細(xì)長的車道線特別有效因?yàn)檐嚨谰€的面積小像素偏移幾個(gè)點(diǎn)就會(huì)讓IoU掉得很厲害。審核完之后還需要做一次“類別平衡”檢查。如果 line_stop 只有 line_lane 的五分之一那么在損失函數(shù)里少數(shù)類很容易被多數(shù)類吞掉。常見做法是統(tǒng)計(jì)每個(gè)類別的像素占比低于5%的類別要么補(bǔ)充采集要么在訓(xùn)練時(shí)使用類別加權(quán)損失這一點(diǎn)在下一章展開。3. 智慧物流車道線分割數(shù)據(jù)集的訓(xùn)練格式目錄、增強(qiáng)與劃分3.1 從JSON到語義掩膜一次性轉(zhuǎn)換腳本labelme生成的JSON是點(diǎn)列不能直接交給深度學(xué)習(xí)框架。需要先把每個(gè)多邊形的點(diǎn)集填充成二值/索引圖。以下是我常用的轉(zhuǎn)換腳本import json import os import numpy as np import cv2 from tqdm import tqdm label_map {_background_: 0, line_lane: 1, line_stop: 2, line_arrow: 3, line_curb: 4, line_block: 5} def json_to_mask(json_path, image_path, mask_path): with open(json_path, r, encodingutf-8) as f: data json.load(f) img cv2.imread(image_path) h, w img.shape[:2] mask np.zeros((h, w), dtypenp.uint8) for shape in data[shapes]: label shape[label] if label not in label_map: continue points np.array(shape[points], dtypenp.int32) cv2.fillPoly(mask, [points], label_map[label]) cv2.imwrite(mask_path, mask)腳本里用的是cv2.fillPoly而不是cv2.polylines因?yàn)檐嚨谰€是“區(qū)域”而不是輪廓線。如果用線畫邊界只有1像素厚訓(xùn)練出來的分割結(jié)果會(huì)發(fā)虛邊界誤差也會(huì)直接影響mIoU。轉(zhuǎn)換后目錄結(jié)構(gòu)我一般是這樣組織的dataset/ ├── images/ │ ├── sun/xxx.jpg │ ├── rain/xxx.jpg │ └── night/xxx.jpg ├── masks/ │ ├── sun/xxx.png │ ├── rain/xxx.png │ └── night/xxx.png ├── train.txt ├── val.txt └── test.txt注意mask必須是PNG格式不要用JPEG因?yàn)镴PEG是有損壓縮會(huì)在邊界產(chǎn)生偽影引入噪聲標(biāo)簽。我在實(shí)際項(xiàng)目里就因此吃過虧模型在訓(xùn)練集上收斂很快但真實(shí)場(chǎng)景中邊界抖動(dòng)明顯后來全部換成PNG并重新生成mask之后mIoU直接提升了3個(gè)百分點(diǎn)。3.2 訓(xùn)練/驗(yàn)證/測(cè)試集劃分按“場(chǎng)景”而不是按“幀”很多人直接從全部圖片里隨機(jī)抽20%做驗(yàn)證集這在智慧物流車道線分割里是嚴(yán)重錯(cuò)誤。因?yàn)橄噜弾瑤缀跸嗤S機(jī)劃分會(huì)讓驗(yàn)證集泄露訓(xùn)練數(shù)據(jù)導(dǎo)致驗(yàn)證分?jǐn)?shù)虛高。我采用“場(chǎng)景級(jí)”劃分從采集記錄中把每次行駛?cè)蝿?wù)看作一個(gè)session每個(gè)session內(nèi)的圖片連續(xù)且構(gòu)圖相似。按session而不是按單幀來分讓訓(xùn)練集和驗(yàn)證集完全隔開。劃分腳本很簡(jiǎn)單import random all_files [...] # 讀取自 images/ 下所有存在的 jpg 路徑 session_of lambda p: os.path.basename(p).split(_)[0] sessions list({session_of(p) for p in all_files}) random.seed(42) random.shuffle(sessions) val_sessions sessions[:int(len(sessions) * 0.2)] val_files [p for p in all_files if session_of(p) in val_sessions]這里假設(shè)文件名前綴是session名例如20250301_sun_001.jpg。如果你的命名不是這樣可以在采集時(shí)就把session信息寫在文件名里這個(gè)習(xí)慣很重要。另外測(cè)試集最好不要和驗(yàn)證集一起調(diào)參。我的做法是用驗(yàn)證集做模型選擇和超參調(diào)整最后拉通一個(gè)“盲測(cè)”倉庫場(chǎng)景不參與任何訓(xùn)練和驗(yàn)證只跑一次得到最終指標(biāo)。盲測(cè)在最后一章還會(huì)再說到。3.3 數(shù)據(jù)增強(qiáng)針對(duì)車道線的幾何與光照增強(qiáng)組合通用分割增強(qiáng)隨機(jī)旋轉(zhuǎn)、水平翻轉(zhuǎn)、色彩抖動(dòng)可以直接用但有幾個(gè)陷阱。旋轉(zhuǎn)要限制在±10°以內(nèi)。因?yàn)檐嚨谰€是細(xì)長結(jié)構(gòu)旋轉(zhuǎn)過大會(huì)導(dǎo)致真實(shí)的車道線變成斜線而物流園區(qū)里車道線極少出現(xiàn)大角度傾斜。水平翻轉(zhuǎn)可以放心用車道線左右對(duì)稱不改變語義。亮度、對(duì)比度、隨機(jī)gamma這三個(gè)增強(qiáng)必須有因?yàn)閿?shù)據(jù)采集覆蓋了不同光照時(shí)段但不可能窮盡所有曝光模型要能泛化到不同曝光。我用albumentations庫實(shí)現(xiàn)增強(qiáng)流程關(guān)鍵代碼import albumentations as A train_transform A.Compose([ A.Rotate(limit10, border_modecv2.BORDER_CONSTANT), A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(brightness_limit0.3, contrast_limit0.3, p0.8), A.RandomGamma(gamma_limit(80, 120), p0.5), A.GaussNoise(var_limit(10.0, 30.0), p0.2), A.Resize(512, 512), ])注意border_modecv2.BORDER_CONSTANT旋轉(zhuǎn)后邊緣的填充值固定為背景0如果用默認(rèn)的鏡像填充會(huì)把邊界上的車道線紋理復(fù)制接縫產(chǎn)生偽標(biāo)簽。這個(gè)小細(xì)節(jié)對(duì)細(xì)線分割的影響很明顯。增強(qiáng)參數(shù)匯總成表方便復(fù)現(xiàn)增強(qiáng)操作參數(shù)范圍適用場(chǎng)景Rotate±10°消除車輛輕微擺動(dòng)HorizontalFlip概率0.5增加左右對(duì)稱信息RandomBrightnessContrast±0.3模擬光照變化RandomGamma80~120模擬曝光偏差GaussNoisevar10~30模擬傳感器噪聲3.4 類別不平衡處理加權(quán)采樣與損失函數(shù)選擇在我的數(shù)據(jù)集里line_arrow和line_stop的像素占比通常只有1%到3%而line_lane可能占到8%背景則占85%以上。直接用CrossEntropyLoss背景會(huì)把其他類全部淹沒。常見兩種解法在損失函數(shù)上給每個(gè)類別一個(gè)權(quán)重權(quán)重和類別像素比例成反比。比如用torch.nn.CrossEntropyLoss(weighttorch.tensor([0.3, 1.0, 5.0, 5.0, 2.0, 4.0]))權(quán)重根據(jù)實(shí)際統(tǒng)計(jì)調(diào)整。在采樣上如果使用OHEM或者Focal Loss也可以在訓(xùn)練初期加快收斂。不過對(duì)細(xì)線任務(wù)我試過Focal Loss效果不如CrossEntropy加類別權(quán)重穩(wěn)定主要原因在于Focal Loss對(duì)“easy background”降權(quán)過猛而背景占了絕大多數(shù)導(dǎo)致模型對(duì)背景的判斷不夠自信容易把地面污漬當(dāng)成線。更穩(wěn)妥的方案是“像素加權(quán)采樣”對(duì)每個(gè)訓(xùn)練step從batch里按包含少數(shù)類的圖片進(jìn)行加權(quán)抽取保證每個(gè)batch中至少有一張帶箭頭的圖片。這樣損失函數(shù)和采樣雙重作用能讓箭頭類的IoU從40%以下提升到60%以上。4. 智慧物流車道線分割模型訓(xùn)練YOLOv8-seg與MMSegmentation4.1 為什么選這兩個(gè)框架智慧物流車道線分割你既可以選擇語義分割每個(gè)像素只屬于一個(gè)類別也可以選擇實(shí)例分割區(qū)分每條獨(dú)立的車道線。我個(gè)人的經(jīng)驗(yàn)是如果目標(biāo)是輸出可行駛區(qū)域的邊界、與規(guī)劃模塊對(duì)接用語義分割更直接。如果下游需要感知每一條線的具體位置比如區(qū)分“第一道線”和“第二道線”實(shí)例分割更容易做后續(xù)擬合。YOLOv8-seg和MMSegmentation是兩種最常用的框架。前者上手快、推理快適合迭代驗(yàn)證后者配置靈活、模型種類多適合追求精度和自定義損失函數(shù)的場(chǎng)景。4.2 YOLOv8-seg的訓(xùn)練配置與命令YOLOv8-seg要求的數(shù)據(jù)格式是每個(gè)實(shí)例一個(gè)多邊形標(biāo)注類似COCO。如果你的標(biāo)注原本是語義mask需要把mask轉(zhuǎn)成實(shí)例多邊形。這一步可以用cv2.findContours從mask提取輪廓然后保存成MOT或COCO風(fēng)格JSON。不過更簡(jiǎn)單的做法是直接用Ultralytics的腳本處理。在項(xiàng)目根目錄創(chuàng)建datasets/lane_seg.yamlpath: /path/to/your/dataset train: images/train val: images/val test: images/test nc: 5 names: [line_lane, line_stop, line_arrow, line_curb, line_block]然后運(yùn)行訓(xùn)練命令yolo segment train datalane_seg.yaml modelyolov8s-seg.pt epochs300 imgsz640 batch16 lr00.01 patience50 project./runs_yolo參數(shù)說明modelyolov8s-seg.pt用小型預(yù)訓(xùn)練模型做遷移學(xué)習(xí)比從頭訓(xùn)練快很多如果數(shù)據(jù)量大可以試yolov8m-seg.pt。imgsz640對(duì)細(xì)線來說640分辨率夠用若車道線寬度小于10像素建議升到960但會(huì)顯著增加顯存和推理時(shí)間。patience50驗(yàn)證集指標(biāo)連續(xù)50個(gè)epoch不提升就早停防止過擬合到物流園區(qū)的特定紋理。lr00.01預(yù)訓(xùn)練模型微調(diào)這個(gè)初始學(xué)習(xí)率不算大可以看訓(xùn)練曲線如果loss震蕩降到0.005。訓(xùn)練時(shí)隨時(shí)用yolo predict驗(yàn)證單張圖yolo segment predict modelruns_yolo/segment/train/weights/best.pt sourcetest_img.jpg save_txtTrue注意YOLOv8-seg的輸出是實(shí)例級(jí)mask但類別名里只有5類。對(duì)于多條車道線每個(gè)實(shí)例是獨(dú)立的。如果你想要的是整體可行駛區(qū)域后處理時(shí)把所有實(shí)例mask合在一起就行。4.3 MMSegmentation的配置與訓(xùn)練命令MMSegmentation更偏研究和精度。我常用deeplabv3plus_r101或segformer_b0。需要先安裝mm系列環(huán)境然后寫一個(gè)配置文件例如segformer_b0_lane.py_base_ [mmseg::_base_/models/segformer_b0.py, mmseg::_base_/default_runtime.py, mmseg::_base_/schedules/schedule_160k.py] dataset_type CustomDataset data_root data/lane_dataset classes [line_lane, line_stop, line_arrow, line_curb, line_block] palette [[128,0,0], [0,128,0], [128,128,0], [0,0,128], [128,0,128]] train_pipeline [ dict(typeLoadImageFromFile), dict(typeLoadAnnotations), dict(typeRandomResize, scale(512, 512), ratio_range(0.8, 1.2)), dict(typeRandomFlip, prob0.5), dict(typePackSegInputs) ] train_dataloader dict( batch_size8, datasetdict(typedataset_type, data_rootdata_root, data_prefixdict(img_pathimages/train, seg_map_pathmasks/train), classesclasses, pipelinetrain_pipeline))配置的關(guān)鍵項(xiàng)是seg_map_path指向的mask圖片里像素值必須是從0到N-1的類別索引。MMSegmentation默認(rèn)不做歸一化0是背景1是line_lane以此類推和我在第3章轉(zhuǎn)換的mask一致。啟動(dòng)訓(xùn)練python tools/train.py configs/segformer_b0_lane.py --work-dir ./work_dirs/lane_seg注意MMSegmentation的默認(rèn)評(píng)估是mIoU不需要額外指定。訓(xùn)練結(jié)束后用tools/test.py評(píng)估python tools/test.py configs/segformer_b0_lane.py work_dirs/lane_seg/iter_160000.pth --eval mIoU4.4 關(guān)鍵訓(xùn)練參數(shù)對(duì)比表我把兩個(gè)框架和推薦參數(shù)整理成下表方便直接對(duì)照參數(shù)YOLOv8-segMMSegmentation輸入尺寸640×640512×512原始圖預(yù)訓(xùn)練權(quán)重yolov8s-seg.ptSegFormer-B0優(yōu)化器AdamW lr0.01AdamW lr0.00006損失函數(shù)內(nèi)置BCEDiceCrossEntropy 類別權(quán)重訓(xùn)練輪次300 epochs160k iters早停patience50不常用用save_best學(xué)習(xí)率是分割模型最容易調(diào)錯(cuò)的地方。MMSegmentation默認(rèn)的lr是0.0006左右而YOLOv8因?yàn)樽詭armuplr0可以給到0.01。我自己的習(xí)慣是如果訓(xùn)練曲線前10輪loss不降就先降低學(xué)習(xí)率而不是盲目加batch size。5. 智慧物流車道線分割模型的評(píng)估指標(biāo)與后處理5.1 mIoU之外還要看車道線連續(xù)性mIoU是通用分割指標(biāo)但它對(duì)細(xì)線不敏感。一個(gè)mIoU達(dá)到0.7的模型可能在30米車道上斷開5處對(duì)無人車的路徑規(guī)劃是致命的。我額外計(jì)算“連通性得分”對(duì)分割結(jié)果做骨架化統(tǒng)計(jì)每條斷線的段數(shù)再與GT對(duì)比。具體做法import cv2 from skimage.morphology import skeletonize def broken_count(mask): mask_bin (mask 0).astype(uint8) ske skeletonize(mask_bin) kernel cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) endpoints cv2.filter2D(ske.astype(uint8), -1, kernel) return int(np.sum(endpoints 2) / 2)然后計(jì)算broken_ratio pred_broken / gt_broken越接近1越好。我一般讓它落在0.8~1.2之間如果太高說明模型把一條完整線拆成了很多段需要提高后處理中的長度閾值或膨脹核大小。5.2 類別權(quán)重與評(píng)估口徑訓(xùn)練時(shí)用了類別權(quán)重評(píng)估時(shí)也要用加權(quán)IoU否則少數(shù)類被平均掉。比如箭頭類IoU只有0.3但權(quán)重是5最終加權(quán)mIoU會(huì)拉開模型間差距。我建議報(bào)告兩個(gè)指標(biāo)未加權(quán)mIoU和“物流關(guān)鍵類IoU”即line_lane、line_arrow、line_block三類的平均值后者更貼近運(yùn)營方的KPI。5.3 跨場(chǎng)地盲測(cè)想檢驗(yàn)數(shù)據(jù)集是否覆蓋了足夠場(chǎng)景最直接的辦法是把一個(gè)場(chǎng)地完全留出來不參與訓(xùn)練也不參與驗(yàn)證。我在每個(gè)項(xiàng)目里都會(huì)安排一次“周末盲測(cè)”拿一個(gè)從未見過的倉庫的3分鐘錄像讓模型跑一遍用離線的標(biāo)注工具快速標(biāo)出斷點(diǎn)再手動(dòng)數(shù)一下漏檢和誤檢。如果盲測(cè)結(jié)果比驗(yàn)證集低10個(gè)百分點(diǎn)以上大概率是數(shù)據(jù)集的場(chǎng)景分布有偏。這時(shí)不要急著加數(shù)據(jù)增強(qiáng)而是回到第2章的光照覆蓋檢查盲測(cè)場(chǎng)景是不是有白色強(qiáng)光、藍(lán)色纏繞膜、或者地面大量水漬把這些特質(zhì)采集進(jìn)來重新訓(xùn)練。5.4 部署時(shí)的后處理技巧分割模型的輸出不能直接進(jìn)規(guī)劃模塊。部署前通常做三步后處理閉運(yùn)算濾波對(duì)mask做一次cv2.morphologyEx(mask, cv2.MORPH_CLOSE, (5,5))可以填掉5像素以內(nèi)的小斷點(diǎn)。最小連通域過濾面積小于img_area * 0.0005的連通域全部置0去掉地面污漬引起的誤檢。曲線擬合用RANSAC或最小二乘對(duì)每一條線的像素點(diǎn)擬合二次曲線輸出給規(guī)劃模塊時(shí)只傳曲線參數(shù)不傳像素圖。這樣既能平滑抖動(dòng)又能減少帶寬。最后一個(gè)提醒數(shù)據(jù)集不是一次性資產(chǎn)。智慧物流園區(qū)的車道線會(huì)重新噴涂臨時(shí)區(qū)域會(huì)被移動(dòng)我一般會(huì)讓模型每月用一個(gè)“小更新集”做增量微調(diào)更新集包含最近兩周的現(xiàn)場(chǎng)圖片這樣數(shù)據(jù)集和模型才能持續(xù)可用。本文還有配套的精品資源點(diǎn)擊獲取