恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

猪只行为识别分割数据集实战:labelme格式解析与训练

  • 首页
  • 资讯中心
  • /
  • 猪只行为识别分割数据集实战:labelme格式解析与训练

相关资讯

开源命令行代码评审工具:基于Git Diff与LLM Agent的自动化Code Review实践 2026/10/19 8:48:41
OpenClaw云服务器部署指南:从源码编译到systemd与Nginx反向代理 2026/10/19 8:48:41
LoRA推理部署实战:合并权重还是动态挂载,选对方案再动手 2026/10/19 8:48:41

最新资讯

扫码打不开?问题不在二维码,而在被拦截的链接背后
SLR语法分析器原理与手写实现:从文法改造到Python代码
Spark核心机制自查:RDD依赖、Stage划分与数据倾斜调优
diagram-design:用契约图驱动系统确定性的工程方法论
Diagram-Design:用可执行架构图驱动系统开发与治理
从零开始手工木作:黑胡桃木山形收纳盘制作全攻略

今日推荐

OpenCowork 实测:支持本地文件、飞书机器人的 Windows AI 助手(只需配置 Token)
GPT-6 Sol 与 Luna 怎么选?Chat、Work、Codex 版本差异与 TaoToken 接入实测
openclaw.net 集成 ElBruno.MempalaceNet 记忆系统:把 MCP 配置改到 TaoToken 的完整实践

本周热门

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

猪只行为识别分割数据集实战:labelme格式解析与训练

发布时间:2026/10/19 8:48:41
猪只行为识别分割数据集实战:labelme格式解析与训练 自己做猪舍巡检项目的时候最头疼往往不是模型结构而是标注数据。尤其是“猪只行为识别”这种偏垂直的场景公开数据集本来就少想找一份带像素级标注、又是实际圈舍环境拍摄的料基本靠运气。最近从一个朋友那边拿到一份“智慧养殖猪只行为识别分割数据集labelme格式1085张4类别”翻来覆去用了一周给我的感觉是这类数据集的参考价值很多时候比模型框架本身还要稀缺。这篇就聊点实在的——这个数据集背后到底怎么用、labelme格式怎么解析、怎么转成训练能用的格式以及我在实际过程中踩过的那些坑。1. 这个数据集到底解决什么问题1.1 智慧养殖里为什么要做“行为识别”养猪这个行业过去靠人的眼睛和经验现在靠摄像头和算法。猪只的行为状态比如说站立、行走、躺卧、进食直接关系到它的健康指数、应激反应、发情状态甚至圈舍环境是否合适。举个例子一头猪长时间躺着不动可能是发烧或者肢蹄有问题一头猪反复站起又卧下可能是环境温度不合适一头猪频繁靠近饲槽但不进食可能是饲料适口性或饮水系统出了问题。这些信号如果靠人工去盯监控画面24小时不间断不现实所以需要用算法去做持续的行为分析。行为识别本质上是一个“分类定位”的任务既要判断这是什么行为还要在画面里找到对应的猪只个体。但如果只做检测级别的矩形框问题马上就来了——圈舍里猪与猪之间经常叠在一起栏位栅栏会遮挡身体一个矩形框里通常包含好几头猪的部分区域。框这个东西用在个体计数上还行用在行为判断上就太粗了。所以很多落地项目里我推荐的做法是把任务升级为实例分割在像素级上把每一头猪的形状圈出来再基于轮廓去判断行为。1.2 为什么偏偏用“分割”标注而不是目标框这份数据集选择labelme格式、使用多边形轮廓标注背后的逻辑其实不复杂。分割标注相比检测框多出来的信息量非常大猪的身体轮廓能直接反映姿态站立和躺卧在轮廓上的长宽比差异非常明显。行为状态的判定往往依赖局部细节比如“进食”这个类别头部区域伸向饲槽的部分必须被精确区分出来矩形框会把饲槽、栏杆一起框进目标里反而干扰分类。分割mask可以进一步计算面积、中心点、方向角度、形变程度等维度这些是后续做行为时序分析的特征基础。所以在实际项目中我拿到一份分割数据集哪怕第一版模型跑的是检测最终也一定会往分割方向迁移。这就是这类“精细标注”数据集的价值所在。2. 数据集的底细1085张、4类别怎么落实到项目里2.1 “4类别”的行为定义与边界“4类别”是这份数据集最核心的信息。根据不同养殖场景的标注习惯常见的行为分成以下几类类别行为定义标注要点standing站立状态四肢支撑身体身体基本垂直地面没有明显位移轮廓必须包含四肢的支撑区域避免和躺卧混淆walking行走状态四肢交替移动位置发生明显变化常伴随前后腿前后分开的轮廓特征lying躺卧状态身体一侧或腹部接触地面四肢弯曲或伸展轮廓通常为扁平状注意和阴影区域区分feeding进食状态头部伸向饲槽或正在咀嚼、吞咽头部和颈部区域必须完整这个类别的分割难度最高我在实际标注中遇到过一个问题“站立”和“行走”在单帧图像上其实不好区分。严格来讲行走是一个时间序列动作单帧里可能出现四肢支撑、身体微倾的瞬间却看不出位移。所以这类数据集在制作时通常会基于视频抽帧来辅助判断如果这一帧前后几帧猪只位置发生变化就标成walking如果持续不动标成standing。使用数据集时要注意如果你自己也做时序模型可以考虑把这两类合并成“active状态”再单独用帧间差分去细分。2.2 1085张到底算多还是少1085张说多不多说少其实也不算太少。它属于典型的“中小规模专用数据集”。深度学习图像分割模型如果用COCO这种大规模预训练权重做迁移学习几千张级别就能微调出可用的效果但如果是完全从零训练这个量级肯定不够。要判断这个规模是否够用得看两个因素场景多样性。如果这1085张都来自同一个摄像头、同一个栏位、同一个时间段那模型泛化到其他圈舍时会明显变差。这种数据集适合做“场景内验证”不适合直接跨场部署。标注的实例密度。一张图里如果有5到10头猪那么总实例数可能在5000到10000个以上单类别实例量还算可观。我拿到数据后第一件事就是统计每个类别的实例数量而不是只看图片张数因为分割模型学的是实例特征不是图片特征。如果实例数量偏少后续可以用视频抽帧扩充、复制粘贴增强、跨场景微调等方式补数据。1085张本身不是天花板而是一个起点。2.3 训练集/验证集/测试集的划分策略很多人拿到数据集直接按8:1:1随机切分这是不推荐的。原因是同一段视频里抽出来的连续帧非常相似随机划分会让验证集和训练集之间的信息重叠过高导致指标虚高模型实际泛化性被高估。我的做法是先把所有图片按视频时间段或拍摄批次分组。以组为单位划分保证同一个时间段的图片只出现在一个集合里。比例建议训练集70%、验证集15%、测试集15%如果有条件测试集最好来自完全不同的圈舍或日期。这样划分出来的性能指标才能真实反映模型在新场景下的表现。3. labelme格式的完整拆解与格式转换实操3.1 labelme标注文件长什么样拿到数据后你会发现每张图片旁边都带有一个同名.json文件这就是labelme的标准输出格式。打开一个典型的文件结构大致如下{ version: 4.5.6, flags: {}, shapes: [ { label: lying, points: [[512.3, 384.1], [521.7, 389.2], [533.2, 396.8]], group_id: 1, description: , shape_type: polygon, flags: {} }, { label: standing, points: [[701.0, 302.4], [715.2, 310.6], [728.9, 312.3]], group_id: 2, shape_type: polygon, flags: {} } ], imagePath: frame_00123.jpg, imageData: null, imageHeight: 1080, imageWidth: 1920 }几个关键字段值得注意shapes数组里每个元素就是一个实例对象。每个实例的label字段是类别名points是多边形顶点坐标shape_type一般是polygon。group_id表示实例的编号同一头猪在不同帧里的group_id如果一致说明标注者做了跨帧关联这个信息很有价值。imageData通常为null图片内容不会内嵌到JSON里所以图片和JSON的路径匹配就变得非常重要。imageHeight和imageWidth是标注时的图像尺寸但我在实际转换时不太信任这两个字段因为可能存在缩放、裁剪后没更新的情况。3.2 转成COCO JSON格式的脚本现在的实例分割框架不管是MMDetection还是Detectron2都原生支持COCO格式。所以我拿到labelme数据后的第一步通常是转成COCO JSON。这里给出一份可以直接改造的参考脚本import json import os import glob from PIL import Image from pycocotools import mask as maskUtils def labelme_to_coco(labelme_dir, output_path, category_mapping): json_files glob.glob(os.path.join(labelme_dir, *.json)) images [] annotations [] img_id 1 ann_id 1 for jf in json_files: with open(jf, encodingutf-8) as f: label json.load(f) img_path os.path.join(labelme_dir, label[imagePath]) img Image.open(img_path) width, height img.size images.append({ id: img_id, file_name: os.path.basename(img_path), width: width, height: height }) for shape in label[shapes]: if shape[shape_type] ! polygon: continue category_name shape[label] if category_name not in category_mapping: continue category_id category_mapping[category_name] points shape[points] # COCO segmentation需要扁平化坐标 segmentation [coord for pt in points for coord in pt] xs [pt[0] for pt in points] ys [pt[1] for pt in points] x_min, x_max min(xs), max(xs) y_min, y_max min(ys), max(ys) bbox [x_min, y_min, x_max - x_min, y_max - y_min] # 用RLE计算面积比直接算多边形面积更稳 rle maskUtils.frPyObjects([segmentation], height, width) area float(maskUtils.area(rle[0])) annotations.append({ id: ann_id, image_id: img_id, category_id: category_id, bbox: bbox, area: area, segmentation: [segmentation], iscrowd: 0 }) ann_id 1 img_id 1 coco_json { images: images, annotations: annotations, categories: [ {id: idx, name: name} for name, idx in category_mapping.items() ] } with open(output_path, w, encodingutf-8) as f: json.dump(coco_json, f) if __name__ __main__: # 类别名按JSON里的实际标注情况修改 mapping { standing: 1, walking: 2, lying: 3, feeding: 4 } labelme_to_coco(./labelme_data, ./output_coco.json, mapping)这段脚本有几个容易忽略的细节我使用的是Image.open重新读取图片宽高而不是直接读JSON里的imageHeight和imageWidth。原因前面说了JSON里的尺寸可能没同步更新。用pycocotools的RLE方式计算面积可以避免多边形退化、自相交时面积计算不准的问题。segmentation要求是二维列表的坐标展平形式这里写的是[segmentation]形状是“单实例多边形”的标准格式别漏了这一层括号。3.3 转成YOLO分割格式的脚本如果你用的是YOLOv8-seg这类模型需要的是目标检测式的txt标注格式。每个实例一行格式为class_id x1 y1 x2 y2 ... xn yn坐标全部归一化到0到1。转换代码如下def labelme_to_yolo_seg(labelme_dir, output_dir, category_mapping): os.makedirs(output_dir, exist_okTrue) for jf in glob.glob(os.path.join(labelme_dir, *.json)): with open(jf, encodingutf-8) as f: label json.load(f) img_path os.path.join(labelme_dir, label[imagePath]) img Image.open(img_path) w, h img.size txt_name os.path.splitext(os.path.basename(jf))[0] .txt out_txt os.path.join(output_dir, txt_name) with open(out_txt, w) as f: for shape in label[shapes]: if shape[shape_type] ! polygon: continue category_name shape[label] if category_name not in category_mapping: continue class_id category_mapping[category_name] norm_points [] for x, y in shape[points]: nx round(x / w, 6) ny round(y / h, 6) norm_points.extend([nx, ny]) line f{class_id} .join(map(str, norm_points)) f.write(line \n)YOLO分割格式有个小坑多边形顶点顺序必须按顺序连接并且第一个点和最后一个点不要重复存储。labelme里的polygon顶点通常已经是按边界顺序排列的直接转换即可但如果发现mask出现“打结”情况要考虑检查顶点顺序是否逆时针或者是否出现了交叉点。4. 从数据集到模型训练和评估的实操路线4.1 直接能跑起来的模型选择在拿到这份labelme数据集之后训练一个分割模型有几条路线可以选择我按部署场景分别说下方案适用场景优点缺点Mask R-CNN服务器端离线分析成熟稳定社区资料多推理速度一般边缘设备跑不动SOLOv2对实例数量敏感的场景不需要框分支掩码质量较高对重叠严重区域偶尔会出现漏检YOLOv8-seg边缘设备实时检测速度快部署方便分割边缘精细度略弱SAM微调零样本预标注后精修标注成本低适合做新类别发现训练成本高微调流程复杂我个人经验是如果是刚拿到数据集做可行性验证先用Mask R-CNN或YOLOv8-seg快速跑通一个baseline。不要一上来就堆结构复杂的模型因为数据集质量还没有验证过模型再复杂也补不了标注错误。先用baseline把问题暴露出来再针对性地优化模型和清洗数据这才是高效路径。4.2 数据增强是做分割的关键1085张的规模直接训练很容易过拟合。分割任务的数据增强和检测不太一样有个核心要求图像变换和mask变换必须同步否则标注就错位了。生效的增强组合我建议这样配置随机水平翻转猪只身体左右对称性高翻转不会破坏语义但注意不要翻转文本、水印等非对称区域。小角度随机旋转±10度以内圈舍摄像头安装角度会有偏差旋转增强能提升泛化性。随机亮度对比度调整猪舍的光照条件一天内变化明显尤其是早晚侧光、走廊灯光反射。随机裁剪缩放模拟摄像头距离变化和画面构图差异。马赛克增强把多张图拼接成一张训练样本对小数据集非常有效。不推荐的增强包括大幅度旋转猪只会变成倒着的姿态语义被破坏、随机擦除会把猪身体的一部分擦掉行为类别信息丢失、颜色反转破坏物体视觉语义。4.3 训练参数与评估指标怎么设训练分割模型输入尺寸建议统一到模型可接受的范围。比如Mask R-CNN通常用1333×800的动态尺寸YOLOv8-seg可以用1280×1280。对1085张的数据集来说训练轮次不宜太少至少要40到60轮配合早停机制防止过拟合。初始学习率用2e-4附近配合warmup策略冻结骨干网络前几轮是标准做法。评估指标方面不要只看mAP0.5。行为识别的核心诉求是“知道每头猪在干什么”所以我会额外关注每个类别的mask AP重点关注feeding是否显著低于其他类别如果是说明头部靠近饲槽的遮挡区域需要额外补充训练数据。分类混淆矩阵特别区分standing和walking之间、lying和standing之间的错误判断。mask边缘的IoU分割结果边缘粗糙会把面积信息带歪影响后续行为特征提取。我在训练后习惯做一个可视化输出把模型预测的mask叠加到原图上与标注mask对照按类别分别打印错误样本。这一步看起来费时间但能帮你快速发现训练数据里的系统性问题比盯着指标看有效得多。5. 实际用这个数据集踩过的坑5.1 标注和图像对不上的老问题第一个踩到的坑是文件名匹配。labelme导出的JSON文件名和图片文件名通常是一致的但偶尔会遇到图片被重命名、或者路径前缀修改的情况。加载数据时报错一查才发现JSON里的imagePath还是旧路径。解决办法很简单在写数据加载脚本时不要直接使用label[imagePath]而是用JSON文件名去掉扩展名再去对应目录找同名图片。如果找不到再回退到JSON里的路径字段。这个双保险能避免绝大多数文件匹配错误。5.2 类别不平衡怎么解决在这类行为识别数据集中类别不平衡几乎是必然的。躺卧类往往占了将近一半因为猪群在舒适环境下大部分时间在睡觉进食和行走类占比可能只有百分之十几。直接拿原始分布训练模型会对躺着这个类别产生强烈偏置。我处理类别不平衡有三招训练时对每个类别做采样器加权让batch里各类别实例数量尽量均衡。对少数类别的训练图做额外增强比如把walking类的图片多复制几次副本增强比例提高。行为类别可以重新组织宏观类别比如先训练一个“静态/动态”二分类器再细分具体行为这样每个子任务的数据分布会更平衡。5.3 光照、遮挡、栏位干扰圈舍环境里的分割难度比想象中要高。猪栏的金属栅栏会横穿过猪的身体牛羊猪腿被栅栏隔断是常见现象地面水渍会反射灯光在mask边缘形成高亮区域红外摄像头图像缺乏颜色信息纹理对比度低分割模型在边缘区域的预测容易抖动。应对这些干扰我的建议是训练时不要把原图直接resize得太小比如用1280分辨率让栅栏横条和猪腿的边界保留足够像素。后处理阶段可以采用条件随机场做边缘平滑或者用形态学操作去除小块噪点。对有严重遮挡的个体优先保证分割主体躯干区域的准确性四肢局部被遮挡可以阈值放宽不要为了抠出被栅栏遮挡的腿而牺牲整体轮廓。5.4 labelme工具本身的几个坑labelme标注工具本身很轻量但大规模使用时也会遇到一些琐碎问题问题现象解决方式标注点过多多边形顶点动辄几百个文件体积大转换慢使用Douglas-Peucker算法做轮廓简化为20~50点JSON和图片不同名加载时报缺失按文件名匹配并校验中文路径报错读取失败或写入乱码统一用英文目录不要用中文和空格标注遗漏目标个别猪只没被标注训练前做可视化抽查对照原图逐张检查标签名不统一有的叫standing有的叫stand用脚本把同义标签合并成固定词汇表如果你打算用这个数据集做项目而我前面提到的那份转换脚本建议先做一步可视化检查把每个mask用随机颜色叠加到原图上人工抽看30到50张确认类别名、多边形贴合度、遮挡区域都合理后再进入训练流程。这一步看似增加时间实际上能省下后面调试模型的大量精力。我个人在拿到数据集之后通常不会急着开训。我会先花半天时间做数据清洗、格式转换、可视化验证把数据集的底摸清楚。这种小规模专用数据集最大的价值不是“量大”而是类别定义和场景针对性够强。只要你把标注解析、格式转换、类别平衡这些基础工作做扎实了后面训练模型的过程会顺畅很多。如果后续有条件建议基于视频流把单帧的mask关联成时序轨迹那样做出来的行为识别系统在落地场景里的实用性会有质的提升。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号