labelme的json标签和图像改变分辨率,再将json转换为YOLO的txt格式进行实例分割

news2024/12/23 6:31:13

最近在做一个分割数据集,训练数据时由于图像数据太大一直爆显存,然后就找了找同时resize图像和json的脚本,然后转换为YOLO格式一直出问题,标签和目标位置对不上,也是困扰了好久,终于解决,记录一下。

首先是resize图像和json,下面是找到的一个脚本,他可以自定义宽高其中一个,另一个根据比例改变,参考的这个链接对labelme已经标注的图片和json文件做resize操作_Yee_Ko的博客-CSDN博客

这个src_dir和 dst_dir是处理前后的路径,src_dir里要同时放图像和json,w_new = “”这里改你想要的大小

import cv2
import os
import glob
import json
import collections
import numpy as np
from labelme import utils
#这个文件可以更改图像和json文件的分辨率,但是是宽高改一个,另一个比例改,改后的json文件图像的宽高有问题
#需要用到json_hw更改
if __name__ == "__main__":
    src_dir = r'E:\seg_resize\before'
    dst_dir = r'E:\seg_resize\after'

    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    # 先收集一下文件夹中图片的格式列表,例如 ['.jpg', '.JPG']
    exts = dict()
    filesnames = os.listdir(src_dir)
    for filename in filesnames:
        name, ext = filename.split('.')
        if ext != 'json':
            if exts.__contains__(ext):
                exts[ext] += 1
            else:
                exts[ext] = 1

    anno = collections.OrderedDict()  # 这个可以保证保存的字典顺序和读取出来的是一样的,直接使用dict()的话顺序会很乱(小细节哦)
    for key in exts.keys():
        for img_file in glob.glob(os.path.join(src_dir, '*.' + key)):
            file_name = os.path.basename(img_file)
            print(f"Processing {file_name}")
            img = cv2.imread(img_file)
            (h, w, c) = img.shape  # 统计了一下,所有图片的宽度里面,1344是占比较多的宽度中最小的那个,因此
            # 都等比例地将宽resize为1344(这里可以自己修改)
            w_new = 1440
            h_new = int(h / w * w_new)  # 高度等比例缩放
            ratio = w_new / w  # 标注文件里的坐标乘以这个比例便可以得到新的坐标值
            img_resize = cv2.resize(img, (w_new, h_new))  # resize中的目标尺寸参数为(width, height)
            cv2.imwrite(os.path.join(dst_dir, file_name), img_resize)

            # 接下来处理标注文件json中的标注点的resize
            json_file = os.path.join(src_dir, file_name.split('.')[0] + '.json')
            save_to = open(os.path.join(dst_dir, file_name.split('.')[0] + '.json'), 'w')
            with open(json_file, 'rb') as f:
                anno = json.load(f)
                for shape in anno["shapes"]:
                    points = shape["points"]
                    points = (np.array(points) * ratio).astype(int).tolist()
                    shape["points"] = points

                # 注意下面的img_resize编码加密之前要记得将通道顺序由BGR变回RGB
                anno['imageData'] = str(utils.img_arr_to_b64(img_resize[..., (2, 1, 0)]), encoding='utf-8')
                json.dump(anno, save_to, indent=4)
    print("Done")

但是用这个脚本处理后,我想使用YOLOv8做实例分割,后来发现怎么也转换不对,经过别人提醒,原因是json转txt的代码中获取的是json中的图像长宽计算的,这个脚本并没有改变json中记录的原图像长宽,所以写了一个文件根据resize后的图像长宽去改json中的值,命名为json_hw.py,下边代码中的json_dir和image_dir要放你的json和resize后图像的路径,到这步就改完了json文件了。

import json
import os
from PIL import Image
#这是一个调整图像分辨率后,但是json文件记录的高宽没有改变,使用这个脚本可以将json文件中的图像高宽改为实际图像高宽


def update_image_resolution(json_dir, image_dir):
    json_files = os.listdir(json_dir)

    for json_file in json_files:
        json_path = os.path.join(json_dir, json_file)
        image_path = os.path.join(image_dir, os.path.splitext(json_file)[0] + '.jpg')

        # 读取JSON文件
        with open(json_path, 'r') as f:
            data = json.load(f)

        # 获取图像的实际大小
        image = Image.open(image_path)
        width, height = image.size

        # 更新JSON文件中的分辨率字段
        data['imageHeight'] = height
        data['imageWidth'] = width

        # 保存更新后的JSON文件
        with open(json_path, 'w') as f:
            json.dump(data, f, indent=4)


if __name__ == "__main__":
    json_dir = r'E:\yolov5-master\mydata\json'
    image_dir = r'E:\yolov5-master\mydata\images'

    update_image_resolution(json_dir, image_dir)

然后随便找了一个json转YOLO的txt格式的脚本,这个一搜很多,我这里随便放一个,json-dir是你json文件的保存路径,save-dir是txt文件的保存路径,classes是你的数据集中的类别,我这代码中写了三类,分别是bud,inflorescence,branch,这三类的顺序和你YOLOv5或者v8的数据集的yaml文件对应好顺序就行,v5和v8都适用,我是用的下面这位博主提供的脚本,这个就是获取json中的图像长宽,也是resize后一直出问题的原因:h, w = json_dict['imageHeight'], json_dict['imageWidth']

YOLOv8实例分割训练自己的数据集保姆级教程_dg68668的博客-CSDN博客

# -*- coding: utf-8 -*-
import json
import os
import argparse
from tqdm import tqdm
from PIL import Image

#这是一个将json文件转换为YOLO格式的txt文件的脚本
def convert_label_json(json_dir, save_dir, classes):
    json_paths = os.listdir(json_dir)
    classes = classes.split(',')


    for json_path in tqdm(json_paths):
        # for json_path in json_paths:
        path = os.path.join(json_dir, json_path)
        with open(path, 'r') as load_f:
            json_dict = json.load(load_f)

        h, w = json_dict['imageHeight'], json_dict['imageWidth']

        # save txt path
        txt_path = os.path.join(save_dir, json_path.replace('json', 'txt'))
        txt_file = open(txt_path, 'w')

        for shape_dict in json_dict['shapes']:
            label = shape_dict['label']
            label_index = classes.index(label)
            points = shape_dict['points']

            points_nor_list = []

            for point in points:
                points_nor_list.append(point[0] / w)
                points_nor_list.append(point[1] / h)

            points_nor_list = list(map(lambda x: str(x), points_nor_list))
            points_nor_str = ' '.join(points_nor_list)

            label_str = str(label_index) + ' ' + points_nor_str + '\n'
            txt_file.writelines(label_str)


if __name__ == "__main__":
    """
    python json2txt_nomalize.py --json-dir my_datasets/color_rings/jsons --save-dir my_datasets/color_rings/txts --classes "cat,dogs"
    """
    parser = argparse.ArgumentParser(description='json convert to txt params')
    parser.add_argument('--json-dir', type=str, default=r'E:\ultralytics-main\ultralytics\mydata\json', help='json path dir')
    parser.add_argument('--save-dir', type=str, default=r'E:\ultralytics-main\ultralytics\mydata\txt', help='txt save dir')
    parser.add_argument('--classes', type=str, default='bud,inflorescence,branch', help='classes')
    args = parser.parse_args()
    json_dir = args.json_dir
    save_dir = args.save_dir
    classes = args.classes
    convert_label_json(json_dir, save_dir, classes)

这个一整套下来就很轻松地将labelme的标签转换成YOLOv5(v5要7.0版本)或者v8需要的分割数据集了,各位加油,如果有帮助就给点个赞吧!!!

 

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

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

相关文章

惠普笔记本U盘重装Win10系统步骤

当惠普笔记本出现系统故障或需要清除所有数据时,通过使用U盘重新安装Win10系统是一个常见且有效的解决方法。重新安装系统可以解决许多问题,并为用户提供一个干净、流畅的操作环境。以下小编将为用户介绍惠普笔记本U盘重装Win10系统步骤。请注意&#xf…

手把手教学,Python 游戏编程之实现飞机大战(含源代码)

文章目录 一、游戏设定 1、游戏界面展示和设定 二、实现过程 1.我方飞机 2、敌方飞机 3、定义武器 4、武器补充库 5、主模块 总结: 前言 我想大家都是有玩过类似飞机大战的射击类游戏,也享受目标被消除通过后带来的愉悦感。 那么如果用Python来实现飞机…

Image Sensor的窗口裁剪

本文介绍Image Sensor的窗口裁剪,Image Sensor的实际像素通常是大于实际所支持的最大分辨率的,有时为了获得想要的分辨率及位置(比如与镜头装配相匹配),需要设置Image Sensor的像素输出位置及大小,本文以OS…

为什么向导式对话框中的取消按钮始终可用

PropSheet_SetWizButtons 是一个宏,其定义位于 PRSHT.H 头文件中,实际上,它只是调用了 PostMessage 函数来向目标窗口发送 PSM_SETWIZBUTTONS 这个消息,仅此而已。 如果你亲自上阵体验一番,就会发现有这么一个问题(特…

c++ stl 之vector使用

参考:https://www.runoob.com/cplusplus/cpp-stl-tutorial.html “C STL(标准模板库)是一套功能强大的 C 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向…

特征向量可视化01_tsne_pca

在学习机器学习或深度学习基础知识的同时训练模型是一个非常有指导性的过程。该数据集易于理解且格式适当,可供您使用。然而,当您走进现实世界并尝试解决行业或现实生活中的挑战时,数据集如果一开始就不存在,通常会很混乱。理解为…

uniapp怎么把px转换成对应手机型号的rpx

首先获取系统手机屏幕的宽度系统信息的概念 | uni-app官网,然后根据公式转换 rpx 750*元素 B 在设计稿上的宽度为 多少px/手机屏幕的宽度 详见:CSS 支持 | uni-app官网 如下为把宽度为1px的转成对应手机型号的rpx uni.getSystemInfo({success(res) {co…

网络营销VS传统营销有什么区别?

随着互联网的普及和发展,网络营销已经成为企业营销的重要手段之一。相比传统营销,网络营销具有更多的优势和特点。本文将从市场环境、营销手段、成本效益等方面,分析网络营销与传统营销的区别。#网络营销# 一、市场环境不同 传统营销主要是通…

华为OD机试真题 Python 实现【查找单入口空闲区域】【2022 Q4 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Python算法源码六、效果展示1、输入2、输出3、说明 一、题目描述 给定一个 m x n 的矩阵,由若干字符 ‘X’ 和 ‘O’构成,’X’表示该处已被占据,’O’表示该处空闲,请…

[pyqt5]动态加载ui文件并给菜单的一个子菜单添加触发事件

场景:大家都知道如果直接将ui文件转成py文件后,如果产品经理要你加一些界面控件,你就得改转换后代码这样很麻烦,我们可以直接加载ui文件,然后编写触发事件,因此写了一个简单案例,证明切实可行&a…

微服务:Springboot集成Hystrix实现熔断、降级、隔离

文章目录 前言知识积累Springboot集成Hystrix1、maven依赖引入2、application开启feign的hystrix支持(客户端配置限流降级熔断)3、入口类增加EnableFeignClients EnableHystrix 开启feign与hystrix4、feign调用增加降级方法服务端配置限流降级熔断(选择使…

stm32 使用keil无实物(软件)仿真,虚拟串口通讯

准备 1.keil 2.vspd虚拟串口 3.sscom串口助手 4.CubeMX //哪里报错no ‘read‘ permission,把哪里map一下 map 0x40000000, 0x400077FF read write // APB1 map 0x40010000, 0x40014BFF read write // APB2 map 0x40020000, 0x4007FFFF read write …

​​国风写实虚拟人频“营业”,塑造国潮文化元宇宙入口

近几年,随着时代话语权逐渐递交给Z世代的年轻人,文化自信成为了主流审美,国风虚拟人激发了年轻人心中的民族文化自豪感。 国风虚拟人谷小雨频营业,发布了“中文之美”虚拟人动画,穿越古今四时感受“雨”字流转之美&am…

MMdetection框架速成系列 第04部分:配置文件详细解析+文件结构剖析+Config类核心实现

🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗🚗 MMdetection框架速成系列 MMdetect…

简单回顾一下kafka的学习

简单回顾一下kafka的学习 WhatBrokerControllerPartitionReplicationTopicProducerConsumer Why为什么有多个分区为什么有副本 How搭建集群Java简单使用ProducerConsumeroffset提交方式自动提交 - 默认手动提交 消费者poll消息的过程指定分区消费消息回溯消费指定offset消费新消…

Firefly

Firefly(流萤): 中文对话式大语言模型在本文中,笔者将介绍关于Firefly(流萤)模型的工作,一个中文对话式大语言模型。https://mp.weixin.qq.com/s/TX7wj8IzD_EaMTvk0bjRtA一个支持中文的176B开源基础模型BLOOM:从数据源…

git merge 和git rebase的区别

文章目录 1. 概念2. git merge2.1. 示例 3. git rebase3.1. 示例 4. 总结 1. 概念 在Git版本控制系统中,有两种方式可以将一个分支的更改合并到另一个分支:git merge 和 git rebase。虽然它们都可以完成相同的任务,但它们的实现方式有所不同…

faster-rcnn.pytorch项目环境配置(从0到1)

faster-rcnn.pytorch项目环境配置(从0到1) 其实pytorch版本和CUDA版本高,都没有关系!!!都可以适配,显卡30系、20系都没关系,都可以用! 下面我将在AutoDL平台上&#xf…

Mapbox 实现热力图教程

热力图在 maobox 中属于专题图的一种,他通过点的颜色和权重 来渲染点和点周围的指标情况。本文来跟大家分享一下如何使用 maobox 实现热力图的功能。 我们以全国十大名茶产区的温度指标为例,来做一个像上图这样的效果, 首先要有相关的点数据: var tentea = {type: &qu…

某制药CDMO头部企业IPD变革项目启动会顺利召开

近日,某制药CDMO头部企业IPD流程变革项目在重庆顺利召开。为进一步优化公司研发管理体系、梳理正向研发理念及文化、培养专业人才,经过深入调研后,某制药CDMO头部企业聘请科济管线首席顾问江新安教授及其团队,为该企业作IPD项目变…