301 lines
11 KiB
Markdown
301 lines
11 KiB
Markdown
# Bird Detect Cascade Batch
|
||
|
||
这是一个 **YOLOv5 + ConvNeXt + 贝叶斯密度估计** 级联鸟类识别批处理程序。它通过 bash 命令处理图片、视频或文件夹,并输出标注结果、JSON、XML。
|
||
|
||
## 1. 最常用运行方式
|
||
|
||
处理单张图片、单个视频或一个文件夹:
|
||
|
||
```bash
|
||
bash run_batch.sh --input /path/to/input
|
||
```
|
||
|
||
指定输出目录,并关闭密度估计:
|
||
|
||
```bash
|
||
bash run_batch.sh --input /path/to/input --output /path/to/runs --disable-density
|
||
```
|
||
|
||
输入路径可以是图片、视频,也可以是包含图片/视频的文件夹。默认会递归处理子文件夹。
|
||
|
||
三个模型都可以单独关闭,例如只运行密度估计:
|
||
|
||
```bash
|
||
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
|
||
bash run_batch.sh \
|
||
--input /path/to/input \
|
||
--det-conf-thres 0.15 \
|
||
--det-second-conf-thres 0.45
|
||
```
|
||
|
||
示例:密集场景仍然显示物种名:
|
||
|
||
```bash
|
||
bash run_batch.sh \
|
||
--input /path/to/input \
|
||
--hide-cls-name-in-dense-scene false
|
||
```
|
||
|
||
示例:让所有物种的检测框和标签统一使用绿色:
|
||
|
||
```bash
|
||
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
|
||
bash run_batch.sh --input /path/to/input
|
||
```
|
||
|
||
关闭目标检测:
|
||
|
||
```bash
|
||
bash run_batch.sh --input /path/to/input --disable-detection
|
||
```
|
||
|
||
关闭细粒度识别,只输出 YOLO 检测框:
|
||
|
||
```bash
|
||
bash run_batch.sh --input /path/to/input --disable-classification
|
||
```
|
||
|
||
关闭密度估计:
|
||
|
||
```bash
|
||
bash run_batch.sh --input /path/to/input --disable-density
|
||
```
|
||
|
||
也可以任意组合,例如只运行目标检测:
|
||
|
||
```bash
|
||
bash run_batch.sh --input /path/to/input \
|
||
--disable-classification \
|
||
--disable-density
|
||
```
|
||
|
||
只运行密度估计:
|
||
|
||
```bash
|
||
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` | 是否让所有物种的检测框和标签使用同一种颜色 |
|
||
|
||
示例:
|
||
|
||
```bash
|
||
DEVICE=cpu TARGET_DET_CLASS_IDS=0 bash run_batch.sh --input /path/to/input
|
||
```
|
||
|
||
指定 GPU 0 运行:
|
||
|
||
```bash
|
||
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. 输出结果
|
||
|
||
每次运行会生成一个任务目录:
|
||
|
||
```text
|
||
runs/<时间戳>_<输入名>/
|
||
├── result/ # 标注后的图片或视频
|
||
├── json/ # 结构化结果
|
||
├── xml/ # XML 标注结果
|
||
└── index.json # 本次批处理汇总
|
||
```
|
||
|
||
图片输出:
|
||
|
||
- `result/<原文件名>.jpg`
|
||
- `json/<原文件名>.json`
|
||
- `xml/<原文件名>.xml`
|
||
|
||
视频输出:
|
||
|
||
- `result/<原文件名>.mp4`
|
||
- `json/<原文件名>.json`
|
||
- `xml/<原文件名>.xml`
|
||
|
||
JSON 中每个目标包含:
|
||
|
||
```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`。
|
||
|
||
构建镜像:
|
||
|
||
```bash
|
||
docker build -t bird-cascade-batch:latest .
|
||
```
|
||
|
||
使用 Compose 处理项目根目录的 `input/`:
|
||
|
||
```bash
|
||
docker compose run --rm bird-cascade-batch
|
||
```
|
||
|
||
临时覆盖参数:
|
||
|
||
```bash
|
||
docker compose run --rm bird-cascade-batch \
|
||
--input /app/input \
|
||
--output /app/runs \
|
||
--sample-interval 5 \
|
||
--disable-density
|
||
```
|
||
|
||
`docker-compose.yml` 默认挂载:
|
||
|
||
```yaml
|
||
volumes:
|
||
- ./models:/app/models:ro
|
||
- ./input:/app/input:ro
|
||
- ./runs:/app/runs
|
||
```
|
||
|
||
## 9. 程序结构
|
||
|
||
```text
|
||
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 批处理主流程。
|