Bird Detect Cascade Batch
这是一个 YOLOv5 + ConvNeXt + 贝叶斯密度估计 级联鸟类识别批处理程序。它通过 bash 命令处理图片、视频或文件夹,并输出标注结果、JSON、XML。
1. 最常用运行方式
处理单张图片、单个视频或一个文件夹:
bash run_batch.sh --input /path/to/input
指定输出目录,并关闭密度估计:
bash run_batch.sh --input /path/to/input --output /path/to/runs --disable-density
输入路径可以是图片、视频,也可以是包含图片/视频的文件夹。默认会递归处理子文件夹。
三个模型都可以单独关闭,例如只运行密度估计:
bash run_batch.sh --input /path/to/input \
--disable-detection \
--disable-classification
2. 哪些参数可以直接写在 bash 指令里
下面这些参数都可以直接写在 bash run_batch.sh ... 后面,不需要改 Python 代码。
| bash 参数 | 默认值 | 含义 |
|---|---|---|
--input PATH |
无,必填 | 输入路径,可以是图片、视频或文件夹 |
--output PATH |
./runs |
输出根目录 |
--sample-interval INT |
2 |
视频抽帧间隔,2 表示每 2 帧处理 1 帧 |
--recursive |
开启 | 输入是文件夹时递归处理子目录 |
--no-recursive |
关闭递归 | 只处理输入文件夹第一层文件 |
--enable-detection |
开启 | 启用 YOLO 目标检测 |
--disable-detection |
关闭目标检测 | 不加载、不运行 YOLO;检测结果为空 |
--enable-classification |
开启 | 启用 ConvNeXt 细粒度识别 |
--disable-classification |
关闭细粒度识别 | 不加载、不运行 ConvNeXt;保留 YOLO 检测框 |
--enable-density |
开启 | 启用贝叶斯密度估计 |
--disable-density |
关闭密度估计 | 不运行密度估计,只运行 YOLO + ConvNeXt |
--det-conf-thres FLOAT |
0.25 |
YOLO 第一层检测阈值,低于该值的框直接丢弃 |
--det-iou-thres FLOAT |
0.45 |
NMS IoU 阈值;越低,重叠框去得越狠 |
--det-second-conf-thres FLOAT |
0.35 |
YOLO 第二层过滤阈值,低于该值不会裁剪,也不会进入 ConvNeXt |
--min-box-area-ratio FLOAT |
0.00002 |
过滤面积占比过小的噪声框 |
--max-box-area-ratio FLOAT |
1.0 |
最大框面积占比;默认不按面积过滤大目标 |
--max-box-aspect-ratio FLOAT |
6.0 |
过滤长宽比过大的细长框 |
--cls-show-conf-thres FLOAT |
0.50 |
普通目标分类置信度低于该值时,不在结果图显示物种名 |
--large-box-area-ratio FLOAT |
0.002 |
框面积占比超过该值时,认为是近景大目标 |
--large-box-cls-show-conf-thres FLOAT |
0.25 |
大目标显示物种名的较低分类阈值 |
--show-large-box-name-always BOOL |
true |
大目标是否只要分类名非空就显示 |
--dense-scene-count-thres INT |
20 |
密度估计数量达到该值时,认为是密集场景 |
--hide-cls-name-in-dense-scene BOOL |
true |
密集场景下是否隐藏所有物种名 |
--crop-padding-ratio FLOAT |
0.08 |
送入 ConvNeXt 前,检测框向外扩的比例 |
--max-detections INT |
50 |
单张图或单帧最多保留的检测框数量 |
--uniform-species-color BOOL |
false |
true 时所有物种的检测框和标签统一使用同一种颜色 |
示例:降低检测阈值、提高进入分类前的二次过滤阈值:
bash run_batch.sh \
--input /path/to/input \
--det-conf-thres 0.15 \
--det-second-conf-thres 0.45
示例:密集场景仍然显示物种名:
bash run_batch.sh \
--input /path/to/input \
--hide-cls-name-in-dense-scene false
示例:让所有物种的检测框和标签统一使用绿色:
bash run_batch.sh \
--input /path/to/input \
--uniform-species-color true
3. 阈值怎么调
最关键的是这两个参数:
--det-conf-thres: YOLO 第一层阈值。低于这个值的框会在 YOLO 后处理阶段直接丢弃。--det-second-conf-thres: YOLO 第二层阈值。低于这个值的框不会裁剪,也不会传给 ConvNeXt 分类。
常见调法:
- 漏检多:降低
--det-conf-thres,例如0.25 -> 0.15。 - 误检多:提高
--det-second-conf-thres,例如0.35 -> 0.45。 - 小噪声框多:提高
--min-box-area-ratio。 - 异常大框多:降低
--max-box-area-ratio;不要为了排除异常框把它设得过低,否则近景大鸟会被误删。 - 细长误检框多:降低
--max-box-aspect-ratio。 - 检测到了但不显示物种名:降低
--cls-show-conf-thres,或检查--hide-cls-name-in-dense-scene。 - 密集场景过早隐藏物种名:提高
--dense-scene-count-thres,或设置--hide-cls-name-in-dense-scene false。
这些阈值现在都可以写在 bash 指令里,不需要去代码里调。
4. 三个模型的开关
三个模型默认都开启:
bash run_batch.sh --input /path/to/input
关闭目标检测:
bash run_batch.sh --input /path/to/input --disable-detection
关闭细粒度识别,只输出 YOLO 检测框:
bash run_batch.sh --input /path/to/input --disable-classification
关闭密度估计:
bash run_batch.sh --input /path/to/input --disable-density
也可以任意组合,例如只运行目标检测:
bash run_batch.sh --input /path/to/input \
--disable-classification \
--disable-density
只运行密度估计:
bash run_batch.sh --input /path/to/input \
--disable-detection \
--disable-classification
注意:细粒度识别依赖目标检测提供裁剪框,因此关闭目标检测后,ConvNeXt 不会加载或运行,即使显式传入 --enable-classification。密度估计与另外两个模型相互独立。
关闭某个模型后:
- 对应 ONNX 模型不会加载,也不会执行推理;
- 关闭目标检测时,
results为空; - 关闭细粒度识别时,每个检测结果的
cls_class_id为-1、cls_class_name为空、cls_confidence为0.0; - 关闭密度估计时,JSON 里的
density为null,结果图不显示密度热力图和密度估计数量。
颜色开关不影响模型推理和 JSON/XML,只影响结果图片或视频的可视化:
--uniform-species-color false:默认行为,每个物种使用各自的稳定颜色;--uniform-species-color true:所有物种的检测框和标签统一使用绿色。
5. 哪些配置用环境变量,不直接写 bash 参数
模型路径、输入尺寸、设备这类参数通常不频繁改,所以保留为环境变量。它们可以写在 bash 命令前面,也不需要改代码。
| 环境变量 | 默认值 | 含义 |
|---|---|---|
ENABLE_DETECTION |
true |
是否启用 YOLO 目标检测 |
ENABLE_CLASSIFICATION |
true |
是否启用 ConvNeXt 细粒度识别 |
ENABLE_DENSITY |
true |
是否启用密度估计 |
DET_MODEL_PATH |
models/YNDC_20251010_yolov5_optimize.onnx |
YOLOv5 检测模型 |
DET_CLASSES_PATH |
models/YNDC_20251010_yolov5_optimize.txt |
YOLO 类别文件 |
CLS_MODEL_PATH |
models/HHK_20260525_mmcls_optimize.onnx |
ConvNeXt 分类模型 |
CLS_CLASSES_PATH |
models/HHK_20260525_mmcls_optimize.txt |
ConvNeXt 类别文件 |
DENSITY_MODEL_PATH |
models/bird_density.onnx |
密度估计模型 |
DET_IMG_SIZE |
640 |
YOLO 输入尺寸 |
CLS_IMG_SIZE |
224 |
ConvNeXt 输入尺寸 |
DENSITY_IMG_SIZE |
0 |
密度模型输入尺寸;0 表示自动读取模型输入 |
TARGET_DET_CLASS_IDS |
0 |
只保留哪些 YOLO 检测类别 |
DEVICE |
cpu |
ONNX Runtime 运行设备,支持 cpu 或 cuda;CUDA 不可用时直接报错,不会静默回退 CPU |
UNIFORM_SPECIES_COLOR |
false |
是否让所有物种的检测框和标签使用同一种颜色 |
示例:
DEVICE=cpu TARGET_DET_CLASS_IDS=0 bash run_batch.sh --input /path/to/input
指定 GPU 0 运行:
CUDA_VISIBLE_DEVICES=0 DEVICE=cuda bash run_batch.sh --input /path/to/input
使用 CUDA 前必须安装与服务器 CUDA/cuDNN 匹配的 onnxruntime-gpu。启动时程序会分别打印 YOLO、ConvNeXt、密度模型的实际 Provider;使用 GPU 时应看到 CUDAExecutionProvider。
6. 哪些情况才需要改代码
一般调阈值、开关三个模型、切换统一颜色、改模型路径都不需要改代码。
只有下面这些情况通常需要改代码:
- YOLO ONNX 输出格式不是
[1, num_boxes, 5 + num_classes]或[num_boxes, 6],需要改app/inference/yolo_onnx.py。 - ConvNeXt 训练时没有使用 ImageNet mean/std,需要改
app/inference/convnext_onnx.py的归一化参数。 - 密度估计模型的前处理或输出含义和当前实现不一致,需要改
app/inference/density_onnx.py。 - 想改变结果 JSON/XML 字段结构,需要改
app/batch_runner.py或app/utils.py。
7. 输出结果
每次运行会生成一个任务目录:
runs/<时间戳>_<输入名>/
├── result/ # 标注后的图片或视频
├── json/ # 结构化结果
├── xml/ # XML 标注结果
└── index.json # 本次批处理汇总
图片输出:
result/<原文件名>.jpgjson/<原文件名>.jsonxml/<原文件名>.xml
视频输出:
result/<原文件名>.mp4json/<原文件名>.jsonxml/<原文件名>.xml
JSON 中每个目标包含:
{
"bbox_xyxy": [100.0, 120.0, 240.0, 310.0],
"det_confidence": 0.91,
"det_class_id": 0,
"det_class_name": "bird",
"cls_class_id": 12,
"cls_class_name": "绿头鸭",
"cls_confidence": 0.87,
"box_area_ratio": 0.0032,
"is_large_box": true,
"is_dense_scene": false,
"show_cls_name": true
}
8. Docker 备选运行方式
如果不想在宿主机安装 Python 依赖,可以用 Docker。Docker 只是备选,默认仍然执行同一个 run_batch.sh。
构建镜像:
docker build -t bird-cascade-batch:latest .
使用 Compose 处理项目根目录的 input/:
docker compose run --rm bird-cascade-batch
临时覆盖参数:
docker compose run --rm bird-cascade-batch \
--input /app/input \
--output /app/runs \
--sample-interval 5 \
--disable-density
docker-compose.yml 默认挂载:
volumes:
- ./models:/app/models:ro
- ./input:/app/input:ro
- ./runs:/app/runs
9. 程序结构
app/
├── batch_runner.py # 批处理入口
├── config.py # 环境变量配置
├── pipeline.py # 主级联流程
├── utils.py # 图像、JSON、XML 工具
├── video_pipeline.py # 视频平滑工具
└── inference/
├── yolo_onnx.py # YOLOv5 ONNX 推理和后处理
├── convnext_onnx.py # ConvNeXt ONNX 推理
└── density_onnx.py # 密度估计 ONNX 推理
历史文件 pipeline_raw.py、pipeline_add_density.py、config_raw.py、batch_runner_raw.py 不参与默认 bash 批处理主流程。