C#本地将labelme数据集转换为机器视觉yolo数据集格式

news2025/3/19 5:34:24

C#本地,将labelme数据集转换为机器视觉yolo数据集格式

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.RegularExpressions;
using System.Text.Unicode;
using System.Threading.Tasks;
using System.Windows.Ink;
using System.Windows.Media.Media3D;

namespace WpfAppYolo11_test1
{
    /// <summary>
    /// 将labelme数据集转换为yolo数据集格式
    /// </summary>
    public class LabelmeToYoloDataSetUtils
    {
        Dictionary<string, short> labels = new Dictionary<string, short>();


        /// <summary>
        /// 转换后保存目录
        /// </summary>
        const string outDir = "D:\\yoloTrainDataSet";
        const int saveLength = 10;

        /// <summary>
        /// labelme转yolo格式数据,要转换的目录
        /// </summary>
        /// <param name="inputDir"></param>
        /// 2025-3-4 00:45:38,
        public void FileConvert(string inputDir)
        {
            //labels.Clear();
            var files = System.IO.Directory.GetFiles(inputDir, "*.json");
            if (files == null || files.Length == 0)
            {
                return;
            }


            //获取目录中文件夹,以数字升序命名最新的训练文件夹
            var folders = Directory.GetDirectories(outDir);
            int lastNum = 1;
            if (folders != null && folders.Length > 0)
            {
                List<DirectoryInfo> dirList = new List<DirectoryInfo>();
                foreach (var item in folders)
                {
                    DirectoryInfo directoryInfo = new DirectoryInfo(item);
                    dirList.Add(directoryInfo);
                }
                var lastDir = dirList.OrderByDescending(g => g.CreationTime).FirstOrDefault();
                //获取文件夹后缀
                var lastNumStr = Regex.Match(lastDir.Name, "\\d*$").Value;
                lastNum = Convert.ToInt32(lastNumStr) + 1;
            }
            //此次训练保存的文件夹
            string newTrainDir = "train" + lastNum;

            //string dirNew = "train" + Guid.NewGuid().ToString("n");
            string dirNew = outDir + "\\" + newTrainDir + "\\train";
            //处理json文件
            foreach (var item in files)
            {
                //处理单个json文件
                SingleFileConvert(item, dirNew);
            }

            //挑选训练图片前两个图片作为验证集
            //创建val文件夹
            string val = Path.Combine(outDir, newTrainDir, "val");                      
           
            var files21 = System.IO.Directory.GetFiles(inputDir, "*.jpg");
            var files22 = System.IO.Directory.GetFiles(inputDir, "*.png");
            var fileContainer = files21.Union(files22).ToList();
            var first1 = fileContainer[0];
            var first2 = fileContainer[1];

            //将训练图片全部复制到train中
            var trainImgNew = Path.Combine(dirNew, "images");
            if (!Directory.Exists(trainImgNew))
            {
                Directory.CreateDirectory(trainImgNew);
            }
            foreach (var itemImg in fileContainer)
            {
                string fileNew2  = Path.Combine(trainImgNew, Path.GetFileName(itemImg));
                File.Copy(itemImg, fileNew2);
            }
            //只有2个样本时,将训练的文件夹作为验证
            if (files.Length <= 2)
            {
                val = dirNew;
                goto Val_done;
            }
            if (!Directory.Exists(val))
            {
                Directory.CreateDirectory(val);
            }
            //图片文件夹
            string valImage = Path.Combine(val, "images");
            if (!Directory.Exists(valImage))
            {
                Directory.CreateDirectory(valImage);
            }
            string file1Name = Path.GetFileName(first1);
            string file2Name = Path.GetFileName(first2);
            string img1 = Path.Combine(valImage, file1Name);
            File.Copy(first1, img1);
            string img2 = Path.Combine(valImage, file2Name);
            File.Copy(first2, img2);

            //坐标数据
            string vallabels = Path.Combine(val, "labels");
            if (!Directory.Exists(vallabels))
            {
                Directory.CreateDirectory(vallabels);
            }
            //找到train目录中的坐标数据
            string vallabels2 = Path.Combine(dirNew, "labels");
            string txt1 = Path.GetFileNameWithoutExtension(file1Name) + ".txt";
            string txt2 = Path.GetFileNameWithoutExtension(file2Name) + ".txt";
            string fileLabel1 = Path.Combine(vallabels2, txt1);
            string fileLabel2 = Path.Combine(vallabels2, txt2);
            if (File.Exists(fileLabel1))
            {
                string fileLabelTxt1 = Path.Combine(vallabels, txt1);
                File.Copy(fileLabel1, fileLabelTxt1);
            }
            if (File.Exists(fileLabel2))
            {
                string fileLabelTxt2 = Path.Combine(vallabels, txt2);
                File.Copy(fileLabel2, fileLabelTxt2);
            }

        Val_done:
            //生成data.yaml
            string dir = dirNew;//Path.Combine(outDir, newTrainDir);
            dir = dir.Replace("\\", "/");
            val = val.Replace("\\", "/");

            StringBuilder sb = new StringBuilder();
            sb.AppendLine("train: " + dir);
            sb.AppendLine("val: " + val);
            sb.AppendLine("test: " + val);
            sb.AppendLine("");
            sb.AppendLine("nc: " + labels.Count);

            //设置编码支持中文
            string labelName = System.Text.Json.JsonSerializer.Serialize(labels.Keys,
                     new System.Text.Json.JsonSerializerOptions()
                     {
                         Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
                     }
                );
            labelName = labelName.Replace("\"", "'");//替换双引号为单引号
            sb.AppendLine("names: " + labelName);

            //保存
            //var arr = inputDir.Split("\\");
            //var lastDir = arr.Last();
            //string newDir = inputDir.TrimEnd(lastDir.ToArray());
            //string filePath = Path.Combine(newDir, "yoloTrainDataSet", "data.yaml");
            string yamlDir = outDir + "\\" + newTrainDir;
            string filePath = Path.Combine(yamlDir, "data.yaml");
            System.IO.File.WriteAllText(filePath, sb.ToString());


        }

        /// <summary>
        /// 单个json文件转换
        /// </summary>
        public void SingleFileConvert(string file, string inputDir)
        {
            string json = System.IO.File.ReadAllText(file);
            var data2 = System.Text.Json.JsonSerializer.Deserialize<LabelMeView>(json);
            if (data2 == null || data2.shapes == null || data2.shapes.Count == 0)
            {
                return;
            }
            StringBuilder stringBuilder = new StringBuilder();

            //读取每个形状
            foreach (var item in data2.shapes)
            {
                //忽略没名称的形状
                if (string.IsNullOrEmpty(item.label))
                {
                    continue;
                }
                labels.TryAdd(item.label, 1);

                double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
                if (item.shape_type == "rectangle")
                {
                    x1 = item.points[0][0];
                    y1 = item.points[0][1];

                    x2 = item.points[1][0];
                    y2 = item.points[1][1];
                }
                else if (item.shape_type == "polygon")
                {
                    x1 = item.points.Select(g => g[0]).Min();
                    y1 = item.points.Select(g => g[1]).Min();

                    x2 = item.points.Select(g => g[0]).Max();
                    y2 = item.points.Select(g => g[1]).Max();
                }
                //中心点
                double x_center = (x1 + x2) / (double)2 / data2.imageWidth;
                double y_center = (y1 + y2) / (double)2 / data2.imageHeight;
                double width = Math.Abs((x2 - x1) / data2.imageWidth);
                double height = Math.Abs((y2 - y1) / data2.imageHeight);
                 
                //获取对象id
                int classId = labels.Keys.ToList().IndexOf(item.label);

                stringBuilder.AppendLine($"{classId} {x_center} {y_center} {width} {height}");
            }
            //保存txt文件
            //var arr = inputDir.Split("\\");
            //var lastDir = arr.Last();
            //string newDir = inputDir.TrimEnd(lastDir.ToArray());
            // string dir = System.IO.Path.Combine( outDir, "labels");
            string dir = System.IO.Path.Combine(inputDir, "labels");
            if (!System.IO.Directory.Exists(dir))
            {
                System.IO.Directory.CreateDirectory(dir);
            }
            //string fileName = Path.GetFileName(file) + "_" + Guid.NewGuid().ToString("n") + ".txt";
            string fileName = Path.GetFileNameWithoutExtension(file) + ".txt";
            string filePath = System.IO.Path.Combine(dir, fileName);
            File.WriteAllText(filePath, stringBuilder.ToString());
        }
    }

    public class LabelMeView
    {
        public string version { get; set; }
        public List<ShapeView> shapes { get; set; }
        public string imagePath { get; set; }

        /// <summary>
        /// 图片高度,px
        /// </summary>
        public int imageHeight { get; set; }

        /// <summary>
        /// 图片宽度,px
        /// </summary>
        public int imageWidth { get; set; }
    }

    public class ShapeView
    {
        /// <summary>
        /// 对象说明,标签
        /// </summary>
        public string label { get; set; }

        /// <summary>
        /// 形状描述;rectangle;polygon
        /// </summary>
        public string shape_type { get; set; }
        public object flags { get; set; }

        /// <summary>
        /// 坐标点
        /// </summary>
        public List<double[]> points { get; set; }
        public string version { get; set; }
    }

}

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

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

相关文章

【软件系统架构】单体架构

一、引言 在软件开发的漫长历程中&#xff0c;架构的选择一直是至关重要的决策。单体架构作为一种经典的架构模式&#xff0c;曾经在许多项目中发挥着不可替代的作用。虽然如今微服务等架构逐渐流行&#xff0c;但理解单体架构对于深入掌握软件架构体系仍然有着重要意义。 二、…

【求助】【建议放弃】【谷粒商城版】Kubernetes

本文作者&#xff1a; slience_me 文章目录 Kubernetes【谷粒商城版】【建议放弃】1. docker安装2. kubernetes安装前3. kubeadm,kubelet,kubectl3.1 简介kubeadmkubeletkubectl常用指令 3.2 安装3.3 kubeadm初始化3.4 加入从节点(工作节点)3.5 安装Pod网络插件&#xff08;CNI…

C# Unity 唐老狮 No.10 模拟面试题

本文章不作任何商业用途 仅作学习与交流 安利唐老狮与其他老师合作的网站,内有大量免费资源和优质付费资源,我入门就是看唐老师的课程 打好坚实的基础非常非常重要: Unity课程 - 游习堂 - 唐老狮创立的游戏开发在线学习平台 - Powered By EduSoho C# 1. 内存中&#xff0c;堆和…

第十五届蓝桥杯2024JavaB组省赛试题A:报数游戏

简单的找规律题目。题目给得数列&#xff0c;第奇数项是20的倍数&#xff0c;第偶数项时24的倍数。题目要求第n 202420242024 项是多少。这一项是偶数&#xff0c;所以答案一定是24的倍数&#xff0c;并且偶数项的个数和奇数项的个数各占一半&#xff0c;所以最终的答案ans( n…

Matlab 汽车二自由度转弯模型

1、内容简介 Matlab 187-汽车二自由度转弯模型 可以交流、咨询、答疑 2、内容说明 略 摘 要 本文前一部分提出了侧偏角和横摆角速度作为参数。描述了车辆运动的运动状态&#xff0c;其中文中使用的参考模型是二自由度汽车模型。汽车速度被认为是建立基于H.B.Pacejka的轮胎模…

学c++的人可以几天速通python?

学了俩天啊&#xff0c;文章写纸上了 还是蛮有趣的

Rocky Linux 9.x 基于 kubeadm部署k8s 1.32

一、部署说明 1、主机操作系统说明 序号操作系统及版本备注1Rocky Linux release 9下载链接&#xff1a;https://mirrors.163.com/rocky/9.5/isos/x86_64/Rocky-9.5-x86_64-minimal.iso 2、主机硬件配置说明 作用IP地址操作系统配置关键组件k8s-master01192.168.234.51Rocky…

解决git init 命令不显示.git

首先在自己的项目代码右击 打开git bash here 输入git init 之后自己的项目没有.git文件&#xff0c;有可能是因为.git文件隐藏了&#xff0c;下面是解决办法

利用AI让数据可视化

1. 从问卷星上下载一份答题结果。 序号用户ID提交答卷时间所用时间来源来源详情来自IP总分1、《中华人民共和国电子商务法》正式实施的时间是&#xff08;&#xff09;。2、&#xff08;&#xff09;可以判断企业在行业中所处的地位。3、&#xff08;&#xff09;是指店铺内有…

解决qt中自定插件加载失败,不显示问题。

这个问题断断续续搞了一天多&#xff0c;主要是版本不匹配问题。 我们先来看下 Based on Qt 6.6.0 → 说明 Qt Creator 本身 是基于 Qt 6.6.0 框架构建的。MSVC 2019, 64-bit → 说明 Qt Creator 是使用 Microsoft Visual C 2019 编译器&#xff08;64 位&#xff09; 编译的。…

智慧社区3.0

项目介绍&#xff1a; 此项目旨在推动成都市探索**超大城市社区发展治理新路**&#xff0c;由三个实验室负责三大内容 1、**研发社区阵地空间管理模块**&#xff1a;AI算法实现态势感知&#xff08;如通过社区图片和视频、文本&#xff0c;对环境 空间质量、绿视率、安全感分…

Springboot+Vue登录、注册功能(含验证码)(后端!)

我们首先写一个接口&#xff0c;叫login&#xff01;然后对传入一个user&#xff0c;因为我们前端肯定是要传过来一个user&#xff0c;然后我们后端返回一个user&#xff0c;因为我们要根据这个去校验&#xff01;我们还引入了一个hutool的一个东西&#xff0c;在pom文件里面引…

搞定python之八----操作mysql

本文是《搞定python》系列文章的第八篇&#xff0c;讲述利用python操作mysql数据库。相对来说&#xff0c;本文的综合性比较强&#xff0c;包含了操作数据库、异常处理、元组等内容&#xff0c;需要结合前面的知识点。 1、安装mysql模块 PyMySql模块相当于数据库的驱动&#…

LVGL 中设置 UI 层局部透明,显示下方视频层

LVGL层次 LVGL自上而下分别是layer_sys > layer_top > lv_sreen_active > layer_bottom 即 系统层、顶层、活动屏幕、底层 原理 如果将UI设置为局部透明&#xff0c;显示下方的视频层&#xff0c;不仅仅需要将当前活动屏幕的背景设置为透明&#xff0c;还需要将底层…

21.多态

一、多态概念 多种形态。 静态多态&#xff1a;编译时多态。&#xff08;函数重载&#xff09; 动态多态&#xff1a;运行时多态。&#xff08;继承关系下&#xff0c;调用父类指针或引用&#xff0c;对于不同的对象有不同的行为&#xff09; 二、多态的定义及实现 1&#xff…

【蓝桥杯】第十三届C++B组省赛

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;蓝桥杯 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 试题A&#xff1a;九进制转十进制试题B&#xff1a;顺子日期试题C&#xff1a;刷题统计试题D&#xff1a;修剪灌木试题E&#xf…

C# PaddleOCR字符识别

1 安装Nuget 2 C# using System; using OpenCvSharp; using Sdcb.PaddleOCR; using Sdcb.PaddleOCR.Models.Local; using Sdcb.PaddleOCR.Models; using Sdcb.PaddleInference;namespace ConsoleApp1 {public class MichaelOCR{string imagePath "D:\\BUFFER\\VS\\Text\…

多环境开发-Profiles

在实际的项目开发中&#xff0c;我们通常会涉及多个环境&#xff0c;如开发环境&#xff08;dev&#xff09;、测试环境&#xff08;test&#xff09;和生产环境&#xff08;pro&#xff09;。在不同的环境下&#xff0c;程序的配置信息会有所不同&#xff0c;例如连接的数据库…

《TCP/IP网络编程》学习笔记 | Chapter 18:多线程服务器端的实现

《TCP/IP网络编程》学习笔记 | Chapter 18&#xff1a;多线程服务器端的实现 《TCP/IP网络编程》学习笔记 | Chapter 18&#xff1a;多线程服务器端的实现线程的概念引入线程的背景线程与进程的区别 线程创建与运行pthread_createpthread_join可在临界区内调用的函数工作&#…

MambaVision:一种Mamba-Transformer混合视觉骨干网络

摘要 我们提出了一种新型混合Mamba-Transformer主干网络&#xff0c;称为MambaVision&#xff0c;该网络专为视觉应用而设计。我们的核心贡献包括重新设计Mamba公式&#xff0c;以增强其对视觉特征的高效建模能力。此外&#xff0c;我们还对将视觉Transformer&#xff08;ViT&…