Matlab制作Tensorflow数据集:将数据写入XML文件

XML文件

关于这个文件格式,其实我接触并不多。
具体介绍见XML文件结构和基本语法
类似的有YAML。

为什么要写XML文件

最近头疼依然是在做数据集标记,因为原始LableImage工具生成的是XML文件,因为装不上这个工具,所以用Matlab标记了,需要将数据写进XML,和那个工具生成一样的格式。
从同事那里拿来工具生成的标准XML文件,开始有点懵。
标准文件是这个样子:
在这里插入图片描述

  • 椭圆画出部分是当前图片的基本信息,宽、高、深度、路径等;
  • 方框画出的部分为每个被标记目标的位置信息、类别等。

LableImage最显著特点是一张图片可以标记多个目标,所以可以看到有很多的目标信息。
这个解脱了每次裁剪数据集的烦恼,同时有可能算法中将背景作为负模板训练,效果更佳。

自写XML

随便找了个教程,把图片基本信息写进去,照猫画虎,然后,原始XML文件长这个样子:

在这里插入图片描述

对比和标准格式的差别,发现自己的数据没有那么层层被包含,当然,也没有写全。
观察发现:宽高等信息,在size中包围,看起来像是它的子集;而size,又是object的子集。
于是,找了另一个例程,看如何生成这种分叉,一直衍生子集。
思索之后,代码就出来了,长得和标准文件基本一样,就不用贴图了,直接上代码:

%标记文件,数据生成XML
numofpic=length(positiveInstances);

class=0;

for i=1:numofpic
   
    rectPosition=positiveInstances(i).objectBoundingBoxes;
   
    siz=size(rectPosition,1);
    
    path=positiveInstances(i).imageFilename; 
    
    fullpath = 'label';
    
    % create document
    docNode = com.mathworks.xml.XMLUtils.createDocument('annotation');

    % document element 
    docRootNode = docNode.getDocumentElement();
    
    img=imread(path);
     
    depth=numel(size(img));
    
    width_pic=size(img,2);
      
    height_pic=size(img,1);
    
    %folder
    folderNode=docNode.createElement('folder');
    folderNode.appendChild(docNode.createTextNode('train'));
    docRootNode.appendChild(folderNode);
    
        
    % filename
    fileNode = docNode.createElement('filename');
    fileNode.appendChild(docNode.createTextNode(path));
    docRootNode.appendChild(fileNode);
    
     % pathname
    fileNode = docNode.createElement('path');
    fileNode.appendChild(docNode.createTextNode(path));
    docRootNode.appendChild(fileNode);
 
    sourceNode= docNode.createElement('source');
    docRootNode.appendChild(sourceNode);
    
    databaseNode=docNode.createElement('database');
    %data_out='UnKnown';
    databaseNode.appendChild(docNode.createTextNode('UnKnown'));
    sourceNode.appendChild(databaseNode);
    
    %size
    %size是root生成的分叉,见第二句话,给root节点添加一个子节点
    sizeNode=docNode.createElement('size');
    docRootNode.appendChild(sizeNode);
    
    %宽高是size的分叉,所以给sizeNode添加子节点
    % size-width
    widthNode = docNode.createElement('width');
    %由于添加进去是字符一类,所以数字进行类型转换
    width_out=num2str(width_pic);
    widthNode.appendChild(docNode.createTextNode(width_out));
    sizeNode.appendChild(widthNode);

    % size-height
    heightNode = docNode.createElement('height');
    height_out=num2str(height_pic);
    heightNode.appendChild(docNode.createTextNode(height_out));
    sizeNode.appendChild(heightNode);
    
     % size-depth
    depthNode = docNode.createElement('depth');
    depth_out=num2str(depth);
    %子节点中写入数据
    depthNode.appendChild(docNode.createTextNode(depth_out));
    %将子节点写入被分叉节点
    sizeNode.appendChild(depthNode);
    
    %由于每张图多个位置标记,所以文件基本信息写在之前,每个类别遍历写入
    for j=1: siz  
        
        x0=rectPosition(j,1);
    
        y0=rectPosition(j,2);
    
        width=rectPosition(j,3);
    
        height=rectPosition(j,4);
        
        x1=x0+width;
        
        y1=y0+height;         
       
        objectNode=docNode.createElement('object');
        docRootNode.appendChild(objectNode);
        
         % class
        classNode = docNode.createElement('name');
        class_out=num2str(class);
        classNode.appendChild(docNode.createTextNode(class_out));
        objectNode.appendChild(classNode);  
        
        %pose
        poseNode=docNode.createElement('pose');
        poseNode.appendChild(docNode.createTextNode('Unspecified'));  
        objectNode.appendChild(poseNode);  
        
        %truncated
        trunNode=docNode.createElement('truncated');
        trun_out=num2str('0');
        trunNode.appendChild(docNode.createTextNode(trun_out));  
        objectNode.appendChild(trunNode);  
        
        %difficult  
        diffNode=docNode.createElement('difficult');
        diff_out=num2str('0');
        diffNode.appendChild(docNode.createTextNode(diff_out));  
        objectNode.appendChild(diffNode);  
        
        %bndbox       
        boundNode=docNode.createElement('bndbox');
        objectNode.appendChild(boundNode);
        
        % bndbox-xmin  
        xminNode = docNode.createElement('xmin');
        xmin_out=num2str(x0);
        xminNode.appendChild(docNode.createTextNode(xmin_out));
        boundNode.appendChild(xminNode);
        
         % bndbox-ymin
        yminNode = docNode.createElement('ymin');
        ymin_out=num2str(y0);
        yminNode.appendChild(docNode.createTextNode(ymin_out));
        boundNode.appendChild(yminNode);
        
         % bndbox-xmax
        xmaxNode = docNode.createElement('xmax');
        xmax_out=num2str(x1);
        xmaxNode.appendChild(docNode.createTextNode(xmax_out));
        boundNode.appendChild(xmaxNode);
          
        % bndbox-ymax
        ymaxNode = docNode.createElement('ymax');
        ymax_out=num2str(y1);
        ymaxNode.appendChild(docNode.createTextNode(ymax_out));
        boundNode.appendChild(ymaxNode);
        
        %segmented
        segNode=docNode.createElement('segmented');
        seg_out=num2str('0');
        segNode.appendChild(docNode.createTextNode(seg_out));     
        docRootNode.appendChild(segNode);
        
        % xmlwrite
        xmlFileName = [path,'.xml'];
        xmlwrite(xmlFileName,docNode);   
    end    
end

进行这样的操作后,每张图片生成一个标记文件:

在这里插入图片描述

节点关系

这个文件自己在写的时候,数据量不大,关系也不是太复杂,不过还是觉得,下次再写类似关系时候,一定注意生成关系:即谁是谁的子节点
所以,建议再写XML文件时,提前搭建一个节点关系,刚才写的文件,自己写了个框架关系,就很了然了。

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值