如何使用YOLOv5的pycocotools进行coco指标评估

news2025/1/24 8:39:46

使用YOLOv5进行coco指标评估

  • 1. 安装pycocotools
  • 2.重新排序并命名
  • 3. 将txt标签转换为json格式格式
  • 2. 生成json
  • 3. 测试是否正确
  • 4. 运行val.py
  • 完整版本(一次运行所有)

1. 安装pycocotools

pip install pycocotools -i https:pypi.douban.com/simple

2.重新排序并命名

在转换之前,如果有图片和txt名字不符合要求,运行文件会报错,因此需要将文件进行重新排序,代码如下:

  1. 可以将文件重新排序并进行重命名
  2. 可以将没有标签的文件进行删除
#第一天学习
#第一天学习
#对文件名重新顺序命名
import os

imgpath = r'F:\sjh\code\my\datasets\VOC_five\images/'
labelpath = r'F:\sjh\code\my\datasets\VOC_five\labels/'

imglist = os.listdir(imgpath)
labellist = os.listdir(labelpath)
imgn = 00000
laben = 00000

# imglist.sort(key=lambda x: int(x[:-4])) #对‘.’进行切片,并取列表的第一个值(左边的文件名)转化整数型

# print(sorted(labellist))
for imaname in imglist:

    img_id = '%05d' %imgn
    imgname = imaname.strip('.jpg')
    oriimg= imgpath + imgname + '.jpg'
    newimname = str(img_id) + '.jpg'
    newimg = imgpath +newimname
    # print(oriimg,newimg)




    orilabel = labelpath + imgname + '.txt'
    newtxtname = str(img_id) + '.txt'
    newlabel = labelpath + newtxtname
    # print(orilabel,newlabel)
    imgn += 1
    if not os.path.exists(oriimg) or not os.path.exists(orilabel):
        print("no exists img",oriimg,orilabel)
        continue
    elif oriimg == newimg:
        print("Has been renamed:",oriimg,newimg)
        continue

    img_size = os.path.getsize(oriimg)
    label_size = os.path.getsize(orilabel)
    if img_size == 0 or label_size ==0:
        print('文件是空的')
        print(orilabel,'文件已删除')
        os.remove(orilabel)
        os.remove(oriimg)
        continue
    # print(newimg,newlabel)
    # os.rename(oriimg, newimg)
    # os.rename(orilabel, newlabel)

3. 将txt标签转换为json格式格式

之后将YOLO的txt文件生成需要使用的txt文件

import os
import cv2
'''
function:可将yolo格式的数据集转换为coco格式的(1), 生成annos.txt

需要准备:
labels:yolo格式的标签,是txt格式,名字为图片名
images:原始标签对应的图片,需要有序号
'''

# 原始标签路径E:\pyCharmProject\AI\papercode\datasets\GTSDB
originLabelsDir = r'F:\sjh\code\my\datasets\VOC_five\labels'
# 转换后的文件保存路径
saveDir = r'F:\sjh\code\my\datasets\VOC_five/annos1.txt'
# 原始标签对应的图片路径
originImagesDir = r'F:\sjh\code\my\datasets\VOC_five\images'

txtFileList = os.listdir(originLabelsDir)
with open(saveDir, 'w') as fw:
    for txtFile in txtFileList:
        with open(os.path.join(originLabelsDir, txtFile), 'r') as fr:
            labelList = fr.readlines()
            for label in labelList:
                label = label.strip().split()
                x = float(label[1])
                y = float(label[2])
                w = float(label[3])
                h = float(label[4])

                # convert x,y,w,h to x1,y1,x2,y2
                imagePath = os.path.join(originImagesDir,
                                         txtFile.replace('txt', 'jpg'))
                print(imagePath)
                image = cv2.imread(imagePath)
                print(image.shape)
                H, W, _ = image.shape
                x1 = (x - w / 2) * W
                y1 = (y - h / 2) * H
                x2 = (x + w / 2) * W
                y2 = (y + h / 2) * H
                # 为了与coco标签方式对,标签序号从1开始计算
                fw.write(txtFile.replace('txt', 'jpg') + ' {} {} {} {} {}\n'.format(int(label[0]), x1, y1, x2, y2))

        print('{} done'.format(txtFile))

生成以下形式
在这里插入图片描述

2. 生成json

# -*- coding: utf-8 -*-
# @Time    : 2022/9/5
# @Author  : rickHan
# @Software: PyCharm
# @File    : yolo2coco2.py
import json
import os
import cv2

#-------------------可用-----------------------------------
'''
function:可将yolo格式的数据集转换为coco格式的(2)
需要准备:
classes.txt:一行就是一个类,不需要数字,只要类名称
annos.txt:由上一个.py文件生成
images:与annos.txt对应的图片,需要有序号

生成.json文件,在annotations文件下
'''

# ------------用os提取images文件夹中的图片名称,并且将BBox都读进去------------
# 根路径,里面包含images(图片文件夹),annos.txt(bbox标注),classes.txt(类别标签),
# 以及annotations文件夹(如果没有则会自动创建,用于保存最后的json)
root_path = r'F:\sjh\code\my\datasets\VOC_five'
# 用于创建训练集或验证集
phase = 'instances_val2017'  # 需要修正,保存后的json文件名

# dataset用于保存所有数据的图片信息和标注信息
dataset = {'categories': [], 'annotations': [], 'images': []}

# 打开类别标签
with open(os.path.join(root_path, 'classes.txt')) as f:
    classes = f.read().strip().split()

# 建立类别标签和数字id的对应关系
for i, cls in enumerate(classes, 1):
    dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})

# 读取images文件夹的图片名称
indexes = os.listdir(root_path+'/images/')

# 统计处理图片的数量
global count
count = 0

# 读取Bbox信息
with open(root_path+ '/annos1.txt') as tr:
    annos = tr.readlines()

    # ---------------接着将,以上数据转换为COCO所需要的格式---------------
    for k, index in enumerate(indexes):
        count += 1
        # 用opencv读取图片,得到图像的宽和高
        im = cv2.imread(root_path+'/images/' + index)
        height, width, _ = im.shape
        print(index)
        # 添加图像的信息到dataset中
        dataset['images'].append({'file_name': index.replace("\\", "/"),
                                  'id': int(index[:5]),  # 提取文件名 里的数字标号 必须是int类型,不能是str
                                  'width': width,
                                  'height': height})

        for ii, anno in enumerate(annos):
            parts = anno.strip().split()

            # 如果图像的名称和标记的名称对上,则添加标记
            if parts[0] == index:
                # 类别
                cls_id = parts[1]
                # x_min
                x1 = float(parts[2])
                # y_min
                y1 = float(parts[3])
                # x_max
                x2 = float(parts[4])
                # y_max
                y2 = float(parts[5])
                width = max(0, x2 - x1)
                height = max(0, y2 - y1)
                dataset['annotations'].append({
                    'area': width * height,
                    'bbox': [x1, y1, width, height],
                    'category_id': int(cls_id),
                    'id': ii,
                    'image_id': int(index[0:5]),	# 提取文件名里的数字标号  必须是int类型,不能是str
                    'iscrowd': 0,
                    # mask, 矩形是从左上角点按顺时针的四个顶点
                    'segmentation': [[x1, y1, x2, y1, x2, y2, x1, y2]]
                })

        print('{} images handled'.format(count))

# 保存结果的文件夹
folder = os.path.join(root_path, './valid/annotations')
if not os.path.exists(folder):
    os.makedirs(folder)
json_name = os.path.join(root_path, './valid/annotations/{}.json'.format(phase))
with open(json_name, 'w') as f:
    json.dump(dataset, f, ensure_ascii=False, indent=1)

3. 测试是否正确

# -*- coding: utf-8 -*-
# @Time    : 2022/9/5
# @Author  : rickHan
# @Software: PyCharm
# @File    : drawtest.py
import os
from pycocotools.coco import COCO
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt
'''
function:绘制标注的数据集和对应图片的位置是否正确
绘制前三张,如果yoyo转换标注的json数据集没有问题,则也能在图上画出框

'''
json_path = r'F:\sjh\code\my\datasets\VOC_five\valid\annotations/instances_val2017.json'
# json_path = r'predictions.json'
img_path = r'F:\sjh\code\my\datasets\VOC_five\images'  #json对应的图片

# load coco data
coco = COCO(annotation_file=json_path)

# get all image index info
ids = list(sorted(coco.imgs.keys()))
print("number of images: {}".format(len(ids)))

# get all coco class labels
coco_classes = dict([(v["id"], v["name"]) for k, v in coco.cats.items()])

# 遍历前三张图像
for img_id in ids[:3]:
    # 获取对应图像id的所有annotations idx信息
    ann_ids = coco.getAnnIds(imgIds=img_id)

    # 根据annotations idx信息获取所有标注信息
    targets = coco.loadAnns(ann_ids)

    # get image file name
    path = coco.loadImgs(img_id)[0]['file_name']

    # read image
    img = Image.open(os.path.join(img_path, path)).convert('RGB')
    draw = ImageDraw.Draw(img)
    # draw box to image
    for target in targets:
        x, y, w, h = target["bbox"]
        x1, y1, x2, y2 = x, y, int(x + w), int(y + h)
        draw.rectangle((x1, y1, x2, y2))
        draw.text((x1, y1), coco_classes[target["category_id"]])

    # show image
    plt.imshow(img)
    plt.show()

测试没有问题,就可以使用了

4. 运行val.py

json文件存放位置,放到测试文件总目录下

.\annotations\instances_val2017.json
python val.py --save-json

结果
在这里插入图片描述

完整版本(一次运行所有)

import os
import cv2
import json
import os
from pycocotools.coco import COCO
from PIL import Image, ImageDraw
import matplotlib.pyplot as plt
'''
**************** first ****************
function:可将yolo格式的数据集转换为coco格式的(1), 生成annos.txt
需要准备:
labels:yolo格式的标签,是txt格式,名字为图片名
images:原始标签对应的图片,需要有序号
'''
root_dir=r'F:\sjh\code\my\datasets\VOC_five'
def first_to_annostxt():
    # 原始标签路径E:\pyCharmProject\AI\papercode\datasets\GTSDB
    originLabelsDir = root_dir + '/labels'
    # 转换后的文件保存路径
    saveDir = root_dir + '/annos1.txt'
    # 原始标签对应的图片路径
    originImagesDir = root_dir + '/images'

    txtFileList = os.listdir(originLabelsDir)
    with open(saveDir, 'w') as fw:
        for txtFile in txtFileList:
            with open(os.path.join(originLabelsDir, txtFile), 'r') as fr:
                labelList = fr.readlines()
                for label in labelList:
                    label = label.strip().split()
                    x = float(label[1])
                    y = float(label[2])
                    w = float(label[3])
                    h = float(label[4])

                    # convert x,y,w,h to x1,y1,x2,y2
                    imagePath = os.path.join(originImagesDir,
                                             txtFile.replace('txt', 'jpg'))
                    print(imagePath)
                    image = cv2.imread(imagePath)
                    print(image.shape)
                    H, W, _ = image.shape
                    x1 = (x - w / 2) * W
                    y1 = (y - h / 2) * H
                    x2 = (x + w / 2) * W
                    y2 = (y + h / 2) * H
                    # 为了与coco标签方式对,标签序号从1开始计算
                    fw.write(txtFile.replace('txt', 'jpg') + ' {} {} {} {} {}\n'.format(int(label[0]), x1, y1, x2, y2))

            print('{} done'.format(txtFile))
def secon_tojson():
    #-------------------可用-----------------------------------
    '''
    function:可将yolo格式的数据集转换为coco格式的(2)
    需要准备:
    classes.txt:一行就是一个类,不需要数字,只要类名称
    annos.txt:由上一个.py文件生成
    images:与annos.txt对应的图片,需要有序号

    生成.json文件,在annotations文件下
    '''
    # ------------用os提取images文件夹中的图片名称,并且将BBox都读进去------------
    # 根路径,里面包含images(图片文件夹),annos.txt(bbox标注),classes.txt(类别标签),
    # 以及annotations文件夹(如果没有则会自动创建,用于保存最后的json)
    root_path = root_dir
    # 用于创建训练集或验证集
    phase = 'instances_val2017'  # 需要修正,保存后的json文件名

    # dataset用于保存所有数据的图片信息和标注信息
    dataset = {'categories': [], 'annotations': [], 'images': []}

    # 打开类别标签
    with open(os.path.join(root_path, 'classes.txt')) as f:
        classes = f.read().strip().split()

    # 建立类别标签和数字id的对应关系
    for i, cls in enumerate(classes, 1):
        dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})

    # 读取images文件夹的图片名称
    indexes = os.listdir(root_path+'/images/') #读取文件

    # 统计处理图片的数量
    global count
    count = 0

    # 读取Bbox信息
    with open(root_path+ '/annos1.txt') as tr: #读取文件
        annos = tr.readlines()

        # ---------------接着将,以上数据转换为COCO所需要的格式---------------
        for k, index in enumerate(indexes):
            count += 1
            # 用opencv读取图片,得到图像的宽和高
            im = cv2.imread(root_path+'/images/' + index) #读取文件
            height, width, _ = im.shape
            print(index)
            # 添加图像的信息到dataset中
            dataset['images'].append({'file_name': index.replace("\\", "/"),
                                      'id': int(index[:5]),  # 提取文件名 里的数字标号 必须是int类型,不能是str
                                      'width': width,
                                      'height': height})

            for ii, anno in enumerate(annos):
                parts = anno.strip().split()

                # 如果图像的名称和标记的名称对上,则添加标记
                if parts[0] == index:
                    # 类别
                    cls_id = parts[1]
                    # x_min
                    x1 = float(parts[2])
                    # y_min
                    y1 = float(parts[3])
                    # x_max
                    x2 = float(parts[4])
                    # y_max
                    y2 = float(parts[5])
                    width = max(0, x2 - x1)
                    height = max(0, y2 - y1)
                    dataset['annotations'].append({
                        'area': width * height,
                        'bbox': [x1, y1, width, height],
                        'category_id': int(cls_id),
                        'id': ii,
                        'image_id': int(index[0:5]),	# 提取文件名里的数字标号  必须是int类型,不能是str
                        'iscrowd': 0,
                        # mask, 矩形是从左上角点按顺时针的四个顶点
                        'segmentation': [[x1, y1, x2, y1, x2, y2, x1, y2]]
                    })

            print('{} images handled'.format(count))

    # 保存结果的文件夹
    folder = os.path.join(root_path, './annotations')
    if not os.path.exists(folder):
        os.makedirs(folder)
    json_name = os.path.join(root_path, './annotations/{}.json'.format(phase))
    with open(json_name, 'w') as f:
        json.dump(dataset, f, ensure_ascii=False, indent=1)

'''
function:绘制标注的数据集和对应图片的位置是否正确
绘制前三张,如果yoyo转换标注的json数据集没有问题,则也能在图上画出框

'''
def third_toview():
    json_path = root_dir+'/annotations/instances_val2017.json'
    # json_path = r'predictions.json'
    img_path = root_dir+'/images'  #json对应的图片
    
    # load coco data
    coco = COCO(annotation_file=json_path)
    
    # get all image index info
    ids = list(sorted(coco.imgs.keys()))
    print("number of images: {}".format(len(ids)))
    
    # get all coco class labels
    coco_classes = dict([(v["id"], v["name"]) for k, v in coco.cats.items()])
    
    # 遍历前三张图像
    for img_id in ids[:3]:
        # 获取对应图像id的所有annotations idx信息
        ann_ids = coco.getAnnIds(imgIds=img_id)
    
        # 根据annotations idx信息获取所有标注信息
        targets = coco.loadAnns(ann_ids)
    
        # get image file name
        path = coco.loadImgs(img_id)[0]['file_name']
    
        # read image
        img = Image.open(os.path.join(img_path, path)).convert('RGB')
        draw = ImageDraw.Draw(img)
        # draw box to image
        for target in targets:
            x, y, w, h = target["bbox"]
            x1, y1, x2, y2 = x, y, int(x + w), int(y + h)
            draw.rectangle((x1, y1, x2, y2))
            draw.text((x1, y1), coco_classes[target["category_id"]])
    
        # show image
        plt.imshow(img)
        plt.show()
first_to_annostxt()
secon_tojson()
third_toview()

如图所示准备数据即可
在这里插入图片描述

参考https://blog.csdn.net/m0_59967951/article/details/126703053

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/433858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML5 <meter> 标签、HTML5 <mark> 标签

HTML5 <meter> 标签 实例 使用 meter 元素展示给定的数据范围&#xff1a; <meter value"2" min"0" max"10">2 out of 10</meter><br> <meter value"0.6">60%</meter>尝试一下 浏览器支持 Fir…

【Python知识】2个特别好用的python模块(请收藏!)

文章目录 前言一、介绍二、FuzzyWuzzy库介绍2.1 fuzz模块2.2 简单匹配&#xff08;Ratio&#xff09;2.3 非完全匹配&#xff08;Partial Ratio&#xff09;2.3 忽略顺序匹配&#xff08;Token Sort Ratio&#xff09;2.4 去重子集匹配&#xff08;Token Set Ratio&#xff09;…

matlab数据归一化与反归一化处理

假如数据实际取值范围为 X i ∈ [ − π π ] , i 1 , 2 , 3 X_i \in [-\pi \ \ \pi], i1,2,3 Xi​∈[−π π],i1,2,3&#xff0c;变量服从正态分布 示例如下&#xff1a; %% 数据归一化处理及其概率密度函数 clear clc Mu [0 0 0]; % 均值 Sigma [1 1 1]; % 标准差 C…

EA使用教程

文章目录 创建新工程属性设置导出图片到剪切板时序图中取消消息后面自动生成的括号在文本框中回车取消流程图的背景渐变导出更清晰图片 创建新工程 1. 点击 FILE -> New Project 开始创建新工程 2. 为新工程命名 3. 选择模型 以下为常用设计模型&#xff1a; Business …

Java并发工具合集JUC大爆发

1. CountDownLatch CountDownLatch是一个同步计数器&#xff0c;初始化的时候 传入需要计数的线程等待数&#xff0c;可以是需要等待执行完成的线程数&#xff0c;或者大于 &#xff0c;一般称为发令枪。\ ​ countdownlatch 是一个同步类工具&#xff0c;不涉及锁定&#xff0…

我实现了一个乞丐版的评论功能

文章目录 设计评论功能0 设计初衷1 前端组建设计**设计原则****设计代码**组件核心代码**调用组建并给出mock数据****效果** 2 后端数据库设计3 后端接口设计4 前后端联调5 后端评论保存接口设计6 前端评论填写流程设计7 联调8 验证码美化 设计评论功能 0 设计初衷 经过长达八…

三百左右的蓝牙耳机哪个音质好?三百左右音质最好的蓝牙耳机推荐

在外出携带的数码产品中&#xff0c;蓝牙耳机的出现频率居高不下&#xff0c;一部手机&#xff0c;一副耳机已经成为不少人外出的标配。蓝牙耳机无外乎是用来听的&#xff0c;下面&#xff0c;我来给大家推荐几款三百左右音质好的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡…

LabVIEW-字符串与路径控件

在前面板中字符串与路径控件位于下图所示位置&#xff1a; 字符串输入和显示功能&#xff0c;是用户最常用的基本操作功能单击字符串控件&#xff0c;鼠标右键&#xff0c;选择“属性”可以对字符串控件的外观进行设置。显示样式有四种方式&#xff0c;即正常、反斜杠符号、密码…

家用洗地机好用吗?好用的洗地机分享

洗地机是一种高效、节能、环保的清洁设备&#xff0c;广泛应用于各种场所的地面清洁工作。它不仅可以快速清洁地面&#xff0c;还可以有效去除污渍、油渍等难以清洁的污染物&#xff0c;让地面恢复光洁如新的状态。同时&#xff0c;洗地机还可以减少清洁人员的劳动强度&#xf…

研读Rust圣经解析——Rust learn-10(泛型,trait,生命周期)

研读Rust圣经解析——Rust learn-10&#xff08;泛型&#xff0c;trait&#xff0c;生命周期&#xff09; 泛型应用泛型方法泛型结构体枚举泛型方法定义中的泛型 trait定义一个trait默认trait方法实现为结构体实现trait调用trait中实现的方法将trait作为参数trait bound多实现入…

2023年6月CDGP数据治理专家认证考试火热报名中

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

数据结构—单链表

目录 1.前言 2.了解单链表 3.单链表代码实现 3.1 单链表结构体实现 3.2 创建节点 3.3 打印单链表 3.4 尾插 3.5 头插 3. 6 头删 3.7 尾删 3.8 查找 3.9 插入 3.9.1 在pos位置之前插入 3.9.2 在pos位置之后插入&#xff08;主要使用这种功能&#xff09;---不需要找…

家用洗地机到底好不好用?家用洗地机分享

在当今社会&#xff0c;人们越来越关注卫生和清洁&#xff0c;这也促进了家庭和工作场所对清洁设备的需求。洗地机就是其中之一&#xff0c;它的高效和便捷性为我们提供了清洁和保洁的重要帮助。使用洗地机不仅能够卫生地保持地面清洁&#xff0c;而且可以节省时间和人力成本。…

拼多多的天天618,如何掀开电商营销的“皇帝新衣”?

电商价格战如火如荼&#xff0c;拼多多也在2023年4月正式启动“数码家电消费季”百亿补贴。 首季将在百亿补贴的基础上加码10亿&#xff0c;对手机、平板等各种数码家电&#xff0c;提供全品类补贴&#xff0c;苹果、华为、小米、美的等国内外各大品牌均会参与。拼多多相关负责…

安装虚拟机VMshare

前言&#xff1a;虚拟机必须在开机的状态下&#xff0c;而且互相需ping通&#xff0c;mobax才可以连接成功 一、下载VMsharePro软件 1、双击 安装程序&#xff1b; 2、按照步骤 点击一个个的“下一步” 3、安装完成之后&#xff0c;会要求你 输入许可证&#xff0c;这个可以…

【Redis】Redis十大数据类型—字符串String

介绍 获取命令地址 英文&#xff1a;https://redis.io/commands/ 中文&#xff1a;http://www.redis.cn/commands.html 字符串(string) 字符串是一种最基本的Redis值类型。Redis字符串是二进制安全的&#xff0c;这意味着一个Redis字符串能包含任意类型的数据&#xff0c;例…

STM:基于Siamese编码器的时空混频器用于CT扫描肺结节生长趋势预测

文章目录 Siamese Encoder-based Spatial-Temporal Mixer for Growth Trend Prediction of Lung Nodules on CT Scans摘要方法Spatial-Temporal MixerTwo-Layer H-Loss 实验结果 Siamese Encoder-based Spatial-Temporal Mixer for Growth Trend Prediction of Lung Nodules on…

JavaScript的三座大山

前言&#xff1a;这个题目是抄的&#xff0c;看着很有意思&#xff0c;就拿过用了&#xff0c;毕竟CV是程序员的基本功底嘛&#xff0c;顺带把图也拿过来了 作用域和闭包 这个几乎是天天在用的东西&#xff0c;可能有些人甚至不知道这个概念&#xff0c;但是用到过这种方法去解…

Dubbo消费者调用流程分析

消费者在发起一次调用的时候时序图如下 由于Dubbo调用是基于动态代理的方式,所以请求先进入 InvokerInvocationHandler#invoke()方法,进而调用到MockClusterInvoker#invoke()方法。MockClusterInvoker#invoke()中判断是否需要开启 Mock,如果开启 Mock 调用 doMockInvoke 执行…

WebRTC系列-Qos系列之AEC-可配置参数

文章目录 1. 简介2. 源码中相关参数WebRTC的自适应回声消除(AEC)是一个广泛使用的技术,用于在音频通信中消除扬声器输出产生的回声。在WebRTC中,有三种AEC算法可供选择,分别是 AECM、 AEC和 AEC3。本文将介绍WebRTC AEC 3算法的原理和应用场景。 在上图中可以看出AEC算…