文章目录
- [Ultralytics YOLO COCO 评估脚本 (coco_evaluate.py)](#Ultralytics YOLO COCO 评估脚本 (coco_evaluate.py))
-
- [1. 描述](#1. 描述)
- [2. 依赖项](#2. 依赖项)
- [3. 使用方法](#3. 使用方法)
- [4. 输入文件格式](#4. 输入文件格式)
- [5. 输出](#5. 输出)
- [6. 注意](#6. 注意)
- [7. 完整代码](#7. 完整代码)
Ultralytics YOLO COCO 评估脚本 (coco_evaluate.py)
这是一个 Python 脚本,用于评估以 COCO JSON 格式提供的目标检测结果。它利用官方的 pycocotools
库来计算标准的 COCO 评估指标。
1. 描述
该脚本接收一个包含真实标注(Ground Truth)的 COCO JSON 文件和一个包含模型预测结果的 COCO 格式 JSON 文件作为输入。然后,它使用 pycocotools
API 来执行评估过程,并最终将标准的 12 个 COCO 评估指标(包括 AP、AP50、AP75、AP across scales、AR across max detections、AR across scales 等)打印到控制台。
2. 依赖项
在运行此脚本之前,请确保已安装必要的 Python 库:
- Python 3.x
pycocotools
: 这是 COCO 官方提供的 API。numpy
:pycocotools
的依赖项。
你可以使用 pip 安装它们:
bash
pip install numpy pycocotools
3. 使用方法
通过命令行运行此脚本。你需要提供标注文件和预测结果文件的路径。
bash
python coco_evaluate.py --annotations <标注文件路径> --predictions <预测文件路径>
参数说明:
--annotations
: 必需 。指向 COCO 格式的 JSON 标注文件的路径(例如instances_val2017.json
)。--predictions
: 必需 。指向包含模型预测结果的 JSON 文件的路径。此文件必须遵循 COCO 的结果提交格式(一个 JSON 列表,每个元素包含image_id
,category_id
,bbox
, 和score
)。
示例:
假设你的标注文件位于 data/coco/annotations/instances_val2017.json
,预测结果文件位于 runs/detect/exp1/predictions.json
,你可以这样运行:
bash
python coco_evaluate.py --annotations data/coco/annotations/instances_val2017.json --predictions runs/detect/exp1/predictions.json
4. 输入文件格式
-
标注文件 (
--annotations
) : 标准的 COCO JSON 格式文件,通常包含info
,licenses
,images
,annotations
,categories
等字段。 -
预测文件 (
--predictions
): 一个 JSON 文件,其内容是一个列表(list)。列表中的每个元素是一个字典(dict),代表一个检测到的目标,必须包含以下键:image_id
: 对应标注文件中图像的 ID(整数)。category_id
: 检测到的目标的类别 ID(整数),必须与标注文件中的类别 ID 对应。bbox
: 检测到的边界框,格式为[x, y, width, height]
,其中x
,y
是左上角坐标。score
: 模型对该检测结果的置信度分数(浮点数)。
示例
predictions.json
的片段:json[ { "image_id": 42, "category_id": 18, "bbox": [258.15, 41.29, 348.26, 243.78], "score": 0.997 }, { "image_id": 73, "category_id": 1, "bbox": [61.87, 222.53, 410.64, 176.95], "score": 0.994 }, ... ]
5. 输出
脚本执行后,会将标准的 COCO 评估结果摘要打印到控制台(标准输出)。输出格式类似于:
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.xxx
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.xxx
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.xxx
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.xxx
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.xxx
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.xxx
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.xxx
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.xxx
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.xxx
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.xxx
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.xxx
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.xxx
其中 0.xxx
会被实际计算出的指标值替换。
6. 注意
- 确保提供的预测文件中的
category_id
与标注文件中的类别 ID 映射一致。 - 脚本目前只评估
bbox
(边界框检测),如果需要评估实例分割 (segm
) 或关键点 (keypoints
),需要修改COCOeval
初始化时的iouType
参数。
7. 完整代码
python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""python coco_evaluate.py --annotations path\instances_val2017.json --predictions path\predictions.json"""
import argparse
import json
import os
from pathlib import Path
import numpy as np
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval
def evaluate_coco(pred_json, anno_json):
"""
使用pycocotools评估COCO格式的检测结果
参数:
pred_json: 预测结果的JSON文件路径
anno_json: COCO格式的标注文件路径
返回:
stats: 评估结果统计
"""
print(f"\n正在评估 COCO 指标,使用 {pred_json} 和 {anno_json}...")
# 检查文件是否存在
for x in [pred_json, anno_json]:
assert os.path.isfile(x), f"文件 {x} 不存在"
# 初始化COCO API
anno = COCO(str(anno_json)) # 初始化标注API
pred = anno.loadRes(str(pred_json)) # 初始化预测API (必须传递字符串,而非Path对象)
# 进行bbox评估
eval_bbox = COCOeval(anno, pred, 'bbox')
eval_bbox.evaluate()
eval_bbox.accumulate()
eval_bbox.summarize()
def main():
parser = argparse.ArgumentParser(description='评估COCO格式的目标检测结果')
parser.add_argument('--annotations', type=str, required=True, help='COCO格式的标注文件路径')
parser.add_argument('--predictions', type=str, required=True, help='预测结果的JSON文件路径')
args = parser.parse_args()
# 确保文件路径存在
pred_json = Path(args.predictions)
anno_json = Path(args.annotations)
# 评估并打印结果
stats = evaluate_coco(pred_json, anno_json)
if __name__ == '__main__':
main()