ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv11野生动物追踪与栖息地分析:从目标检测到生态应用

YOLOv11野生动物追踪与栖息地分析:从目标检测到生态应用 简介这是一份面向环保监测与野生动物保护领域开发者的YOLOv11实战技术文档聚焦如何利用单阶段目标检测算法构建野生动物追踪与栖息地分析系统帮助读者掌握从环境数据采集、YOLOv11模型训练到系统集成与案例验证的完整链路。压缩包内含1个PDF文件大小仅2.53MB文档共42页支持目录跳转章节结构清晰便于按需查阅。文档从环保监测背景与意义讲起系统梳理YOLO系列发展历程及YOLOv11网络结构、损失函数并逐层设计野生动物追踪系统和栖息地分析系统涵盖定位设备与传感器选型、遥感影像与地理信息数据处理、栖息地适宜性评估模型构建等随后给出开发环境搭建、数据收集与预处理、模型训练与优化方法并通过案例实战展示野生动物识别、活动轨迹分析及栖息地质量评估结果形成从原理到落地的闭环。目前已有61人学习适合从事智能环保监测、生态数据分析及目标检测应用的技术人员参考。1. 野生动物监测与YOLOv11一张红外照片背后的自动化流程保护区里一台红外相机架一个月能拍回两三万张照片一半是晃动的树枝和空镜头。以前这些照片靠人一张张看熟练标注员一天顶多筛两千张看久了眼花漏检率跟着涨。YOLOv11野生动物追踪与栖息地分析系统就是把这个流程自动化的环保监测新方案——用YOLOv11做检测主干把动物从照片和视频里找出来再靠追踪把同一只个体的轨迹串起来最后把轨迹落到地理坐标上算出栖息地利用热点。这套方案适合三类人保护区或林场的技术员手上攒了大量红外相机数据等着出生态报告做动物行为学研究的团队需要的不是单张照片而是个体的活动范围还有想拿真实场景练手的目标检测开发者。它不挑设备来源森林里的可见光相机、夜间红外相机、无人机正射影像都能作为输入只是后面要处理的坑不太一样。下面按实际落地的顺序来先把野外影像整理成模型能吃的数据格式再把训练环境配起来跑通第一个模型然后解决推理、结果保存和个体追踪接着讲清理小目标、夜间误检、ID跳变这些坑最后给出一套能说服自己的模型验证方法。2. 把野外影像变成YOLOv11能吃的数据VOC转YOLO格式与四个边界坑野生动物项目的检测精度七成由数据决定而不是模型。跟工业质检那种背景干净、光照稳定的场景不同相机陷阱照片里可能有逆光、雨滴、树叶遮挡同一物种在不同季节的毛色差异极大。如果不先把数据整理扎实后面调YOLOv11的参数全是玄学。2.1 标注来源先用现成数据集还是自己标我的建议是第一版模型永远先用公开数据集跑通流程。像LILA那个相机陷阱数据集里就包含大量真实野外场景的标注类目覆盖了鹿、野猪、狐狸这些常见物种。先用它训练一个基础模型拿到保护区自己的数据后再做增量微调比直接从零标几千张图快得多。如果一定要自己标注工具选labelImg或者Roboflow都行标注格式建议用VOC XML因为后期转YOLO格式的脚本最成熟。自己标之前先想清楚一个问题检测目标是物种级别还是个体级别。YOLOv11的检测框只能告诉你「这是一只鹿」区分「这是哪只鹿」要靠后面的追踪模块所以标注时不需要给每只个体起名字给物种标签就够了把个体身份交给追踪去解决。2.2 VOC转YOLO格式的转换脚本与四个边界坑YOLOv11默认的训练标注是TXT格式每行五个数类别ID、中心点x、中心点y、宽度、高度全部归一化到0到1。VOC的XML格式不一样所以第一步是写转换脚本。这里给一个可用的版本# voc_to_yolo.py import os import xml.etree.ElementTree as ET from glob import glob def voc_to_yolo(xml_path, out_dir, class_names): tree ET.parse(xml_path) root tree.getroot() size root.find(size) # 注意这里要读图片真实宽高而不是xml里的size w float(size.find(width).text) h float(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text # 不在类别映射表里的标注直接跳过避免脏数据混进训练 if name not in class_names: continue cls_id class_names.index(name) # 有difficult标记的样本表示严重遮挡或边界截断转换时直接扔掉 difficult obj.find(difficult) if difficult is not None and int(difficult.text) 1: continue box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) # YOLO格式要归一化的中心点坐标和宽高 x_center (xmin xmax) / 2.0 / w y_center (ymin ymax) / 2.0 / h bw (xmax - xmin) / w bh (ymax - ymin) / h # 框坐标越界时截断到图像边界防止训练时loss算到负坐标 x_center min(max(x_center, 0.0), 1.0) y_center min(max(y_center, 0.0), 1.0) bw min(bw, 1.0 - x_center) bh min(bh, 1.0 - y_center) lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) out_name os.path.basename(xml_path).replace(.xml, .txt) with open(os.path.join(out_dir, out_name), w) as f: f.write(\n.join(lines)) # 用法把所有VOC标注转成YOLO格式 class_names [wild_boar, deer, fox, bird] for xml_path in glob(data/annotations/*.xml): voc_to_yolo(xml_path, data/labels, class_names)这段脚本的逻辑说明先把XML根节点下的size取出来做归一化分母再遍历每个object标注把类别名映射成整数ID把框坐标从绝对像素值换算成归一化的中心点和宽高。最后落盘成与图片同名的TXT文件YOLO训练时就是靠文件名来关联图片和标注的。这里有几个参数和边界处理值得强调。class_names的顺序决定了类别ID训练时YAML里的names顺序必须和这里完全一致顺序错了模型学出来就是张冠李戴。difficult1的样本是我建议直接跳过的因为严重遮挡和截断框会让模型在训练初期收到大量误导信号。框越界的截断处理也很关键相机陷阱里经常拍到动物半个身子在画面边缘XML里原始坐标会超出图像尺寸直接送进去会让归一化坐标超过1.0轻则loss波动重则不收敛。第一坑是EXIF旋转。很多相机拍竖图时靠EXIF里的orientation字段记录旋转方向图片查看器会帮你转正但xml里记录的宽高还是原始像素宽高。如果xml里size是4000x3000实际显示却是3000x4000所有标注坐标就全偏了。解决方法是标注之前先统一把图片用工具转正再做标注。第二坑是跨项目类别名不一致。比如一个数据集里叫boar另一个叫wild_boar合并前必须建统一映射表否则同一个类被拆成两个ID训练模型怎么都学不好。第三坑是GT框的坐标可能在转换时出现xmax小于xmin的脏数据脚本里没有兜底实际项目中我会在循环里加一个if xmax xmin or ymax ymin: continue。第四坑是数据泄漏这个留到第五章细说它比前面三个坑都隐蔽。2.3 类别不均衡怎么在数据集层面先压住野生动物数据天然不均衡松鼠一张存储卡里几百次出现豹子一年拍到两回差距可能有几百倍。这种不均衡如果不在数据层面先处理YOLOv11训练出来的模型会对高频类别过拟合低频类别几乎学不到特征。我的做法分三步。第一步统计所有类别的样本量对样本量超过某个阈值的高频类别做随机下采样把每个类的图片数量压到差不多的量级。第二步是数据增强层面对低频类别用复制粘贴增强把这个类的目标抠出来随机贴到背景图上。第三步最省事YOLO自带的mosaic增强和mixup就已经在训练时混入了多张图的信息只要高频类别没把总数压到失衡太离谱光靠mosaic就能稳住低频类别的召回。这里要提醒一下类别不均衡不要用调整loss权重的方式来硬解在目标检测里改loss权重很容易让模型产生大量该类的误检。先把数据层面的均衡做了再考虑要不要动损失函数。3. 0基础跑通YOLOv11环境配置最小训练命令与关键参数从零配环境的坑比训练本身多。很多0基础同学卡在第一步就放弃了这一章给出一个能跑通的最小路径从conda环境到训练命令每一步都说明为什么这么做。3.1 ultralytics环境配置从conda到yolo checksultralytics是YOLOv11的官方维护库装好它就能用yolo命令和Python API。环境配置这一步的核心是隔离不要把YOLOv11装进系统自带的Python里不然跟已有的包版本冲突起来排查半天都找不到原因。# 1. 创建独立的conda环境Python 3.10是兼容性最好的版本 conda create -n yolo11 python3.10 -y conda activate yolo11 # 2. 安装ultralytics它会自动拉取配套的依赖库 pip install ultralytics # 3. 验证环境是否可用会列出PyTorch版本和CUDA是否可用 yolo checks第一步用conda隔离环境是最省心的做法避免污染系统Python。第二步pip install ultralytics会同时装上torch、opencv等依赖不需要手动一个个装。第三步yolo checks是验证命令运行后会输出CUDA是否可用、GPU型号、PyTorch版本。如果这里显示CPU而不是CUDA说明装的是CPU版PyTorch。提示如果你的机器有NVIDIA独立显卡建议先装CUDA版PyTorch再装ultralytics否则后面训练速度差几十倍。具体做法是到PyTorch官网的安装页面复制对应的命令行装上GPU版之后再用pip install ultralytics。3.2 训练自己的模型wildlife.yaml与训练参数训练前要准备一个数据集配置文件告诉YOLOv11图片在哪、标注在哪、类别有几类。这个YAML文件是整个训练的入口# wildlife.yaml # 路径建议用绝对路径训练时命令行的工作目录经常变化 path: /home/user/wildlife_data train: images/train val: images/val # 类别ID必须和转换脚本里的class_names顺序严格一致 names: 0: wild_boar 1: deer 2: fox 3: bird 4: badger这里path是数据集的根目录train和val分别是训练集和验证集图片的相对路径YOLOv11会自动在同级目录下找labels文件夹里的TXT标注。names这个列表的ID不能乱第2章转换脚本里class_names.index(name)算出来的ID就是按照这个顺序排的。如果顺序错了训练不会报错但推理结果全是错的。配好数据集后训练命令如下# 用COCO预训练的yolo11n做微调而不是随机初始化从头训练 yolo detect train \ datawildlife.yaml \ modelyolo11n.pt \ epochs150 \ imgsz640 \ batch16 \ patience60 \ projectwildlife_project \ nameexp1关键参数说明如下参数我的建议值说明modelyolo11n.ptn是轻量版数据量小时用它最稳imgsz640小目标多就改1280但显存占用翻倍batch168G显存的安全值显存大可以加到32epochs150不是越多越好配合patience做早停patience6060轮不提升就停防过拟合也省时间project/namewildlife_project/exp1输出目录便于对比多组实验patience是YOLOv11的早停参数意思是验证集指标连续60轮不提升就自动停止训练。野生动物的数据噪声很大loss曲线比工业数据波荡得多所以这个值我一般设得偏大避免模型明明还在爬坡就被早停了。imgsz的选择要看你的目标大小如果画面里动物占面积很大640够用如果像远距离的鸟或者松鼠那种小目标建议直接上1280小目标检测对分辨率极其敏感。3.3 yolov11网络结构与迁移学习从哪些预训练权重开始yolov11的backbone相比v8做了一些调整比如用C3k2模块替代了原来的C2f整体参数量在同尺寸下略有下降推理速度更快。但对做应用的人来说更需要关心的是选哪个预训练权重ultralytics官方提供了n、s、m、l、x五个尺寸参数量递增。0基础的同学我建议无脑从yolo11n.pt开始。原因很实在第一n尺寸的训练速度快几分钟就能看到loss曲线方便你快速验证数据集配置有没有问题第二野生动物数据集通常只有几千张大模型在这个量级上非常容易过拟合效果反而不如小模型。等n跑通全流程、确认数据没问题再换成s或m精度会有明显提升。有种常见的误用是新手一上来就选最大的x结果显存不够、训练极慢、还过拟合白白浪费一整天。迁移学习的价值在野生动物场景尤其明显COCO预训练模型已经学会了边缘、纹理、形状这些通用特征哪怕COCO里没有鹿和狐狸这些底层特征迁移过来也远好于随机初始化。所以永远不要用modelyolo11n.yaml这种从零训练的配置坚持用.pt预训练权重起步。4. 推理、保存结果与追踪从检测框到栖息地热点训练完的模型要落地得能批量处理野外数据、保存结果、把检测框串成个体轨迹最后产出生态学能用的分析结果。这一章解决的是「模型跑完输出什么」的问题。4.1 yolov11保存推理结果save、save_txt与save_conf各管什么推理不是点一下出张图就完了野生动物监测的下游分析需要结构化结果。YOLOv11的predict接口提供了几个保存选项很多人只用了saveFalse导致结果没存下来或者只存了图丢了坐标数据这些都是后面没法分析的。from ultralytics import YOLO # 加载训练产出的最佳权重 model YOLO(runs/detect/exp1/weights/best.pt) results model.predict( sourcecamera_trap_2023/, imgsz640, conf0.15, # 野外场景置信度阈值要低一点宁多检不漏检 iou0.5, saveTrue, # 保存画了框的标注图方便人工复核 save_txtTrue, # 保存每张图的检测结果TXT save_confTrue, # 在TXT里附加置信度后面过滤用得上 projectinference_0321, namerun1 ) # 在代码里也能直接访问每个检测框的字段 for r in results: for box in r.boxes: cls_id int(box.cls[0]) # 类别ID conf float(box.conf[0]) # 置信度 x1, y1, x2, y2 box.xyxy[0].tolist() # 像素坐标saveTrue会输出带标注框的图片文件这是给人工复核用的。save_txtTrue会把每张图的检测结果写成一个TXT每行格式是class_id x_center y_center width height conf注意这里输出的是归一化坐标后面做栖息地分析时要换算回实际距离。save_confTrue决定TXT里末尾那一位是否保留置信度我建议一定打开后面做置信度阈值筛选时没有这个字段就得重新跑推理。参数上要特别留意conf0.15这个值。工业场景里默认0.25没问题但野外相机拍的动物经常被遮挡、距离远、姿态怪异置信度天然偏低。我一般先把阈值降到0.15甚至0.1把召回率拉高即使混进来一批误检也没关系后面用置信度和时间盲测再做二次过滤。先保住真目标再清理噪声这是野外检测的常规打法。4.2 用ByteTrack把检测框串成个体轨迹单张照片的检测框没有时间维度没法回答「这只鹿在这个区域活动了多久」。做法是先按时间顺序把同一相机的照片或视频帧喂给追踪器让追踪器给每个检测框分配一个track_id同一个体的所有框共享同一个ID这样才能算活动轨迹。from ultralytics import YOLO model YOLO(runs/detect/exp1/weights/best.pt) results model.track( sourceplot1_video.mp4, conf0.2, iou0.5, persistTrue, # 跨帧保持同一个track_id不重置 trackerbytetrack.yaml, # 用ByteTrack而不是默认的botsort saveTrue ) # 每个检测框的track_id在box.id里 for r in results: if r.boxes.id is not None: for box in r.boxes: track_id int(box.id[0]) # 个体的轨迹ID cls_id int(box.cls[0]) conf float(box.conf[0])persistTrue是关键它告诉追踪器把当前帧的track_id延续到下一帧而不是每帧重新编号。trackerbytetrack.yaml指定用ByteTrack算法这是ultralytics内置配置中的默认追踪器。在野生动物场景里ByteTrack比DeepSORT更合适因为DeepSORT依赖的外观特征在动物身上极不可靠——同一只动物换个角度、换个光线外观特征比不同个体还大ReID模型基本失效。ByteTrack纯靠位置和IOU关联反而稳。用照片序列做追踪有个特殊注意点必须先把同一个相机部署点的照片按拍摄时间戳排序再按顺序喂给追踪模型。如果照片顺序是乱的追踪器会认为动物在画面里瞬移轨迹全断。我自己处理相机陷阱数据时会先把照片名里的时间戳解析出来排序再一个相机一个相机地过而不是把所有相机的照片混在一起。4.3 从轨迹到栖息地分析坐标对齐与核密度热点拿到带track_id的检测结果后下一步是把像素坐标换算成实际地理坐标再做栖息地分析。红外相机是固定部署的每张照片的拍摄位置就是这台相机的GPS坐标无人机航拍则用每帧的POS数据。这一步不要直接在经纬度上算距离高纬度地区经度1度的实际距离远小于赤道附近直接算欧氏距离会失真要先投影到UTM平面坐标。import pandas as pd import numpy as np from scipy.stats import gaussian_kde # 假设检测结果已经关联了相机GPS坐标 df pd.read_csv(detections_with_gps.csv) # 同一个track_id对应的检测框取中位数坐标代表这一次活动的位置 df_track df.groupby(track_id).agg( lon(lon, median), lat(lat, median), species(class_name, first), ).reset_index() # 用核密度估计找出活动热点区域 kde gaussian_kde(np.vstack([df_track[lon], df_track[lat]])) # 在包络范围内切网格计算每个网格的密度值 lon_min, lon_max df_track[lon].min(), df_track[lon].max() lat_min, lat_max df_track[lat].min(), df_track[lat].max() xs, ys np.meshgrid( np.linspace(lon_min, lon_max, 200), np.linspace(lat_min, lat_max, 200) ) density kde(np.vstack([xs.ravel(), ys.ravel()])).reshape(xs.shape) # density可以直接转成栅格图叠加到底图上做可视化这段代码的逻辑先按track_id做聚合每个轨迹只取一个中位数坐标点既保留了活动位置信息又避免了同一个体连续几十帧重复计数导致热点偏移。然后用gaussian_kde对全部位点做核密度估计带宽由数据自动估计。最后切一个200x200的网格逐点计算密度值输出成一个栅格矩阵可以叠加到ArcGIS或QGIS里做进一步分析。栖息地分析的核心产出是这个密度栅格生态学上叫利用分布。注意gaussian_kde对离群点敏感如果追踪结果里混了几个误检的单帧轨迹会拉出虚假热点。所以我一般会在聚合前先过滤掉只出现过一次或两次的track_id这些大概率是误检不是真实的活动位点。5. 野生动物场景避坑指南小目标、夜间、ID跳变与置信度野外环境的坑比干净数据集多得多这一章是血泪经验汇总。每个问题按「现象、原因、解决」来写踩过坑的人能直接对号入座。5.1 小目标漏检imgsz、SAHI切片与HCA-Net注意力思路现象是远处的小动物完全检测不到比如树上的鸟、远处山坡上的狐狸在640分辨率的画面上可能只有30x30像素。原因是YOLOv11的下采样倍数高小目标在深层特征图上只剩不到一个像素点特征全丢了。这在小目标优化里是最常见的问题。解决路径分三步。第一步低成本先试imgsz1280把输入分辨率翻倍小目标的像素面积变成原来的四倍很多漏检自然就消失了代价是显存和推理时间上涨。第二步如果大分辨率还不行用SAHI切片推理把大图切成一堆512x512的重叠小块分别跑检测再合并结果等于把小目标放大后再检。第三步才是结构层面的优化有些项目会参照HCA-Net这类混合通道注意力思路在backbone的浅层输出位置加一个轻量的通道注意力分支让小目标特征在传递过程中不被淹没。这三步按顺序试大部分小目标场景能解决到可用程度。5.2 夜间红外样本让模型集体误判现象是白天训练出来的模型效果很好放到夜间红外相机数据上一测一半以上的框都是误检把树干、石头、甚至热源残影都框成动物。原因是红外图像只有单通道亮度信息物体的纹理和色彩线索全部丢失像素分布和可见光图像完全是两个世界。解决这个问题必须从训练数据下手。收集一批夜间红外样本混进训练集目标占比别太低我一般按30%左右混入。数据增强上打开mosaic时让红外图片和可见光图片交叉拼接模型被迫学习跨模态特征。还有一个实操技巧红外图推理前先做一次直方图均衡化预处理能显著降低夜间图像的噪点干扰。如果白天和夜间的数据量都很大干脆训练两个模型分开用比强行合在一起效果好得多。5.3 追踪ID跳变ByteTrack参数怎么调现象是同一只动物走出画面再回来track_id变了两只动物交错后A变成B、B变成A轨迹全乱。原因是ByteTrack默认参数是按行人场景调优的行人运动平滑、遮挡时间短而野生动物会在画面里藏进灌丛很久不出现或者快速跑动导致位置突变。解决方法是调整ByteTrack的匹配策略在ultralytics里改bytetrack.yaml配置# bytetrack.yaml在项目的配置目录下修改 tracker_type: bytetrack # 检测框置信度高于此值才参与高置信度匹配调低让更多框进入关联 track_high_thresh: 0.35 track_low_thresh: 0.10 # 只有置信度高于此值才允许创建新轨迹调高减少凭空冒出的ID new_track_thresh: 0.70 match_thresh: 0.80track_high_thresh从默认的0.5调低到0.35能让更多低置信度检测框参与轨迹匹配而不是被直接丢弃后重新创建新轨迹。new_track_thresh从默认的0.6调高到0.7减少新轨迹的误开启这两个参数一降一升配合起来能明显抑制ID跳变。match_thresh控制轨迹匹配的IOU要求野生动物的快速位移导致相邻帧框重叠率低这个值不需要动太多。指向一个更彻底的办法如果动物长时间消失在画面里再出现任何纯位置追踪算法都接不上。预算允许的话可以在每段视频里人工标注关键个体的出现时间段用人工分段去修正自动轨迹这是生态学报告里常见的质检步骤。5.4 权重文件下载失败与训练中断现象是第一次运行yolo detect train时卡在下载yolo11n.pt进度条不动等很久最终报错退出。原因是训练前ultralytics会自动下载预训练权重而大文件传输在公共网络上很容易被中断。这个坑跟网络状况相关遇到了直接用下面的办法绕过去。# 用断点续传方式下载权重到当前工作目录 # Release页面上的yolo11n.pt直链 换成实际下载链接 wget -c Release页面上的yolo11n.pt直链 -O yolo11n.pt # 训练时指定本地权重文件的路径 yolo detect train datawildlife.yaml model./yolo11n.pt epochs150 ...wget -c带断点续传参数中断了不用从头再下。下载完成后训练命令里的model参数从裸文件名改成./yolo11n.pt本地路径ultralytics检测到文件已经存在就不再尝试下载。还有一种情况是训练中途断了ultralytics支持断点续训在同样的project和name下加resumeTrue参数它会自动读取上次保存的权重和训练状态继续跑。别小看这个参数几个小时的训练因为网络抖动白废谁遇到谁知道。5.5 随机切分数据集是数据泄漏时间盲测才是真实水平现象是随机切分训练验证集后精度很高模型一部署到新数据上就掉点严重。原因是相机陷阱的连拍特性同一只动物在几秒内连拍十几张这十几张的背景、光照、姿态几乎一样。随机切分时这些相似帧一半进了训练集一半进了验证集模型相当于开卷考试评估指标虚高得厉害。解决方法是按时间切分而不是随机切分。把整个采集周期的数据按时间排序前80%做训练集、后20%做验证集让验证集里的场景在时间上完全晚于训练集模拟真实部署时的预测场景。如果数据跨季节最好保证训练集覆盖春夏、验证集覆盖秋冬这种严格的时间隔离。这个做法牺牲了一部分验证集精度但换来的是可信的模型表现估计。下一章给出具体的验证流程。6. 验证模型能不能真的上岗时间盲测与F1-置信度曲线部署前的最后一步是在时间盲测集上找出最合适的置信度阈值。很多人直接沿用默认的0.25出结果这在野生动物场景里隐患很大因为野外检测的置信度分布跟COCO验证集完全不一样。用下面这段脚本在盲测集上扫一遍F1值选出最佳阈值import numpy as np from ultralytics import YOLO model YOLO(runs/detect/exp1/weights/best.pt) # 简化版F1计算按检测框数量匹配用于选阈值够用 # 正式评估请按IoU匹配mAP那套逻辑更严谨 def compute_f1(conf): tp fp fn 0 for r in model.predict(data/images/val_time, confconf, saveFalse): preds [b for b in r.boxes if float(b.conf[0]) conf] # 对应TXT标注里的真实框数量 gt_path r.path.replace(images, labels).replace(.jpg, .txt) with open(gt_path) as f: gt_count len([l for l in f.read().splitlines() if l]) tp min(len(preds), gt_count) fp max(0, len(preds) - gt_count) fn max(0, gt_count - len(preds)) f1 2 * tp / max(1, 2 * tp fp fn) return f1 # 从0.05到0.55按步长0.05扫描置信度阈值 for conf in np.arange(0.05, 0.60, 0.05): print(fconf{conf:.2f} F1{compute_f1(conf):.3f})这个脚本把TP判定简化成了按数量匹配选阈值阶段够用正式出报告请换成按IoU匹配的评估逻辑。扫描结果通常会出现一个明显的F1峰值区间比如在0.1到0.3之间F1都在0.85以上。这时候我的习惯是选区间内偏高的阈值因为更高的阈值意味着更少的误检后端人工复核的工作量会小很多而召回率只损失一点点。整个方案的落地路径到这里就完整了。前几年我做夜间红外数据时偷懒直接用了默认阈值一个月的数据交到同事手里复核他们在几百张空框图的包围里翻了三天车。后来每次换新场景我都严格按照这套流程走时间盲测切分、扫F1曲线、再定阈值。这个习惯帮我少挨了很多骂也让我对「模型到底能不能上岗」心里有底。希望帮到你。本文还有配套的精品资源点击获取
返回列表