
簡介本數據集面向計算機視覺入門與目標檢測實踐者聚焦“電瓶車進入電梯”這一社區(qū)安防場景可用于訓練和驗證單類別檢測模型幫助讀者快速搭建針對電動踏板車闖入電梯的識別方案。資源包共602個文件包含200張jpg原圖、200個Pascal VOC格式xml標注和200個YOLO格式txt標注另有少量說明文件壓縮包約11.07MB兩種標注格式可分別適配不同檢測框架省去格式轉換步驟。所有圖片均使用labelImg手工繪制矩形框標注類別為electric scooter共210個標注框標注準確合理。目前已有205人學習下載適合作為課程設計、畢業(yè)設計或算法驗證的小型數據集讀者可直接用于模型訓練、數據增強與檢測效果對比快速驗證單類別檢測流程。1. 電瓶車進電梯檢測200 張 VOCYOLO 數據集到底能跑出什么電瓶車進電梯這件事物業(yè)頭疼、業(yè)主害怕但真正落到算法層面它其實是一個典型的「小目標 固定場景 單類別」檢測問題。你拿到的這份電瓶車進入電梯檢測數據集200 張圖VOC 和 YOLO 兩種標注格式核心目標只有一個把電梯轎廂里的電瓶車框出來。聽起來簡單但 200 張這個量級決定了它不是一個能直接沖 SOTA 的數據集而是一個用來驗證 pipeline、做 demo、跑通訓練流程的起點。適合誰適合手頭有電梯監(jiān)控畫面、想快速驗證檢測可行性的人也適合剛接觸 YOLO 訓練、需要一個真實場景數據集練手的人。別指望 200 張能覆蓋所有電梯型號和光照條件但它足夠讓你把「數據標注→格式轉換→訓練→推理→部署」這條鏈路完整走一遍知道坑在哪。2. 拆開這份數據集VOC 與 YOLO 雙格式的選型邏輯與目錄結構2.1 為什么同一批圖要同時給 VOC 和 YOLO 兩種格式VOC 格式是 XML 文件每個圖對應一個 XML里面用bndbox記錄xmin/ymin/xmax/ymax坐標是絕對像素值。YOLO 格式是 TXT 文件每行class_id x_center y_center width height全部歸一化到 0~1。兩種格式同時給本質上是照顧不同訓練框架的輸入習慣。YOLOv5/v8/v11 系列默認吃 YOLO 格式而一些老代碼、MMDetection 配置、或者你自己寫的 PyTorch Dataset 可能更順手用 VOC。常見做法是拿 YOLO 格式直接喂 ultralytics拿 VOC 格式做數據校驗和可視化因為 XML 可讀性更好出問題容易定位。注意兩種格式的類別索引必須對齊。VOC 里類別名是字符串YOLO 里是數字如果轉換時類別映射寫錯訓練時 loss 會正常降但 mAP 極低這是血淚經驗。2.2 200 張圖的目錄應該怎么擺拿到壓縮包解壓后別急著改路徑。先按下面這個結構整理后面所有腳本都基于這個結構寫dataset/ ├── images/ │ ├── 001.jpg │ ├── 002.jpg │ └── ... ├── annotations_voc/ │ ├── 001.xml │ ├── 002.xml │ └── ... ├── labels_yolo/ │ ├── 001.txt │ ├── 002.txt │ └── ... └── classes.txtclasses.txt里只寫一行ebike或者你數據集里定義的類別名。這個文件是后面轉換和訓練時類別映射的唯一依據不要散落在代碼里硬編碼。2.3 用腳本檢查 VOC 標注有沒有越界和漏標200 張圖雖然少但標注錯誤率往往不低。先跑一個校驗腳本把xminxmax、yminymax、坐標超出圖像寬高的 XML 全部揪出來import os import xml.etree.ElementTree as ET from PIL import Image voc_dir dataset/annotations_voc img_dir dataset/images for xml_file in os.listdir(voc_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(voc_dir, xml_file)) root tree.getroot() img_name root.find(filename).text img_path os.path.join(img_dir, img_name) if not os.path.exists(img_path): print(f[缺失圖像] {xml_file} - {img_name}) continue w, h Image.open(img_path).size for obj in root.findall(object): name obj.find(name).text bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) if xmin xmax or ymin ymax: print(f[坐標顛倒] {xml_file} {name} ({xmin},{ymin},{xmax},{ymax})) if xmin 0 or ymin 0 or xmax w or ymax h: print(f[越界] {xml_file} {name} 圖像尺寸({w},{h}) 框({xmin},{ymin},{xmax},{ymax}))邏輯說明逐 XML 解析先確認對應圖像存在再讀圖像寬高最后對每個 object 做坐標合法性判斷。參數說明voc_dir和img_dir按你實際路徑改如果類別名不是ebike腳本不關心名字只查坐標所以不用改類別相關邏輯。跑完如果輸出很多越界說明標注時可能用了縮放后的圖需要統(tǒng)一回原圖坐標。3. 從 VOC 轉 YOLO轉換腳本、歸一化參數與四個邊界坑3.1 轉換腳本的核心邏輯與類別映射VOC 轉 YOLO 的公式很簡單x_center (xmin xmax) / 2 / wy_center (ymin ymax) / 2 / hwidth (xmax - xmin) / wheight (ymax - ymin) / h。但寫腳本時最容易翻車的是類別索引和文件名對齊。下面這個腳本直接可用import os import xml.etree.ElementTree as ET from PIL import Image voc_dir dataset/annotations_voc img_dir dataset/images out_dir dataset/labels_yolo classes [ebike] # 按 classes.txt 順序 os.makedirs(out_dir, exist_okTrue) for xml_file in os.listdir(voc_dir): if not xml_file.endswith(.xml): continue tree ET.parse(os.path.join(voc_dir, xml_file)) root tree.getroot() img_name root.find(filename).text img_path os.path.join(img_dir, img_name) w, h Image.open(img_path).size lines [] for obj in root.findall(object): name obj.find(name).text if name not in classes: print(f[未知類別] {xml_file} - {name}) continue cls_id classes.index(name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) x_center (xmin xmax) / 2.0 / w y_center (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) out_name os.path.splitext(xml_file)[0] .txt with open(os.path.join(out_dir, out_name), w) as f: f.write(\n.join(lines))邏輯說明先建輸出目錄逐 XML 讀圖像尺寸再對每個 object 做歸一化最后按同名 txt 寫出。參數說明classes列表必須和classes.txt完全一致順序不能錯:.6f保留六位小數YOLO 訓練時精度足夠不要用科學計數法。3.2 轉換后必須做的三項校驗轉完不是就完了至少做三件事第一隨機抽 10 個 txt用cat看有沒有空文件或者坐標超過 1第二用 Python 統(tǒng)計每個 txt 的行數和 XML 里 object 數量對比不一致的記下來第三把 YOLO 格式反畫回圖上肉眼確認框位置沒偏。反畫腳本很多核心就是x_center*w還原成像素坐標再畫矩形。這一步能抓住 90% 的轉換錯誤。3.3 四個邊界坑空標注、截斷框、類別名大小寫、文件名空格空標注有些圖可能沒有電瓶車XML 里沒有 object轉出來是空 txt。YOLO 訓練時空 txt 是合法的負樣本但如果你數據集里全是正樣本突然混入空文件要確認是不是漏標。截斷框電瓶車只露出一半時標注可能貼著圖像邊緣歸一化后坐標接近 0 或 1訓練時要注意 YOLO 的rect推理模式可能裁掉邊緣。類別名大小寫Ebike和ebike在 Python 里是兩個字符串映射會失敗統(tǒng)一用小寫。文件名空格如果圖像文件名帶空格XML 里filename可能被截斷轉換時讀不到圖建議批量重命名去掉空格。4. 用 YOLOv8/v11 訓練 200 張電瓶車數據參數怎么設、多久能收斂4.1 環(huán)境配置與數據 YAML 寫法ultralytics 環(huán)境配置不復雜但版本要對齊。常見做法是 Python 3.9pip install ultralyticsGPU 驅動和 CUDA 按你機器來。數據 YAML 文件這樣寫path: /abs/path/to/dataset train: images val: images names: 0: ebike200 張圖train 和 val 都指向images是無奈之舉因為量太少再切 20% 驗證就只剩 160 張訓練模型根本學不動。更合理的做法是train 用全部 200 張val 也用全部 200 張只看 loss 和訓練集 mAP當作過擬合驗證。等有更多數據再切分。4.2 訓練命令與關鍵參數解釋yolo detect train \ datadataset.yaml \ modelyolov8n.pt \ epochs200 \ imgsz640 \ batch8 \ lr00.001 \ patience50 \ device0modelyolov8n.pt用 nano 版200 張圖用大模型純屬浪費。epochs200是因為數據少需要多輪才能記住但patience50防止過擬合后繼續(xù)跑。batch8看顯存8G 顯存跑 640 分辨率 batch 8 沒問題。lr00.001比默認 0.01 小小數據集用大學習率容易震蕩。imgsz640是 YOLO 默認電梯場景電瓶車占畫面比例不小640 夠用。4.3 訓練過程看什么loss 曲線、mAP50 和混淆矩陣200 張圖訓練loss 下降快是正常的可能 30 輪就降到很低。重點看mAP50有沒有到 0.8 以上如果一直在 0.5 徘徊大概率是標注問題或者類別映射錯了?;煜仃囋趓uns/detect/train/下如果出現(xiàn)大量背景誤檢說明電梯里其他物體比如人、推車被誤判成電瓶車需要加負樣本。訓練完的results.csv可以用 pandas 讀出來畫圖看有沒有過擬合。5. 避坑與排查200 張小數據集訓練電瓶車檢測的 5 個真實翻車記錄5.1 現(xiàn)象訓練 loss 正常降但推理時框全圖亂飛原因VOC 轉 YOLO 時坐標沒歸一化或者歸一化用了錯誤的寬高比如用了縮放后圖像的尺寸。解決回頭檢查轉換腳本確認w, h來自原圖且x_center等值都在 0~1 之間。用cat看一個 txt如果出現(xiàn)大于 1 的數就是沒歸一化。5.2 現(xiàn)象mAP50 始終為 0但 loss 在降原因類別索引不匹配。YAML 里names: 0: ebike但 txt 里寫的是1或者 VOC 里類別名是Ebike而 classes 列表寫的是ebike。解決統(tǒng)一類別名大小寫檢查classes.txt、YAML 和轉換腳本里的classes列表三者一致。5.3 現(xiàn)象驗證集 mAP 很高但實際電梯監(jiān)控畫面里檢測不到原因200 張圖可能來自同一部電梯、同一角度、同一光照模型過擬合到背景。解決如果條件允許拿幾段不同電梯的監(jiān)控截圖做測試不要只看驗證集。沒有新數據的話至少做數據增強比如hsv_h0.015、hsv_s0.7、hsv_v0.4、fliplr0.5在 YAML 里加augment: True。5.4 現(xiàn)象訓練時提示No labels found原因YOLO 默認在images同級找labels目錄但你的 txt 放在labels_yolo。解決要么把labels_yolo改名為labels要么在 YAML 里用train: images和val: images的同時確保 ultralytics 能通過路徑替換找到標簽。最穩(wěn)的辦法是目錄結構改成images/train和labels/train但 200 張圖沒必要直接改名labels最快。5.5 現(xiàn)象推理時電瓶車被切成兩半只框住一半原因電瓶車在電梯里可能被門或人遮擋標注時只標了可見部分模型學到的是部分特征。解決標注時盡量標完整車身遮擋嚴重就標可見部分并在訓練時用mosaic增強讓模型適應遮擋。YOLO 默認開啟 mosaic不用額外設。6. 200 張之后把電瓶車檢測推到可用的三個進階技巧200 張圖跑通訓練只是起點真要放到電梯里用還得做三件事。第一用訓練好的模型對未標注的電梯監(jiān)控視頻做推理把置信度高于 0.6 的幀自動保存人工篩選后加入訓練集這是最省力的數據擴充方式。第二導出 ONNX 或 TensorRT 模型在邊緣設備上測幀率電梯場景不需要 30 幀5 幀就夠報警但延遲要低。第三加一個簡單的跟蹤邏輯連續(xù) 3 幀檢測到電瓶車才觸發(fā)報警避免單幀誤檢導致誤報。我自己的習慣是每次擴充數據后重新訓練時把lr0再降一半因為新數據分布和老數據有差異小學習率更穩(wěn)。希望幫到你。本文還有配套的精品資源點擊獲取