如何把利用paddlepaddle导出的json文件转化为yolo或者voc文件

这篇具有很好参考价值的文章主要介绍了如何把利用paddlepaddle导出的json文件转化为yolo或者voc文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 修改源码,让模型能够生成出对于单个图像的标注。

2. 把数据转为yolo格式

3.把yolo格式转化为xml格式


这两天想偷懒,想让模型先在数据上标一遍,然后我再做修正,主要是图个省事。由于我们主要是利用paddle,模型也是基于paddle推理的,因此即便我对paddle有一万个吐槽但也不得不用它。但在利用paddle保存推理结果文件时,遇到了一个大问题:就是paddle推理出来的所有数据都在同一个json文件,并且导入labelimg中也不能正常的显示到标注的框,不能对数据进行矫正。因此我就想着在代码中间能不能修改某些内容。

如果你是真想把json文件转化为yolo或者xml的话,那哥们儿,你的思路走窄了,从json里面分离出那么多垃圾消息出来,很难的 !!!

接下来介绍一下我的做法:

1. 修改源码,让模型能够生成出对于单个图像的标注。

首先就是修改源码,对应的文件为 PaddleDetection/ppdet/engine/trainer.py 。

添加下述代码:

class_label=['背景',
             '添加你的检测物品标签'
            ]
def save_result_txt(save_path,boxs,threshold=0.5):#,tszie=640,osize=608
    with open(save_path,'w') as f:
        for msg in boxs:
            if msg['score']>threshold:
                bbox=msg['bbox']
                x1,y1,w,h=bbox
                img_m = Image.open('dataset/yz_new_0815/data/0.5data/'+save_path.split('/')[-1].replace('txt','jpg'))
                # dw = 1./img_m.width  # 图片的宽
                # dh = 1./img_m.height  # 图片的高
                print(save_path)
                # return
                bbox=np.array([x1,y1,x1+w,y1+h])
                #bbox=bbox*(tszie/osize)
                bbox=bbox.astype(np.int32)
                x1,y1,x2,y2=bbox
                # strs='%s %s %s %s %s %s\n'%(class_label[msg['category_id']],msg['score'],x1,y1,x2,y2)
                strs='%s %s %s %s %s\n'%(msg['category_id'],x1,y1,x2,y2)
                f.write(strs)

如何把利用paddlepaddle导出的json文件转化为yolo或者voc文件,开发语言,paddlepaddle,json,python,人工智能,YOLO

之后在命令行中,令save_result为True,就能保存推理的结果了。从代码中可以看出,得到的数据就是四个点的坐标,非常真诚,不想yolo那种还得归一化或者相对长宽啥的。讲真的,我就听喜欢四个点坐标这种格式的,真诚永远是必杀技。但是没办法,我目前好像没见有这种格式的。

2. 把数据转为yolo格式

书接上回,上回说到我们已经把数据变成yolo的形式,而非格式,因为我们没有对数据进行一个归一化的处理。因此在这一回我们把数据归一化,得到yolo格式的数据。代码如下:

# -*- coding:utf-8 -*-
# 作用:
# 将图片标注文件转化成yolo格式的txt标注文件
#
#
import sys
import os
import cv2
import random

data_base_dir = "./20221210_result/"  # 这里就是推理出来的yolo形式的数据(姑且叫position数据)文件所在的文件夹

file_list = []

for file in os.listdir(data_base_dir):
    if file == 'classes.txt':
        continue
    if file.endswith(".txt"):
        # print(file)
        img_name = file[:-4]
        print(file)
        # print(file[:-4])    #得到图片名,不带后缀
        
        imginfo = cv2.imread('图像所在位置文件夹' + img_name + '.jpg').shape
        # h = shape[0]  w = shape[1]

        raw_file = open(data_base_dir + file)  # 返回一个文件对象
        print('raw_file is ' + data_base_dir + file)
        new_file = open('yolo格式标注文件位置文件夹' + file, 'a+')
        line = raw_file.readline()  # 调用文件的 readline()方法
        while line:
            print(line)
            line = line.split(" ")
            print(line[1])
            # line[0] = float(line[0])
            x1 = float(line[1])
            print(x1)
            y1 = float(line[2])
            x2 = float(line[3])
            y2 = float(line[4])
            h = imginfo[0]
            w = imginfo[1]
            print('h== ' + str(h))
            print('w== ' + str(w))

            new_x = "%.6s" % ((x1 + x2) / (2 * w))
            new_y = "%.6s" % ((y1 + y2) / (2 * h))

            new_w = "%.6s" % ((x2 - x1) / w)
            new_h = "%.6s" % ((y2 - y1) / h)

            new_file.write(line[0] + ' ' + new_x + ' ' + new_y + ' ' + new_w + ' ' + new_h + '\n')
            print(line[0] + ' ' + new_x + ' ' + new_y + ' ' + new_w + ' ' + new_h + '\n')

            # print line                  # 后面跟 ',' 将忽略换行符
            # print(line, end = '')       # 在 Python 3 中使用
            line = raw_file.readline()
new_file.close()
raw_file.close()

到这一步如果不出意外的话,我们就已经把position数据转化为了yolo数据。但是如果你打开labelimg,你会发现报错了,报错的原因是没有classes.txt文件。因此在yolo格式中,一定要加上一个classes.txt文件,要不然就会报错。

一定要加上一个classes.txt文件,要不然就会报错。

一定要加上一个classes.txt文件,要不然就会报错。

一定要加上一个classes.txt文件,要不然就会报错。

重要的事情说三遍哈,已经四遍了哈哈哈。

如何把利用paddlepaddle导出的json文件转化为yolo或者voc文件,开发语言,paddlepaddle,json,python,人工智能,YOLO

3.把yolo格式转化为xml格式

上回说到,我们已经把position数据转化成了yolo格式,但是paddle这个挨千刀的,不支持yolo格式训练,至少在现在还没有对应的yaml文件。因此要是真的把数据调好了,用yolo格式还是没用,因为根本训练不了。这就提到了把yolo格式转化为xml格式的必要性了。代码如下:

import os
import xml.etree.ElementTree as ET
from xml.dom.minidom import Document
import cv2

'''
import xml
xml.dom.minidom.Document().writexml()
def writexml(self,
             writer: Any,
             indent: str = "",
             addindent: str = "",
             newl: str = "",
             encoding: Any = None) -> None
'''


class YOLO2VOCConvert:
    def __init__(self, txts_path, xmls_path, imgs_path):
        self.txts_path = txts_path  # 标注的yolo格式标签文件路径
        self.xmls_path = xmls_path  # 转化为voc格式标签之后保存路径
        self.imgs_path = imgs_path  # 读取读片的路径各图片名字,存储到xml标签文件中
        self.classes = [
                        '添加你的检测物品标签'
                        ]

    # 从所有的txt文件中提取出所有的类别, yolo格式的标签格式类别为数字 0,1,...
    # writer为True时,把提取的类别保存到'./Annotations/classes.txt'文件中
    def search_all_classes(self, writer=False):
        # 读取每一个txt标签文件,取出每个目标的标注信息
        all_names = set()
        txts = os.listdir(self.txts_path)
        # 使用列表生成式过滤出只有后缀名为txt的标签文件
        txts = [txt for txt in txts if txt.split('.')[-1] == 'txt' and txt is not 'classes.txt']
        print(len(txts), txts)
        # 11 ['0002030.txt', '0002031.txt', ... '0002039.txt', '0002040.txt']
        for txt in txts:
            txt_file = os.path.join(self.txts_path, txt)
            with open(txt_file, 'r') as f:
                print(txt_file)
                objects = f.readlines()
                for object in objects:
                    object = object.strip().split(' ')
                    print(object)  # ['2', '0.506667', '0.553333', '0.490667', '0.658667']
                    all_names.add(int(object[0]))
            # print(objects)  # ['2 0.506667 0.553333 0.490667 0.658667\n', '0 0.496000 0.285333 0.133333 0.096000\n', '8 0.501333 0.412000 0.074667 0.237333\n']

        print("所有的类别标签:", all_names, "共标注数据集:%d张" % len(txts))

        return list(all_names)

    def yolo2voc(self):
        # 创建一个保存xml标签文件的文件夹
        if not os.path.exists(self.xmls_path):
            os.mkdir(self.xmls_path)

        # 把上面的两个循环改写成为一个循环:
        imgs = os.listdir(self.imgs_path)
        txts = os.listdir(self.txts_path)
        txts = [txt for txt in txts if not txt.split('.')[0] == "classes"]  # 过滤掉classes.txt文件
        print(txts)
        # 注意,这里保持图片的数量和标签txt文件数量相等,且要保证名字是一一对应的   (后面改进,通过判断txt文件名是否在imgs中即可)
        if len(imgs) == len(txts):  # 注意:./Annotation_txt 不要把classes.txt文件放进去
            map_imgs_txts = [(img, txt) for img, txt in zip(imgs, txts)]
            txts = [txt for txt in txts if txt.split('.')[-1] == 'txt']
            print(len(txts), txts)
            for img_name, txt_name in map_imgs_txts:
                # 读取图片的尺度信息
                print("读取图片:", img_name)
                img = cv2.imread(os.path.join(self.imgs_path, img_name))
                height_img, width_img, depth_img = img.shape
                print(height_img, width_img, depth_img)  # h 就是多少行(对应图片的高度), w就是多少列(对应图片的宽度)

                # 获取标注文件txt中的标注信息
                all_objects = []
                txt_file = os.path.join(self.txts_path, txt_name)
                with open(txt_file, 'r') as f:
                    objects = f.readlines()
                    for object in objects:
                        object = object.strip().split(' ')
                        all_objects.append(object)
                        print(object)  # ['2', '0.506667', '0.553333', '0.490667', '0.658667']

                # 创建xml标签文件中的标签
                xmlBuilder = Document()
                # 创建annotation标签,也是根标签
                annotation = xmlBuilder.createElement("annotation")

                # 给标签annotation添加一个子标签
                xmlBuilder.appendChild(annotation)

                # 创建子标签folder
                folder = xmlBuilder.createElement("folder")
                # 给子标签folder中存入内容,folder标签中的内容是存放图片的文件夹,例如:JPEGImages
                folderContent = xmlBuilder.createTextNode(self.imgs_path.split('/')[-1])  # 标签内存
                folder.appendChild(folderContent)  # 把内容存入标签
                annotation.appendChild(folder)  # 把存好内容的folder标签放到 annotation根标签下

                # 创建子标签filename
                filename = xmlBuilder.createElement("filename")
                # 给子标签filename中存入内容,filename标签中的内容是图片的名字,例如:000250.jpg
                filenameContent = xmlBuilder.createTextNode(txt_name.split('.')[0] + '.jpg')  # 标签内容
                filename.appendChild(filenameContent)
                annotation.appendChild(filename)

                # 把图片的shape存入xml标签中
                size = xmlBuilder.createElement("size")
                # 给size标签创建子标签width
                width = xmlBuilder.createElement("width")  # size子标签width
                widthContent = xmlBuilder.createTextNode(str(width_img))
                width.appendChild(widthContent)
                size.appendChild(width)  # 把width添加为size的子标签
                # 给size标签创建子标签height
                height = xmlBuilder.createElement("height")  # size子标签height
                heightContent = xmlBuilder.createTextNode(str(height_img))  # xml标签中存入的内容都是字符串
                height.appendChild(heightContent)
                size.appendChild(height)  # 把width添加为size的子标签
                # 给size标签创建子标签depth
                depth = xmlBuilder.createElement("depth")  # size子标签width
                depthContent = xmlBuilder.createTextNode(str(depth_img))
                depth.appendChild(depthContent)
                size.appendChild(depth)  # 把width添加为size的子标签
                annotation.appendChild(size)  # 把size添加为annotation的子标签

                # 每一个object中存储的都是['2', '0.506667', '0.553333', '0.490667', '0.658667']一个标注目标
                for object_info in all_objects:
                    # 开始创建标注目标的label信息的标签
                    object = xmlBuilder.createElement("object")  # 创建object标签
                    # 创建label类别标签
                    # 创建name标签
                    imgName = xmlBuilder.createElement("name")  # 创建name标签
                    # print(len(self.classes))
                    imgNameContent = xmlBuilder.createTextNode(self.classes[int(object_info[0])])
                    imgName.appendChild(imgNameContent)
                    object.appendChild(imgName)  # 把name添加为object的子标签

                    # 创建pose标签
                    pose = xmlBuilder.createElement("pose")
                    poseContent = xmlBuilder.createTextNode("Unspecified")
                    pose.appendChild(poseContent)
                    object.appendChild(pose)  # 把pose添加为object的标签

                    # 创建truncated标签
                    truncated = xmlBuilder.createElement("truncated")
                    truncatedContent = xmlBuilder.createTextNode("0")
                    truncated.appendChild(truncatedContent)
                    object.appendChild(truncated)

                    # 创建difficult标签
                    difficult = xmlBuilder.createElement("difficult")
                    difficultContent = xmlBuilder.createTextNode("0")
                    difficult.appendChild(difficultContent)
                    object.appendChild(difficult)

                    # 先转换一下坐标
                    # (objx_center, objy_center, obj_width, obj_height)->(xmin,ymin, xmax,ymax)
                    x_center = float(object_info[1]) * width_img + 1
                    y_center = float(object_info[2]) * height_img + 1
                    xminVal = int(x_center - 0.5 * float(object_info[3]) * width_img)  # object_info列表中的元素都是字符串类型
                    yminVal = int(y_center - 0.5 * float(object_info[4]) * height_img)
                    xmaxVal = int(x_center + 0.5 * float(object_info[3]) * width_img)
                    ymaxVal = int(y_center + 0.5 * float(object_info[4]) * height_img)

                    # 创建bndbox标签(三级标签)
                    bndbox = xmlBuilder.createElement("bndbox")
                    # 在bndbox标签下再创建四个子标签(xmin,ymin, xmax,ymax) 即标注物体的坐标和宽高信息
                    # 在voc格式中,标注信息:左上角坐标(xmin, ymin) (xmax, ymax)右下角坐标
                    # 1、创建xmin标签
                    xmin = xmlBuilder.createElement("xmin")  # 创建xmin标签(四级标签)
                    xminContent = xmlBuilder.createTextNode(str(xminVal))
                    xmin.appendChild(xminContent)
                    bndbox.appendChild(xmin)
                    # 2、创建ymin标签
                    ymin = xmlBuilder.createElement("ymin")  # 创建ymin标签(四级标签)
                    yminContent = xmlBuilder.createTextNode(str(yminVal))
                    ymin.appendChild(yminContent)
                    bndbox.appendChild(ymin)
                    # 3、创建xmax标签
                    xmax = xmlBuilder.createElement("xmax")  # 创建xmax标签(四级标签)
                    xmaxContent = xmlBuilder.createTextNode(str(xmaxVal))
                    xmax.appendChild(xmaxContent)
                    bndbox.appendChild(xmax)
                    # 4、创建ymax标签
                    ymax = xmlBuilder.createElement("ymax")  # 创建ymax标签(四级标签)
                    ymaxContent = xmlBuilder.createTextNode(str(ymaxVal))
                    ymax.appendChild(ymaxContent)
                    bndbox.appendChild(ymax)

                    object.appendChild(bndbox)
                    annotation.appendChild(object)  # 把object添加为annotation的子标签
                f = open(os.path.join(self.xmls_path, txt_name.split('.')[0] + '.xml'), 'w')
                xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
                f.close()


if __name__ == '__main__':
    # 把yolo的txt标签文件转化为voc格式的xml标签文件
    # yolo格式txt标签文件相对路径
    txts_path1 = ''
    # 转化为voc格式xml标签文件存储的相对路径
    xmls_path1 = ''
    # 存放图片的相对路径
    imgs_path1 = ''

    yolo2voc_obj1 = YOLO2VOCConvert(txts_path1, xmls_path1, imgs_path1)
    labels = yolo2voc_obj1.search_all_classes()
    print('labels: ', labels)
    yolo2voc_obj1.yolo2voc()

如果你嫌列表要一点一点写类别太麻烦了,可以用这种方式:(classes.txt就是前面提到的类别文本)

cls = []
cnt = 0
for i in open(txtPath + 'classes.txt', 'r', encoding='utf-8').readlines():
    cls.append(i)

至此,就可以把paddle里面图里的数据转化为xml格式了。文章来源地址https://www.toymoban.com/news/detail-731195.html

到了这里,关于如何把利用paddlepaddle导出的json文件转化为yolo或者voc文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何把实体类对象转化为json(json转实体类对象)​

    使用fastjson框架解决实体类转json的问题(实体类要序列化哦,如  实体类  ) 1、序列化(实体类转json,text为json数据,user为实体类,JSON.toJSONString为固定写法) 2、反序列化(json转实体类,text为json数据,User为实体类,JSON.parseObject为固定写法) 点击下载jar

    2024年02月10日
    浏览(27)
  • 如何将JSON字符串转化成对象

    在这里只能使用ObjiectMapper这个类才能将Json字符串转成对象的格式进行输出 话不多说,直接上代码 注意事项: json字符串只能匹配上实体类里面定义的属性,没有被定义的属性是无法进行匹配赋值的

    2024年02月13日
    浏览(30)
  • [labelme避坑]——批量将labelme生成json文件转化成dataset方法

    labelme的具体安装不再重复,大家可以看看其他帖子。up主最近自己处理数据集批量转化dataset,看了很多方法,有的没讲清楚,有的不断报错,今天写一个更为清晰的帖子供大家参考, 执行成功的话记得点赞收藏,欢迎交流 ~ 如果你记得labelme安装在哪里,那就直接过去,如果

    2024年02月06日
    浏览(29)
  • 数据处理| 自己的数据集json文件转txt文件(YOLO所需文件)

    计算机视觉中文件处理的一些脚本文件! 首先一定要明确 自己的json格式 ,把自己的数据集设置为yolo所需要的格式。 #Json文件属性不同,提取信息不同 文件夹格式 json文件格式 需要提取的是 照片宽 \\\"W\\\": \\\"0.564815\\\", 照片高 \\\"H\\\": \\\"0.587961\\\", 归一化后的x,y值\\\"Point(x,y)\\\": \\\"0.587963,0.5223

    2024年02月04日
    浏览(33)
  • Golang 中空的切片转化成 JSON 后变为 null 的问题如何解决?

    目录 问题 原因 小结 在 Golang 中,经常需要将其他类型(例如 slice、map、struct 等类型)的数据转化为 JSON 格式。有时候转化的结果并不是预期中的,例如将一个空的切片转化为 JSON 时,会变成\\\"null\\\",而并非预期的\\\"[]\\\"。示例代码如下: 运行示例看下结果: 结果输出的值为 “

    2024年02月07日
    浏览(34)
  • 045:Vue读取本地上传JSON文件,导出JSON文件方法

    第045个 查看专栏目录: VUE ------ element UI 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 (1)提供vue2的一些基本操作:安装、引用,模板使用,computed,watch,生命周期(beforeCreate,created,beforeMount,mounted, beforeUpdate,upda

    2024年02月04日
    浏览(38)
  • 如何将IDEA中的插件导出或者导入插件

    事情起因是这里内网无法下载插件,只能通过局域网传输插件。。 搜了下站内好像没有人出关于IDEA插件导入导出的完整教程,自己摸索了下分享出来吧! IDEA插件位置 首先要知道的是idea存放插件的位置, 方便导入或者导出插件 dea根据版本的不同插件默认存放的位置也是 不一

    2024年02月09日
    浏览(25)
  • Java中将json字符串导出为json文件【详细步骤】

    一、概述 请根据具体需求具体改动,此代码需要将前端的数据查询出来,然后进行json字符串的转化 .getCatalogId(id)方法是根据id查出来的内容然后再进行转换成json字符串 也可以直接传入json字符串进行测试 二、代码  三、使用postman进行测试 导出的文件在D盘temp文件夹下面 下面

    2024年02月06日
    浏览(30)
  • 将YOLO数据集转成COCO格式,单个文件夹转为单个json文件,例如.../images/train转为instance_train.json

    参考链接 :objectdetection-tricks/tricks_4.py 相关视频教学:tricks_4 用于yolov5和v7中的yolo格式转换coco格式的脚本.(如何在v5和v7中输出ap_small,ap_middle,ap_large coco指标) 还可以参考相关的VOC转COCO的方式:damo-yolo/voc2coco.py 代码效果 :将数据集转成COCO格式, 单个文件夹 转为 单个json 文件

    2024年02月01日
    浏览(37)
  • 解决微信小程序报[ app.json 文件内容错误] app.json: app.json 未找到,未找到入口 app.json 文件,或者文件读取失败,请检查后重新编译

    问题原因: 导入微信开发者工具后project.config.json文件被微信开发者工具修改,缺少代码:“miniprogramRoot”: “./dist”从而导致微信开发者工具无法找到app.json文件进而报错:app.json: app.json 未找到,所以需要找到app.json 文件所在的文件夹,然后在project.config.json文件里写上aap.

    2024年02月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包