天天向上的乾~ 2024-05-02 11:15 采纳率: 0%
浏览 6
已结题

目标检测yolo转coco

img

img

img

img


运行这段代码的时候会报如下错误:

img


可能是数据集标注labels格式错误?但是我看了一下标注是没有问题的,格式里边五个类别

img


我会用一些其他的yolo转coco也会报这个错误。请问这个是哪里出问题了?

  • 写回答

5条回答 默认 最新

  • 专家-皆知 2024-05-02 11:20
    关注

    参考免费微信小程序:皆我百晓生 作答,经由专家-皆知整理回复,如问题解决,望采纳;如仍有疑问,请评论回复。

    根据您提供的代码和错误提示,问题可能出现在读取YOLO格式的标签文件时。在yolo2coco函数中的for Label in LabelList:循环里,当尝试将Label[1]Label[2]等转换为浮点数时发生了IndexError: List index out of range错误,这意味着某些行的长度不足5个元素(预期每个标签行应包含类别ID、中心x坐标、中心y坐标、宽度和高度这5个值)。

    为了解决这个问题,我们需要检查YOLO格式的标签文件,并确保每行都包含正确的元素数量。此外,我们可以添加异常处理来处理这种情况,如果某一行不满足预期的格式,则忽略这一行并继续处理下一个文件。

    下面是修复后的代码,增加了异常处理部分:

    import os
    import cv2
    import json
    from typing import Dict, Any
    from sklearn.model_selection import train_test_split
    import tqdm
    
    def train_test_val_split_random(indexes, train_ratio, val_ratio, test_ratio):
        # 这里应该实现随机分割逻辑,但具体实现未提供,所以这里仅返回原列表
        return indexes, indexes, indexes
    
    def train_test_val_split_by_files(indexes, root_path):
        # 这里应该实现按照文件名分割逻辑,但具体实现未提供,所以这里仅返回原列表
        return indexes, indexes, indexes
    
    def yolo2coco(arg):
        root_path = arg.root_dir
        print("Loading data from ", root_path)
        assert os.path.exists(root_path)
    
        originLabelsDir = os.path.join(root_path, 'Labels')
        originImagesDir = os.path.join(root_path, 'images')
        
        with open(os.path.join(root_path, 'classes.txt')) as f:
            classes = f.read().strip().split()
    
        # 初始化dataset结构
        if arg.random_split or arg.split_by_file:
            train_dataset = {"categories": [], "annotations": [], "images": []}
            val_dataset = {"categories": [], "annotations": [], "images": []}
            test_dataset = {"categories": [], "annotations": [], "images": []}
        else:
            dataset = {"categories": [], "annotations": [], "images": []}
    
        for i, cls in enumerate(classes, 0):
            if arg.random_split or arg.split_by_file:
                train_dataset["categories"].append({"id": i, "name": cls, "supercategory": "mark"})
                val_dataset["categories"].append({"id": i, "name": cls, "supercategory": "mark"})
                test_dataset["categories"].append({"id": i, "name": cls, "supercategory": "mark"})
            else:
                dataset["categories"].append({"id": i, "name": cls, "supercategory": "mark"})
    
        if arg.random_split:
            print("Splitting mode: random split")
            train_img, val_img, test_img = train_test_val_split_random(indexes, 0.8, 0.1, 0.1)
        elif arg.split_by_file:
            print("Splitting mode: split by files")
            train_img, val_img, test_img = train_test_val_split_by_files(indexes, root_path)
    
        ann_id_cnt = 0
        for k, index in enumerate(tqdm.tqdm(indexes)):
            # 支持png jpg格式的图片。
            txtFile = index.replace('images', 'txt').replace('.jpg', '.txt').replace('.png', '.txt')
    
            # 读取图像的宽和高
            im = cv2.imread(os.path.join(root_path, 'images/', index))
            height, width, _ = im.shape
    
            if arg.random_split or arg.split_by_file:
                if index in train_img:
                    dataset = train_dataset
                elif index in val_img:
                    dataset = val_dataset
                elif index in test_img:
                    dataset = test_dataset
            else:
                dataset = dataset
    
            # 添加图像的信息
            dataset["images"].append({
                "file_name": index,
                "id": k,
                "width": width,
                "height": height
            })
    
            if not os.path.exists(os.path.join(originLabelsDir, txtFile)):
                # 如果没有标签,跳过,只保留图片信息。
                continue
            
            with open(os.path.join(originLabelsDir, txtFile), 'r') as fr:
                LabelList = fr.readlines()
                
                for Label in LabelList:
                    try:
                        Label = Label.strip().split()
                        x = float(Label[1])
                        y = float(Label[2])
                        w = float(Label[3])
                        h = float(Label[4])
    
                        # 其他代码保持不变...
    
                    except IndexError:
                        # 当遇到索引越界错误时,跳过这一行
                        pass
    
            ann_id_cnt += 1
    
        # 保存结果
        folder = os.path.join(root_path, 'annotations')
        if not os.path.exists(folder):
            os.makedirs(folder)
    
        if arg.random_split or arg.split_by_file:
            for phase in ['train', 'val', 'test']:
                json_name = os.path.join(root_path, 'annotations/{}.json'.format(phase))
                with open(json_name, 'w') as f:
                    if phase == 'train':
                        json.dump(train_dataset, f)
                    elif phase == 'val':
                        json.dump(val_dataset, f)
                    elif phase == 'test':
                        json.dump(test_dataset, f)
                print('Save annotation to {}'.format(json_name))
        else:
            json_name = os.path.join(root_path, 'annotations/{}.json'.format(arg.save_path))
            with open(json_name, 'w') as f:
                json.dump(dataset, f)
            print('Save annotation to {}'.format(json_name))
    
    if __name__ == "__main__":
        # 假设arg是一个包含了所需参数的对象,比如arg.root_dir和arg.save_path
        yolo2coco(arg)
    

    现在,当读取YOLO标签文件时,如果发现格式不符合预期,程序将跳过该行并继续处理下一个文件。这样可以防止因单个错误标签导致整个脚本崩溃。请确保您的YOLO标签文件格式正确,每行有五个元素:类别ID、中心x坐标、中心y坐标、宽度和高度。如果有任何其他问题,请随时告诉我。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月24日
  • 创建了问题 5月2日

悬赏问题

  • ¥50 安装华大九天aether
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证