YOLOv8自用数据集输出COCO评价指标(包含大中小物体的AP值)解决AssertionError: Results do not correspond to current coco set问题

首先在YOLO项目下新建一个文件夹 可命名为TXToCOCO  在该文件下新增txt2coco.py文件、class.txt文件,在数据集文件夹下新建annotations文件夹

txt2coco.py文件用于将yolo格式的数据集转化为coco格式并生成json文件

class.txt用来存放每个类别的名字

txt2coco.py文件如下---只需修改路径即可

import os
import json
import cv2
import random
import time
from PIL import Image

# 部分同学都用的autodl, 用antodl举例
# 使用绝对路径

#数据集 txt格式-labels标签文件夹
txt_labels_path='改为自己数据集val的标签所在路径'

#数据集图片images文件夹
datasets_img_path='改为自己数据集val的图片所在路径'
# 这里 voc 为数据集文件名字,可以改成自己的路径

# xx.json生成之后存放的地址
save_path='dataset/annotations/'#指定生成的json文件的存放路径


classes_txt='/TXToCOCO/class.txt改为class.txt文件所在路径'


with open(classes_txt,'r') as fr:
    lines1=fr.readlines()

categories=[]
for j,label in enumerate(lines1):
    label=label.strip()
    categories.append({'id':j,'name':label,'supercategory':'None'})
print(categories)

write_json_context=dict()
write_json_context['info']= {'description': 'For object detection', 'url': '', 'version': '', 'year': 2021, 'contributor': '', 'date_created': '2021'}
write_json_context['licenses']=[{'id':1,'name':None,'url':None}]
write_json_context['categories']=categories
write_json_context['images']=[]
write_json_context['annotations']=[]

imageFileList=os.listdir(datasets_img_path)


for i,imageFile in enumerate(imageFileList):
    imagePath = os.path.join(datasets_img_path,imageFile)
    image = Image.open(imagePath)
    W, H = image.size

    img_context={}
    img_context['file_name']=imageFile
    img_context['height']=H
    img_context['width']=W
    print(f"Before conversion: {imageFile[:-4]}")
    img_context['id'] = imageFile[:-4]
    int_id = int(img_context['id'])
    print(f"After conversion: {img_context['id']}")
    img_context['license']=1
    img_context['color_url']=''
    img_context['flickr_url']=''
    write_json_context['images'].append(img_context)

    txtFile=imageFile[:-4]+'.txt'

    with open(os.path.join(txt_labels_path,txtFile),'r') as fr:
        lines=fr.readlines()
    for j,line in enumerate(lines):
        bbox_dict = {}

        class_id,x,y,w,h=line.strip().split(' ')
        class_id,x, y, w, h = int(class_id), float(x), float(y), float(w), float(h)
        xmin=(x-w/2)*W
        ymin=(y-h/2)*H
        xmax=(x+w/2)*W
        ymax=(y+h/2)*H
        w=w*W
        h=h*H
        bbox_dict['id']=i*10000+j
        bbox_dict['image_id']=int(imageFile[:-4])
        bbox_dict['category_id']=class_id
        bbox_dict['iscrowd']=0
        height,width=abs(ymax-ymin),abs(xmax-xmin)
        bbox_dict['area']=height*width
        bbox_dict['bbox']=[xmin,ymin,w,h]
        bbox_dict['segmentation']=[[xmin,ymin,xmax,ymin,xmax,ymax,xmin,ymax]]
        write_json_context['annotations'].append(bbox_dict)

name = os.path.join(save_path,"instances_val2017"+ '.json')
with open(name,'w') as fw:
    json.dump(write_json_context,fw,indent=2)
print("ok")

class.txt文件格式如下(将所有类别写入,可与数据集的yaml文件中的类别顺序保持一致)

'airplane',
 'airport',
 'baseballfield',
 'basketballcourt',
 'bridge'

运行txtococo.py文件   即可在annotations文件下生成instance_val2017.json文件

然后在val.py文件中加入语句save_json=True即可生成预测的json文件

    model.val(
        save_json=True)

新建一个python文件get_COCO_metrics.py    该文件用于对比两个json文件生成coco评价指标

import argparse
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval

def parse_opt():
    parser = argparse.ArgumentParser()
    parser.add_argument('--anno_json', type=str, default='这里改为数据集转化后生成的json文件路径', help='training model path')
    parser.add_argument('--pred_json', type=str, default='这里改为val后生成的预测json文件路径', help='data yaml path')
    
    return parser.parse_known_args()[0]

if __name__ == '__main__':
    opt = parse_opt()
    anno_json = opt.anno_json
    pred_json = opt.pred_json

    anno = COCO(anno_json)  # init annotations api
    print(pred_json)
    pred = anno.loadRes(pred_json)  # init predictions api
    eval = COCOeval(anno, pred, 'bbox')
    eval.evaluate()
    eval.accumulate()
    eval.summarize()

以上为输出coco评价指标的全过程,有些人可能会出现报错AssertionError: Results do not correspond to current coco set,该报错的原因是数据集转化后生成的json文件与运行val文件后生成的预测json文件中的图像id不匹配  (可对比两个json文件看是哪里没有匹配)

若为imageid不匹配则可新建两个python文件分别将两个json文件的image_id调为相同的格式  ,image_id.py文件内容如下

import json
import os

# 读取源文件
with open('predictions.json', 'r') as file:
    data = json.load(file)

# 对每个字典进行处理
for item in data:
    # 如果字典中包含 'image_id' 键
    if 'image_id' in item:
        # 将 'image_id' 值转换为5位数形式,并在前面用0填充
        item['image_id'] = str(item['image_id']).zfill(5)

# 获取当前脚本所在目录
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构建新文件的路径
new_file_path = os.path.join(current_dir, 'new_pre_file.json')

# 将修改后的内容写入到新文件中
with open(new_file_path, 'w') as file:
    json.dump(data, file, indent=4)

只需修改之前json文件与修改后新生成json文件的路径即可     通过两个文件(分别对应之前的两个json文件与新生成的统一格式的json文件)  运行这两个python文件,最后在get_coco_metrics.py文件中将两个json文件的路径修改为调整后的json文件路径,运行get_coco_metric.py文件,成功输出coco评价指标!

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值