【halcon深度学习】图像分割数据集格式的转换

前言

目前用于**图像分割的**数据集,我目前接触到的用的比较多的有:
1 PASCAL VOC
2 COCO
3 YOLO
4 Halcon自己的格式(其实就是Halcon字典类型)

当前我涉及到计算机视觉中的数据集格式有,PASCAL VOC、COCO 和 YOLO 用于不同的目标检测和图像分割任务。以下是这三种数据集格式的介绍:

1. PASCAL VOC 格式:

PASCAL VOC(Visual Object Classes)是一个广泛使用的目标检测和图像分割数据集,其标注格式以XML文件的形式提供。以下是一个PASCAL VOC格式的示例(针对单个物体):

<annotation><folder>images</folder><filename>example.jpg</filename><source><database>PASCAL VOC</database></source><size><width>800</width><height>600</height><depth>3</depth></size><object><name>cat</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>200</xmin><ymin>150</ymin><xmax>400</xmax><ymax>450</ymax></bndbox></object>
</annotation>

2. COCO 格式:

COCO(Common Objects in Context)是一个用于目标检测、分割和关键点估计的大规模数据集,其标注格式以JSON文件的形式提供。以下是一个COCO格式的示例(针对单个物体):

{"info": {},"images": [{"id": 1,"file_name": "example.jpg","width": 800,"height": 600,"depth": 3}],"annotations": [{"id": 1,"image_id": 1,"category_id": 1,"bbox": [200, 150, 200, 300],"area": 60000,"iscrowd": 0}],"categories": [{"id": 1,"name": "cat"}]
}

3. YOLO 格式:

YOLO(You Only Look Once)是一个目标检测算法,同时也有其特定的数据集格式。YOLO格式通常需要一个文本文件,其中每行描述了一张图像中的目标。以下是一个YOLO格式的示例(每行表示单个物体):

0 0.45 0.35 0.2 0.5

在此示例中,每行包含了类别索引和目标的归一化坐标信息(中心点坐标和宽高相对于图像尺寸的比例)。

请注意,这些示例仅为了演示目的,实际数据集文件可能包含更多图像和目标的标注信息。不同的数据集格式适用于不同的任务和算法,您在使用特定数据集时需要了解其相应的标注格式。

这几种格式,都是描述图片中的某个框框的位置,以及这个框框对应的类别。

背景

我现在手头有一个PASCAL VOC 格式的数据集,每张图片都有对应好的标记图片,我现在想用halcon去读取整个数据集。但是,halcon是有自己的标注工具的:MVTec Deep Learning Tool
有这个软件标注的图片,导出的数据集格式是:.hdict
那有没有办法,把 PASCAL VOC 直接转为 .hdict 格式呢?

PASCAL VOC 转 .hdict

PASCAL VOC 的格式类型,我们已经看到了,就是个XML解析这个XML不在话下,但是 .hdict这个文件是个二进制的文件,看不到其中的内容。
于是,我搜索全网,发现了一个 PASCAL VOC 转 .hdict 的一个halcon脚本,然后花了一块大洋买了下来,下载下来一看,问题不大,稍微改改果然能用:

*read_dict ('C:/Users/12820/Desktop/数据/分割.hdict', [], [], DictHandle)
* Image Acquisition 01: Code generated by Image Acquisition 01*read_dl_dataset_from_coco
*read_dlcreate_dict (NEWDictHandle1)
class_ids:=[0,1,2,3,4,5]
class_names:=['crazing', 'inclusion', 'patches', 'pitted_surface', 'rolled-in_scale', 'scratches']
image_dir:='images/'set_dict_tuple (NEWDictHandle1, 'class_ids', class_ids)
set_dict_tuple (NEWDictHandle1, 'class_names', class_names)
set_dict_tuple (NEWDictHandle1, 'image_dir', image_dir)list_files ('images/', ['files','follow_links','recursive'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)list_files ('labels/', ['files','follow_links','recursive'], xmladdress)
samples:=[]
for Index := 0 to |ImageFiles| - 1 by 1read_image (Image, ImageFiles[Index])open_file (xmladdress[Index], 'input', FileHandle)IsEof := falsebbox_row1:=[]  bbox_col1:=[]  bbox_row2:=[]  bbox_col2:=[]  bbox_label_id:=[]while (not(IsEof))fread_line (FileHandle, XmlElement, IsEof)if (IsEof)breakendiftuple_split (XmlElement, '<''>', Substrings)create_dict (image)if (Substrings[1]=='folder')floder:= Substrings[2] endif  if (Substrings[1]=='filename')filename:= Substrings[2] endif    *class_names:=['crazing', 'inclusion', 'patches', 'pitted_surface', 'rolled-in_scale', 'scratches']if (Substrings[1]=='name')if (Substrings[2]== class_names[0] )bbox_label_id:=[bbox_label_id,0]elseif (Substrings[2]==class_names[1])bbox_label_id:=[bbox_label_id,1]elseif (Substrings[2]==class_names[2])bbox_label_id:=[bbox_label_id,2]elseif (Substrings[2]==class_names[3])bbox_label_id:=[bbox_label_id,3]elseif (Substrings[2]==class_names[4])bbox_label_id:=[bbox_label_id,4]elseif (Substrings[2]==class_names[5])bbox_label_id:=[bbox_label_id,5]endifendifif (Substrings[1]=='xmin')bbox_col1:= [bbox_col1,Substrings[2]]tuple_number (bbox_col1, bbox_col1)endif  if (Substrings[1]=='ymin')bbox_row1:= [bbox_row1,Substrings[2] ]tuple_number (bbox_row1, bbox_row1)endif  if (Substrings[1]=='xmax')bbox_col2:=[bbox_col2, Substrings[2] ]tuple_number (bbox_col2, bbox_col2)endif  if (Substrings[1]=='ymax')bbox_row2:=[bbox_row2, Substrings[2] ]tuple_number (bbox_row2, bbox_row2)endif  endwhile* gen_rectangle1 (Rectangle,bbox_row1 , bbox_col1,bbox_row2 , bbox_col2)set_dict_tuple (image, 'image_id', Index+1)set_dict_tuple (image, 'image_file_name', floder+'/'+filename)set_dict_tuple (image, 'bbox_label_id', bbox_label_id)set_dict_tuple (image, 'bbox_row1', bbox_row1)set_dict_tuple (image, 'bbox_col1', bbox_col1)set_dict_tuple (image, 'bbox_row2', bbox_row2)set_dict_tuple (image, 'bbox_col2', bbox_col2)samples:=[samples,image]*stop()  
endforset_dict_tuple (NEWDictHandle1, 'samples', samples)write_dict (NEWDictHandle1, '数据test.hdict', [], [])

看到最后一句:write_dict 才意识到,原来所谓的.hdict文件就是halcon里的字典格式啊!
虽然,这个脚本文件可以用,但是1800条数据转换下来,花费了将近半个小时,这能忍?
还有就是PASCAL VOC标注文件有点地方图片名称没带后缀导致,导入后图片无法在
Deep Learning Tool 中显示!所以,搞清楚原理之后,我还是自己写个工具才更省心啊:

HTuple NEWDict;
HOperatorSet.CreateDict(out NEWDict);List<int> class_ids = new List<int> { 0, 1, 2, 3, 4, 5 };List<string> class_names = new List<string> { "crazing", "inclusion", "patches", "pitted_surface", "rolled-in_scale", "scratches" };string image_dir = "F:\\temp\\数据集格式转换测试\\images";//图片字典HTuple hv_image = new HTuple();HTuple hv_samples = new HTuple();HTuple hv_class_ids = new HTuple(class_ids.ToArray());HTuple hv_class_names = new HTuple(class_names.ToArray());HTuple hv_image_dir = new HTuple(image_dir);HOperatorSet.SetDictTuple(NEWDict, "class_ids", hv_class_ids);HOperatorSet.SetDictTuple(NEWDict, "class_names", hv_class_names);HOperatorSet.SetDictTuple(NEWDict, "image_dir", hv_image_dir);string[] imageFiles = Directory.GetFiles(image_dir, "*.*", SearchOption.AllDirectories);List<Dictionary<string, object>> samples = new List<Dictionary<string, object>>();int index = 0;string extension = "";foreach (string imagePath in imageFiles){HOperatorSet.CreateDict(out hv_image);string xmlPath = "D:/DATASET/yolo/NEU-DET/ANNOTATIONS/" + Path.GetFileNameWithoutExtension(imagePath) + ".xml";XDocument xdoc;using (StreamReader reader = new StreamReader(xmlPath)){string xmlContent = reader.ReadToEnd();xdoc = XDocument.Parse(xmlContent);// 现在可以使用xdoc进行XML解析操作}XElement xroot = xdoc.Root;//根节点List<int> bbox_label_ids = new List<int>();List<int> bbox_col1 = new List<int>();List<int> bbox_row1 = new List<int>();List<int> bbox_col2 = new List<int>();List<int> bbox_row2 = new List<int>();//----foldervar folder = xroot.Element("folder").Value;//----filenamevar filename = xroot.Element("filename").Value;if(Path.GetExtension(filename) != ""){extension = Path.GetExtension(filename);}else{if (extension != ""){filename += extension;}}//----获取object节点(一个xml中可能会有多个)var objectNodes = xroot.Descendants("object");foreach (var objectNode in objectNodes){//bndbox节点,包含xmin,ymin,xmax,ymaxXElement bndboxNode = objectNode.Element("bndbox");XElement xminNode = bndboxNode.Element("xmin");XElement yminNode = bndboxNode.Element("ymin");XElement xmaxNode = bndboxNode.Element("xmax");XElement ymaxNode = bndboxNode.Element("ymax");// 解析坐标值并添加到相应列表bbox_col1.Add(int.Parse(xminNode.Value));bbox_row1.Add(int.Parse(yminNode.Value));bbox_col2.Add(int.Parse(xmaxNode.Value));bbox_row2.Add(int.Parse(ymaxNode.Value));// 获取类别名称对应的编号,并添加到相应列表string className = objectNode.Element("name").Value;int id = class_names.IndexOf(className);bbox_label_ids.Add(id);                                }HOperatorSet.SetDictTuple(hv_image, "image_id", index + 1);HOperatorSet.SetDictTuple(hv_image, "image_file_name", (folder + "/") + filename);HOperatorSet.SetDictTuple(hv_image, "bbox_label_id", bbox_label_ids.ToArray());HOperatorSet.SetDictTuple(hv_image, "bbox_row1", bbox_row1.ToArray());HOperatorSet.SetDictTuple(hv_image, "bbox_col1", bbox_col1.ToArray());HOperatorSet.SetDictTuple(hv_image, "bbox_row2", bbox_row2.ToArray());HOperatorSet.SetDictTuple(hv_image, "bbox_col2", bbox_col2.ToArray());// hv_image添加到samplesusing (HDevDisposeHelper dh = new HDevDisposeHelper()){                HTuple ExpTmpLocalVar_samples = hv_samples.TupleConcat(hv_image);hv_samples.Dispose();hv_samples = ExpTmpLocalVar_samples;                    }index++;}HOperatorSet.SetDictTuple(NEWDict, "samples", hv_samples);HOperatorSet.WriteDict(NEWDict, "数据Csharp.hdict", new HTuple(), new HTuple());MessageBox.Show("转换完成");

这次使用XDocument方式解析,弹指间,转换就完成了!再次用Deep Learning Tool打开转换好的Csharp.hdict,这次就成功了
在这里插入图片描述

读取.hdict 格式的数据集

有了.hdict 这个格式的数据集,怎么用呢?

*读取数据集!!!这个就是深度学习工具标记的字典
read_dict (“xxxxx.hdict”, [], [], DLDataset)
应为它就是一个字典,所以直接使用read_dict就能读取数据集了!

还有,halcon除了自家的数据集之外,其实可以直接读取coco数据集:
read_dl_dataset_from_coco (FileExists, [], [], DLDataset1)
是不是很方便!

具体如何训练数据这些内容,后续持续输出,我们下一篇文件见!

附录

附送一个PASCAL VOC 转 YOLO的 python脚本!

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
import globclasses = ["crazing", "inclusion", "patches", "pitted_surface", "rolled-in_scale", "scratches"]def convert(size, box):dw = 1./size[0]dh = 1./size[1]x = (box[0] + box[1])/2.0y = (box[2] + box[3])/2.0w = box[1] - box[0]h = box[3] - box[2]x = x*dww = w*dwy = y*dhh = h*dhreturn (x,y,w,h)def convert_annotation(image_name):in_file = open('./ANNOTATIONS/'+image_name[:-3]+'xml')out_file = open('./LABELS/'+image_name[:-3]+'txt','w')tree=ET.parse(in_file)root = tree.getroot()size = root.find('size')w = int(size.find('width').text)h = int(size.find('height').text)for obj in root.iter('object'):cls = obj.find('name').textif cls not in classes:print(cls)continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))bb = convert((w,h), b)out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')wd = getcwd()if __name__ == '__main__':for image_path in glob.glob("./IMAGES/*.jpg"):image_name = image_path.split('\\')[-1]#print(image_path)convert_annotation(image_name)

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

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

相关文章

软件设计师学习笔记3-CPU组成

目录 1.计算机结构 1.1计算机的外设与主机 1.2计算机各部分之间的联系(了解一下即可) 2.CPU结构 1.计算机结构 1.1计算机的外设与主机 1.2计算机各部分之间的联系(了解一下即可) 该图片来自希赛软考 注&#xff1a;黄色的是传递数据的数据总线&#xff0c;白色的是传递控…

表和Json的相互操作

目录 一、表转Json 1.使用 for json path 2.如何返回单个Json 3.如何给返回的Json增加一个根节点呢 4.如何给返回的Json增加上一个节点 二、对Json基本操作 1.判断给的字符串是否是Json格式 2.从 JSON 字符串中提取标量值 3. 从 JSON 字符串中提取对象或数组 4. 更…

【Linux】进程概念,轻松入门【下篇】

目录 1. 基本概念 2. 常见环境变量 常见环境变量指令 &#xff08;1. PATH &#xff08;2. HOME &#xff08;3. SHELL 3.环境变量的组织形式 &#xff08;1&#xff09;通过代码如何获取环境变量 &#xff08;2&#xff09;普通变量与环境变量的区别 &#xff08;3&…

206.Flink(一):flink概述,flink集群搭建,flink中执行任务,单节点、yarn运行模式,三种部署模式的具体实现

一、Flink概述 1.基本描述 Flink官网地址:Apache Flink — Stateful Computations over Data Streams | Apache Flink Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。 2.有界流和无界流 无界流(流): 有定义流的开始,没有定义结束。会无休止…

[当前就业]2023年8月25日-计算机视觉就业现状分析

计算机视觉就业现状分析 前言&#xff1a;超越YOLO&#xff1a;计算机视觉市场蓬勃发展 如今&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;新版本的发布周期很快&#xff0c;每次迭代的性能都优于其前身。每 3 到 4 个月就会推出一个升级版 YOLO 变体&#xf…

数据通信——RIP协议

一&#xff0c;实验背景 你们公司又订购了一批设备&#xff0c;你以为还要为新员工设计静态路由&#xff0c;结果领导说&#xff0c;不是有动态路由吗&#xff1f;用动态路由&#xff0c;就用什么R的那个。“垃圾RIP&#xff0c;用RIP还不如静态&#xff0c;RIP缺点太多&#x…

25-非父子通信 - event bus 事件总线

作用:非父子组件之间&#xff0c;进行简易消息传递。(复杂场景 -> Vuex) 1.创建一个都能访问到的事件总线(空 Vue 实例) -> utils/EventBus.js import Vue from vue const Bus new Vue() export default Bus 2. A组件(接收方),监听 Bus实例 的事件(支持多个组件同时监…

SSL核心概念 SSL类型级别

SSL&#xff1a;SSL&#xff08;Secure Sockets Layer&#xff09;即安全套接层&#xff0c;及其继任者传输层安全&#xff08;Transport Layer Security&#xff0c;TLS&#xff09;是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。 H…

探索内网穿透工具:实现局域网SQL Server数据库的公网远程访问方法

文章目录 1.前言2.本地安装和设置SQL Server2.1 SQL Server下载2.2 SQL Server本地连接测试2.3 Cpolar内网穿透的下载和安装2.3 Cpolar内网穿透的注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 数据库的重要性相信大家都有所了解&…

下一代存储解决方案:湖仓一体

文章首发地址 湖仓一体是将数据湖和数据仓库相结合的一种数据架构&#xff0c;它可以同时满足大数据存储和传统数据仓库的需求。具体来说&#xff0c;湖仓一体可以实现以下几个方面的功能&#xff1a; 数据集成&#xff1a; 湖仓一体可以集成多个数据源&#xff0c;包括结构…

私有化部署即时通讯平台,30分钟替换钉钉和企业微信

随着企业对即时通讯和协作工具的需求不断增长&#xff0c;私有化部署的即时通讯平台成为企业的首选。WorkPlus作为有10余年行业深耕经验与技术沉淀品牌&#xff0c;以其安全高效的私有化部署即时通讯解决方案&#xff0c;帮助企业在30分钟内替换钉钉和企业微信。本文将深入探讨…

JavaWeb学习-Day10

SpringBootWeb案例 准备工作 开发流程&#xff1a; 开发接口步骤&#xff1a; 删除部门&#xff1a; 新增部门&#xff1a; 简化代码&#xff1a; limit:分页展示&#xff0c;公式&#xff1a;&#xff08;页数-1&#xff09;*页面总数&#xff0c;页面总数 目前出现的问题&am…

STM32 CubeMX (H750)RGB屏幕 LTDC

STM32 CubeMX STM32 RGB888 LTDC STM32 CubeMX一、STM32 CubeMX 设置时钟树LTDC使能设置屏幕参数修改RGB888的GPIO 二、代码部分效果 RGB屏幕线束定义&#xff1a; 一、STM32 CubeMX 设置 时钟树 这里设置的时钟&#xff0c;关于刷新速度 举例子&#xff1a;LCD_CLK24MHz 时…

【大数据知识】大数据平台和数据中台的定义、区别以及联系

数据行业有太多数据名词&#xff0c;例如大数据、大数据平台、数据中台、数据仓库等等。但大家很容易混淆&#xff0c;也很容易产生疑问&#xff0c;今天我们就来简单聊聊大数据平台和数据中台的定义、区别以及联系。 大数据平台和数据中台的定义 大数据平台&#xff1a;一个…

浅谈 Linux 下 vim 的使用

Vim 是从 vi 发展出来的一个文本编辑器&#xff0c;其代码补全、编译及错误跳转等方便编程的功能特别丰富&#xff0c;在程序员中被广泛使用。 Vi 是老式的字处理器&#xff0c;功能虽然已经很齐全了&#xff0c;但还有可以进步的地方。Vim 可以说是程序开发者的一项很好用的工…

代码随想录Day_48打卡

①、打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房…

STM32之17.PWM脉冲宽度调制

一LED0脉冲宽度调制在TIM14_CHI&#xff0c;先将LED&#xff08;PF9&#xff09;代码配置为AF推挽输出模式&#xff0c;将PF9引脚连接到TIM14&#xff0c; #include <stm32f4xx.h>static GPIO_InitTypeDef GPIO_InitStruct;void Led_init(void) {//打开端口F的硬件时钟&a…

Yolo系列-yolov2

YOLO-V2 更快&#xff01;更强&#xff01; YOLO-V2-BatchNormalization BatchNormalization&#xff08;批归一化&#xff09;是一个常用的深度神经网络优化技术&#xff0c;它可以将输入数据进行归一化处理&#xff0c;使得神经网络更容易进行学习。在YOLOv2中&#xff0c;B…

《C和指针》笔记11: external和internal链接属性

当组成一个程序的各个源文件分别被编译之后&#xff0c;所有的目标文件以及那些从一个或多个函数库中引用的函数链接在一起&#xff0c;形成可执行程序。然而&#xff0c;如果相同的标识符出现在几个不同的源文件中时&#xff0c;它们是像Pascal那样表示同一个实体&#xff1f;…

Apache StreamPark系列教程第二篇——项目打包和开发

一、项目打包 项目依赖maven、jdk8.0、前端(node、npm) //下载代码 git clone//maven打包相关内容 mvn -N io.takari:maven:wrapper //前端打包相关内容 curl -sL https://rpm.nodesource.com/setup_16.x | bash - yum -y install nodejs npm -v npm install -g pnpm默认是h2…