尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
夜间老鼠检测数据集:VOC+YOLO双格式316张图565框实战指南
简介本资源为夜间老鼠检测数据集面向从事目标检测算法训练与验证的开发者、学生及科研人员可用于夜间场景下的老鼠识别模型训练与效果评估。数据集采用Pascal VOC与YOLO双格式标注包含316张jpg图片及一一对应的316个xml与316个txt标注文件标注类别为laoshu共565个矩形框使用labelImg工具完成标注另附1个mp4视频文件可供直观查看夜间目标表现。压缩包为7z格式共951个文件涵盖318个txt、316个xml、316个jpg及1个mp4整体约91.81MB目录结构清晰便于直接接入常见检测框架。目前已有312人学习下载适合需要快速获取夜间小目标样本、验证数据标注流程或补充训练集的读者参考使用。1. 夜间老鼠检测数据集316 张图、565 个框这份 VOCYOLO 双格式资源到底能干什么夜间老鼠检测这件事真正卡住人的从来不是模型结构而是数据。白天拍老鼠本来就难夜里红外补光下目标又小、又糊、又爱贴着墙根跑公开数据集里专门做夜间鼠类检测的少得可怜。这份资源给的是 316 张 jpg 图片配套 316 个 Pascal VOC 格式的 xml 标注和 316 个 YOLO 格式的 txt 标注单类别laoshu总框数 565标注工具是 labelImg规则就是对类别画矩形框。另外还附了 1 个视频文件方便你直接拿来做推理演示或者抽帧扩充。它适合谁做智慧农业、粮仓监测、餐饮后厨虫鼠害巡检、实验室动物行为记录这类场景的算法同学尤其是想快速跑通「夜间小目标检测」全流程、又不想从零标数据的人。316 张不算大但胜在格式齐全、标注干净拿来验证 YOLO 训练链路、做迁移学习冷启动、或者当一个小规模 benchmark 都够用。需要提前说清楚数据集本身不对训练出来的模型精度做任何保证它提供的是准确且合理的标注模型效果取决于你的训练策略和场景匹配度。2. VOC 与 YOLO 双格式拆解为什么同一批图要存两套标注2.1 两种格式的本质差异与选型理由Pascal VOC 和 YOLO 格式描述的是同一件事——目标框的位置和类别但坐标系和存储方式完全不同。VOC 用 xml存的是绝对像素坐标xmin, ymin, xmax, ymax一个目标一个object节点可读性强方便人工核对和二次编辑。YOLO 用 txt每行一个目标格式是class_id x_center y_center width height全部归一化到 0~1 之间一个文件对应一张图训练时直接读省去解析 xml 的开销。这份资源两套都给好处很直接你想用 labelImg 继续补标、改框用 xml你想直接喂给 YOLOv5/v8/v11 训练用 txt。不用自己写转换脚本也就避开了转换环节最容易出的坐标错位、类别索引对不上这些坑。常见做法是先用 xml 做数据清洗和可视化核查确认无误后再用 txt 进训练两条链路互不干扰。2.2 目录结构与文件对应关系拿到压缩包解压后典型结构是这样的不同打包方式可能略有差异以实际为准dataset/ ├── JPEGImages/ # 316 张 jpg 原图 │ ├── firc_laoshu_31.jpg │ ├── firc_laoshu_41.jpg │ └── ... ├── Annotations/ # 316 个 VOC xml │ ├── firc_laoshu_31.xml │ └── ... ├── labels/ # 316 个 YOLO txt │ ├── firc_laoshu_31.txt │ └── ... └── video/ # 1 个视频文件关键点是文件名必须一一对应firc_laoshu_31.jpg对应firc_laoshu_31.xml和firc_laoshu_31.txt。训练前一定要做一次完整性校验确认三者的文件名集合完全一致缺一个都会在训练时报「找不到标签」或者静默跳过该样本。我一般会先跑一遍集合比对再开始划分训练集。2.3 用脚本校验标注完整性下面这段脚本做三件事统计 jpg/xml/txt 数量、找出缺失配对、统计总框数是否等于 565。import os from pathlib import Path import xml.etree.ElementTree as ET root Path(dataset) jpg_dir root / JPEGImages xml_dir root / Annotations txt_dir root / labels jpgs {p.stem for p in jpg_dir.glob(*.jpg)} xmls {p.stem for p in xml_dir.glob(*.xml)} txts {p.stem for p in txt_dir.glob(*.txt)} print(fjpg{len(jpgs)} xml{len(xmls)} txt{len(txts)}) # 找出任意一方缺失的样本 missing jpgs ^ xmls | jpgs ^ txts if missing: print(配对异常样本:, sorted(missing)) else: print(三方文件名完全一致) # 统计 VOC 总框数核对是否为 565 total_boxes 0 for x in xml_dir.glob(*.xml): tree ET.parse(x) total_boxes len(tree.getroot().findall(object)) print(fVOC 总框数 {total_boxes})逻辑说明用集合的对称差^快速定位只在某一方出现的文件名比逐个循环比对高效。参数上root指向解压后的数据集根目录如果你的目录名不是JPEGImages/Annotations/labels改成实际路径即可。跑出来VOC 总框数 565就说明标注没丢和简介里的数字对得上。3. 从零跑通 YOLO 训练数据划分、配置与启动3.1 划分训练集与验证集316 张图属于小数据集划分比例不建议用常规的 8:2验证集太小会导致指标抖动大。我一般按 8.5:1.5 划验证集留 45~50 张既能评估又不至于让训练样本太少。划分要随机但固定种子保证可复现。import random from pathlib import Path import shutil random.seed(42) root Path(dataset) stems sorted(p.stem for p in (root / JPEGImages).glob(*.jpg)) random.shuffle(stems) val_ratio 0.15 n_val int(len(stems) * val_ratio) val_stems set(stems[:n_val]) train_stems set(stems[n_val:]) for split, subset in [(train, train_stems), (val, val_stems)]: (root / images / split).mkdir(parentsTrue, exist_okTrue) (root / labels / split).mkdir(parentsTrue, exist_okTrue) for s in subset: shutil.copy(root / JPEGImages / f{s}.jpg, root / images / split / f{s}.jpg) shutil.copy(root / labels / f{s}.txt, root / labels / split / f{s}.txt) print(ftrain{len(train_stems)} val{len(val_stems)})逻辑说明random.seed(42)固定划分结果方便你复现我的实验。val_ratio0.15对应约 47 张验证图。注意 YOLO 训练要求 images 和 labels 目录结构镜像对应脚本里已经按images/train、labels/train建好这是 YOLOv5 之后版本的默认约定。3.2 编写 data.yaml 与类别配置YOLO 训练靠一个 yaml 文件告诉它去哪找数据、有几个类别。这份数据集只有laoshu一类配置极简# data.yaml path: ./dataset train: images/train val: images/val nc: 1 names: [laoshu]参数说明path是数据集根目录train/val是相对 path 的子路径。nc是类别数必须和 names 长度一致写错会在训练启动时直接报错。names里的顺序就是类别索引laoshu对应 class_id 0和 txt 里的 0 必须对上——这是最常见的翻车点之一后面避坑章节会细说。3.3 启动训练与关键超参以 YOLOv8 为例一条命令就能起训yolo detect train \ datadata.yaml \ modelyolov8n.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ patience30 \ projectruns/laoshu \ nameexp1参数说明modelyolov8n.pt用 nano 版做迁移学习冷启动316 张图从零训容易过拟合预训练权重能显著稳住早期 loss。epochs150配合patience3030 轮没提升就早停省时间。imgsz640是通用选择但夜间老鼠目标偏小如果显存够可以试 960 看小目标召回是否提升。batch16按显存调8G 显存跑 640 一般没问题。训练日志里重点盯mAP50和mAP50-95小数据集上前者涨得快、后者涨得慢是正常的。3.4 推理验证与视频测试训练完拿验证集和那个附带的视频文件跑一遍直观看看效果# 图片推理 yolo detect predict modelruns/laoshu/exp1/weights/best.pt sourcedataset/images/val saveTrue # 视频推理 yolo detect predict modelruns/laoshu/exp1/weights/best.pt sourcedataset/video/xxx.mp4 saveTrue逻辑说明saveTrue会把带框结果存到runs/detect/predict下。视频推理能暴露单帧看不出的问题比如目标运动模糊、连续帧漏检、框抖动。如果视频里老鼠移动快导致漏检常见做法是提高输入分辨率或者用跟踪器如 ByteTrack把帧间结果关联起来减少闪烁。4. 避坑与排查小数据集训练最容易栽的五个地方4.1 类别索引对不上loss 死活不降现象训练能启动但 loss 长期在 1.0 以上震荡mAP 接近 0。原因txt 里的 class_id 和 data.yaml 的 names 顺序不一致比如标注时laoshu被写成了 1 而不是 0。解决跑一段脚本扫所有 txt 的类别列确认取值集合是{0}。from pathlib import Path ids set() for t in Path(dataset/labels).rglob(*.txt): for line in t.read_text().strip().splitlines(): if line: ids.add(int(line.split()[0])) print(出现的类别索引:, ids)如果输出不是{0}就得批量修正或者把 names 按实际索引补齐。4.2 归一化坐标越界框跑到图外现象可视化时框飘到图像边界外或者训练报坐标非法。原因YOLO 要求x_center, y_center, width, height都在 0~1手工转换或工具导出时可能算出负值或大于 1。解决加一段校验把越界框揪出来。from pathlib import Path bad [] for t in Path(dataset/labels).rglob(*.txt): for i, line in enumerate(t.read_text().strip().splitlines()): if not line: continue _, x, y, w, h map(float, line.split()) if not all(0 v 1 for v in (x, y, w, h)): bad.append((t.name, i, x, y, w, h)) print(越界框数量:, len(bad))越界通常是转换脚本没做 clip解决时把坐标裁到 [0,1] 再写回。4.3 验证集太小指标忽高忽低现象每轮 mAP 跳变超过 0.1看不出模型到底行不行。原因验证集只有二三十张单张图里框数差异大统计噪声被放大。解决把验证比例提到 0.15 以上或者用 K 折交叉验证取平均。316 张的规模5 折每折验证约 63 张指标会稳很多。4.4 夜间小目标漏检严重现象白天或亮场景召回还行夜间红外图里小老鼠大量漏检。原因目标像素面积小下采样后特征几乎消失。解决提高imgsz到 960 或 1280在数据层做 mosaic、mixup 增强模型侧可以换带 P2 小目标检测头的结构。注意增强别开太猛316 张本来就少过强增强反而让模型学不到真实分布。4.5 视频推理帧间抖动现象单帧检测框位置还行但视频里框一直跳。原因逐帧独立检测没有时序约束小目标置信度在阈值附近反复横跳。解决接一个跟踪器做 ID 关联或者对置信度做滑动平均。如果只是做演示把conf阈值从默认 0.25 提到 0.4 也能压掉一部分抖动代价是召回略降。5. 把 316 张用出 3000 张的效果小数据集的进阶玩法316 张图直接训模型很容易记住背景而不是目标。我踩过的坑是第一版模型在验证集上 mAP50 冲到 0.9换到真实夜间监控视频里直接崩原因就是过拟合了训练场景的红外纹理。后来我固定了一套流程把这份数据集的价值榨到最大。第一招是离线增强扩样。不是靠训练时的在线增强而是用 albumentations 把训练集先扩 3~5 倍落盘重点加亮度扰动、高斯噪声、随机裁剪模拟不同红外相机的成像差异。扩样后训练集能到 1000 张以上验证集保持原图不动这样评估才干净。import albumentations as A import cv2 from pathlib import Path aug A.Compose([ A.RandomBrightnessContrast(brightness_limit0.3, contrast_limit0.3, p0.7), A.GaussNoise(var_limit(10, 50), p0.5), A.HorizontalFlip(p0.5), A.RandomCrop(height480, width480, p0.3), ], bbox_paramsA.BboxParams(formatyolo, label_fields[cls])) src Path(dataset/images/train) dst Path(dataset/images/train_aug) dst.mkdir(parentsTrue, exist_okTrue) for img_path in src.glob(*.jpg): img cv2.imread(str(img_path)) h, w img.shape[:2] lbl Path(dataset/labels/train) / f{img_path.stem}.txt boxes, cls [], [] for line in lbl.read_text().strip().splitlines(): c, x, y, bw, bh line.split() boxes.append([float(x), float(y), float(bw), float(bh)]) cls.append(int(c)) for i in range(3): # 每张扩 3 份 r aug(imageimg, bboxesboxes, clscls) cv2.imwrite(str(dst / f{img_path.stem}_aug{i}.jpg), r[image]) with open(Path(dataset/labels/train_aug) / f{img_path.stem}_aug{i}.txt, w) as f: for b, c in zip(r[bboxes], r[cls]): f.write(f{c} { .join(f{v:.6f} for v in b)}\n)参数说明RandomCrop会裁掉部分目标BboxParams自动过滤掉裁后不完整的框避免产生脏标签。var_limit控制噪声强度夜间图本身噪点多适度加噪能提升鲁棒性但别超过 50否则目标被淹没。第二招是用视频抽帧补数据。附带的那个视频文件别浪费用 ffmpeg 按固定间隔抽帧人工筛掉无鼠帧后补标能快速增加场景多样性。抽帧命令ffmpeg -i dataset/video/xxx.mp4 -vf fps2 dataset/frames/%04d.jpgfps2表示每秒抽 2 帧夜间老鼠移动慢这个频率够用抽太密会有大量重复帧。第三招是冻结骨干做线性探测。数据少的时候先冻结 backbone 只训检测头 20 轮再解冻全量微调比一上来就全量训稳定得多。YOLOv8 里可以通过freeze参数控制冻结层数先freeze10跑一轮观察 loss 平稳后再放开。验证方法上我习惯留一个「跨场景测试集」——从视频里抽的、和训练图不同机位的帧单独评估。训练集 mAP 和跨场景 mAP 的差距才是这份数据集真实可用性的体现。差距在 0.15 以内算健康超过 0.3 就说明过拟合严重得回去补数据多样性。从那以后我每次拿到小数据集都强制先跑一遍完整性校验、再划一个跨场景验证集最后才动模型结构。数据这关没过调参就是玄学。希望这份拆解能帮你少走点弯路把这份夜间老鼠数据集真正用起来。本文还有配套的精品资源点击获取
RELATED

相关推荐

GitHub Trending日榜观察:AI工具、本地应用与学习资源趋势解析

GitHub Trending日榜观察:AI工具、本地应用与学习资源趋势解析

早上七点出头,我照例打开GitHub的Trending页面,准备给今天的技术雷达做个晨检。2026年9月29日,周二,这份日榜比我预想的更有意思:前排依旧是AI相关项目的天下,但仔细看下来,上榜的仓库类型和三个…

📅 2026/10/4 8:02:52
UVM序列响应与寄存器模型:从八个包卡死到镜像值同步实战解析

UVM序列响应与寄存器模型:从八个包卡死到镜像值同步实战解析

写这个UVM和SystemVerilog系列笔记已经到第四期了。前几期把验证环境的基本骨架、objection机制、sequence和driver之间的握手流程、还有factory和config_db的常见用法都过了一遍,评论区有不少朋友催更,也有人私信问“为啥我的sequence回包没处理&#x…

📅 2026/10/4 8:02:52
插件系统从加载失败到排查:IAR、Web Boot与MusicFree实战拆解

插件系统从加载失败到排查:IAR、Web Boot与MusicFree实战拆解

做了这么多年开发,我早就把“插件”这个词从功能名词变成了排障关键词。plugins这个标签背后,既有嵌入式IDE里那些帮你多长一只手的功能扩展,也有Web应用启动时那一行让人头皮发麻的加载报错,还有音乐播放器里充满黑话的“接口模板…

📅 2026/10/4 8:02:52
MORE NEWS

更多资讯

📰

工行和招行FDE实践:WorkBuddy 金融智能体平台 × 银行合作 Skills 深度梳理

核心定义:Skill 是可独立调用、标准化封装的原子业务能力;专家 Skill 业务角色人设;专家团 多个专家 / 多个 Skill 编排成完整业务流水线。WorkBuddy 金融版面向银行场景,基于 MCP 协议连接外部数据源连接器,把信贷…

📰

番茄小说/起点中文网 AI 写作约攻略(2026)

越来越多的作者开始用 AI 辅助创作,但签约率参差不齐。核心原因不是"能不能用 AI",而是"怎么用 AI"。这篇攻略详解主流平台签约要求和 AI 辅助创作的实战技巧。 一、主流平台签约要求对比平台类型签约门槛收益模式AI 态度番茄小说免…

📰

鸿蒙 ACL 权限申请踩坑:差点白交一批,最后 3 项一次通过

直接说结论:**鸿蒙上不是所有「看起来像受限」的权限都要申请 ACL;真正要走 ACL 的只有 3 项,我一次申请、全部通过。**但在这之前,我差点因为「凭印象申请」,把一批根本不用交的权限白交上去。 如果你也准备鸿蒙上架、…

📰

不烧心代码智能体:轻量级自治系统设计与落地实践

1. 项目概述:什么是“不烧心代码智能体”?“不烧心代码智能体”——这名字一出来,我就笑了。不是因为它玄乎,而是太真实了。干过三年以上开发、带过小团队、改过祖传代码的同行,看到“不烧心”三个字,手指会…

📰

插件机制详解:从IAR、Harness到MusicFree,排查加载失败的通用方法

上周在几个技术群里看同一类问题反复出现:有人说装完工具一启动就报failed to load plugins web boot: 2 entries did not activate,有人在问“iar plugins 是干什么的”,还有人在折腾musicfree plugins。表面看互不相干,骨子里都…

📰

【抽象代数概念速查】ideal in commutative ring-交换环中的理想

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬