首先在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评价指标!