欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Matlab 读写*.xml文件

程序员文章站 2022-04-01 08:45:00
...

Matlab 读写*.xml文件

1.摘要

       因为经常使用将图像中的目标标注信息保存在*.xml文件中。在训练深度神经网络是常用这样的训练数据。有时候需要使用原有的数据来扩充数据,而最常用的工具也就是Matlab(这里示例使用的Matlab2016b)。在这篇博文中主要介绍:①Matlab读取*.xml文件信息;②将*.xml文件中的信息显示在对应的图像上,可以简单可视化数据;③将在图像中的目标数据写入*.xml文件中; ④读取*.xml文件相关的函数。将Matlab相关代码附上,希望对大家有所帮助。

如果对你有所帮助,请帮忙打“Call”点赞哈,谢谢啦!!!

%%  
%文件创建:Carlson 2018.04.11
%全部功能:
%       1.读、写xml文件
%       2.读xml文件并显示目标信息
%目的:
%       1.显示检测图像中标注是否正确
%       2.更改或者扩充数据使用
%% 初始化 
%注意修改下面四个值  
clear
xmlfilepath='Annotations'; %标注文件*.xml的位置
ImagefilePath='JPEGImages'; %图像文件*.jpg的位置
NewxmlPath='AnnotationsNew'; %保存新的*.xml文件位置
NewImgPath='JPEGImagesNew'; %保存新的*.jpg文件位置
%% Main 函数
%示例1
[Imageinfo,ImageObject]=Readxmlfile([xmlfilepath,'\','IMG_044.xml']);
%示例2
CheckxmlandImg(xmlfilepath,ImagefilePath)
%示例3
%imageinfo={'IMG_002.jpg',1123,1233,3};
%imageObject={{'object1',11,22,33,44},{'object2',111,122,313,414}};
%Writexmlfile(imageinfo,ImageObject,NewxmlPath);
Writexmlfile(Imageinfo,ImageObject,NewxmlPath);

如下是*.xml文件的内容:

<?xml version="1.0" encoding="utf-8"?>
<annotation>
   <folder>hudie</folder>
   <filename>IMG_044.jpg</filename>
   <path>C:\Carlson\Dataset\IMG_044.jpg</path>
   <source>
      <database>Unknown</database>
   </source>
   <size>
      <width>4288</width>
      <height>2848</height>
      <depth>3</depth>
   </size>
   <segmented>0</segmented>
   <object>
      <name>object1</name>
      <pose>Unspecified</pose>
      <truncated>0</truncated>
      <difficult>0</difficult>
      <bndbox>
         <xmin>1028</xmin>
         <ymin>1790</ymin>
         <xmax>1223</xmax>
         <ymax>1976</ymax>
      </bndbox>
   </object>
   <object>
      <name>Object2</name>
      <pose>Unspecified</pose>
      <truncated>0</truncated>
      <difficult>0</difficult>
      <bndbox>
         <xmin>1440</xmin>
         <ymin>1473</ymin>
         <xmax>1730</xmax>
         <ymax>1697</ymax>
      </bndbox>
   </object>
</annotation>

2.读取xml文件信息

这个函数主要是读取*.xml文件的数据信息。

%% read data from *.xml
function [Imageinfo,ImageObject]=Readxmlfile(xmlfile)
    %这个是读取xml中的信息,分别是图像信息和目标信息.
    %图像信息如:imageinfo={'IMG_002.jpg',1123,1233,3};
    %目标信息如:ImageObject={{'Object1',11,22,33,44},{'Object2',111,122,313,414},ect,...};
    %xml文件名:xmlfi='Annotations\IMG_010.xml'
    Imageinfo={}; ImageObject={};
    tree = xmlread(xmlfile); %读取每一个xml
    theStruct = parseChildNodes(tree); %结构化xml的数据 
    ImageName=theStruct.Children(4).Children.Data; %获得xml对应的图像名字
    OrgImgW=theStruct.Children(10).Children(2).Children.Data;
    OrgImgH=theStruct.Children(10).Children(4).Children.Data;
    OrgImgD=theStruct.Children(10).Children(6).Children.Data;
    [W,M]=size(theStruct.Children);
    Obn=1;ImageAllinfo={};
    for Namei=1:M
        Ob='object';
        ObTemp=theStruct.Children(Namei).Name(1,:);
        if isequal(Ob,ObTemp)
            ObjectName=theStruct.Children(Namei).Children(2).Children.Data; %获得每一个目标的类别
            %获得对应的位置
            xmin=str2double(theStruct.Children(Namei).Children(10).Children(2).Children.Data);
            ymin=str2double(theStruct.Children(Namei).Children(10).Children(4).Children.Data);
            xmax=str2double(theStruct.Children(Namei).Children(10).Children(6).Children.Data);
            ymax=str2double(theStruct.Children(Namei).Children(10).Children(8).Children.Data);
            ImageAllinfo{Obn}={ObjectName,xmin,ymin,xmax,ymax}; %存储在一个Cell矩阵
            Obn=Obn+1;
        end
    end
    Imageinfo{1}=ImageName;Imageinfo{2}=OrgImgW;Imageinfo{3}=OrgImgH;Imageinfo{4}=OrgImgD;
    ImageObject=ImageAllinfo;
end

3.信息写入xml文件

这里这个函数是将图像中的目标信息写入到对应的*.xml文件中。

%% write data to *.xml
function Writexmlfile(Imageinfo,ImageObject,NewxmlPath)
%这个函数是将图像信息和目标信息写入*.xml文件中
%Imageinfo图像信息如:imageinfo={'IMG_002.jpg',1123,1233,3};
%ImageObject目标信息如:ImageObject={{'Object1',11,22,33,44},{'object2',111,122,313,414},{...},...};
%NewxmlPath保存*.xml路径:NewxmlPath='AnnotationsNew';
    %主节点
    docNode = com.mathworks.xml.XMLUtils.createDocument... 
              ('annotation');
    docRootNode = docNode.getDocumentElement;
    %docRootNode.setAttribute('attr_name','attr_value');
    %二级节点:
    %1.基本信息写入
    %Imageinfo={'imageName','width','height','depth'}
    thisElement = docNode.createElement('folder');
    thisElement.appendChild... 
        (docNode.createTextNode('hudie'));
    docRootNode.appendChild(thisElement);    
    thisElement = docNode.createElement('filename');
    thisElement.appendChild... 
        (docNode.createTextNode(Imageinfo{1}));
    docRootNode.appendChild(thisElement);    
    thisElement = docNode.createElement('path');
    thisElement.appendChild... 
        (docNode.createTextNode(['D:\Carlson\Dataset\',Imageinfo{1}]));
    docRootNode.appendChild(thisElement);    
    sourcenode = docNode.createElement('source');
    docRootNode.appendChild(sourcenode);
        databaseElement = docNode.createElement('database');
        databaseElement.appendChild... 
            (docNode.createTextNode('Unknown'));
        sourcenode.appendChild(databaseElement);    
    sizenode = docNode.createElement('size');
    docRootNode.appendChild(sizenode);
        databaseElement = docNode.createElement('width');
        databaseElement.appendChild... 
                (docNode.createTextNode(num2str(Imageinfo{2})));
        sizenode.appendChild(databaseElement);
        databaseElement = docNode.createElement('height');
        databaseElement.appendChild... 
                (docNode.createTextNode(num2str(Imageinfo{3})));
        sizenode.appendChild(databaseElement);
        databaseElement = docNode.createElement('depth');
        databaseElement.appendChild... 
                (docNode.createTextNode(num2str(Imageinfo{4})));
        sizenode.appendChild(databaseElement);        
    segmentedElement = docNode.createElement('segmented');
    segmentedElement.appendChild... 
        (docNode.createTextNode('0'));
    docRootNode.appendChild(segmentedElement);
   
    %2.标注信息写入
    %ImageObject={{'name','xmin','xmin','xmin','xmin'}}
    for n=1:length(ImageObject)
        Objectinfo=ImageObject{n};
        objectnode = docNode.createElement('object');
        docRootNode.appendChild(objectnode);
            NameElement = docNode.createElement('name');
            NameElement.appendChild... 
                    (docNode.createTextNode(Objectinfo{1}));
            objectnode.appendChild(NameElement);      
            poseElement = docNode.createElement('pose');
            poseElement.appendChild... 
                    (docNode.createTextNode('Unspecified'));
            objectnode.appendChild(poseElement);            
            truncatedElement = docNode.createElement('truncated');
            truncatedElement.appendChild... 
                    (docNode.createTextNode('0'));
            objectnode.appendChild(truncatedElement);            
            difficultElement = docNode.createElement('difficult');
            difficultElement.appendChild... 
                    (docNode.createTextNode('0'));
            objectnode.appendChild(difficultElement);            
            bndboxElement = docNode.createElement('bndbox');
            docRootNode.appendChild(bndboxElement);
                    xminElement = docNode.createElement('xmin');
                    xminElement.appendChild... 
                             (docNode.createTextNode(num2str(Objectinfo{2})));
                    bndboxElement.appendChild(xminElement);     
                    yminElement = docNode.createElement('ymin');
                    yminElement.appendChild... 
                             (docNode.createTextNode(num2str(Objectinfo{3})));
                    bndboxElement.appendChild(yminElement);                    
                    xmaxElement = docNode.createElement('xmax');
                    xmaxElement.appendChild... 
                             (docNode.createTextNode(num2str(Objectinfo{4})));
                    bndboxElement.appendChild(xmaxElement);                    
                    ymaxElement = docNode.createElement('ymax');
                    ymaxElement.appendChild... 
                             (docNode.createTextNode(num2str(Objectinfo{5})));
                    bndboxElement.appendChild(ymaxElement);
            objectnode.appendChild(bndboxElement);
    end
    %保存*.xml文件
    xmlFileName = [NewxmlPath,'\',Imageinfo{1}(1:(end-4)),'.xml'];
    xmlwrite(xmlFileName,docNode);
    %显示*.xml文件信息
    type(xmlFileName);
end

4.读取*.xml相关的函数

下面是3个读取*.xml文件用到的相关函数:

%% Recurse over node children.
function children = parseChildNodes(theNode)
    children = [];
    if theNode.hasChildNodes
       childNodes = theNode.getChildNodes;
       numChildNodes = childNodes.getLength;
       allocCell = cell(1, numChildNodes);
       children = struct(             ...
          'Name', allocCell, 'Attributes', allocCell,    ...
          'Data', allocCell, 'Children', allocCell);
        for count = 1:numChildNodes
            theChild = childNodes.item(count-1);
            children(count) = makeStructFromNode(theChild);
        end
    end
end
%% Create structure of node info.
function nodeStruct = makeStructFromNode(theNode)
    nodeStruct = struct(                        ...
       'Name', char(theNode.getNodeName),       ...
       'Attributes', parseAttributes(theNode),  ...
       'Data', '',                              ...
       'Children', parseChildNodes(theNode));
    if any(strcmp(methods(theNode), 'getData'))
       nodeStruct.Data = char(theNode.getData); 
    else
       nodeStruct.Data = '';
    end
end
%% Create attributes structure.
function attributes = parseAttributes(theNode)
    attributes = [];
    if theNode.hasAttributes
       theAttributes = theNode.getAttributes;
       numAttributes = theAttributes.getLength;
       allocCell = cell(1, numAttributes);
       attributes = struct('Name', allocCell, 'Value', ...
                           allocCell);
       for count = 1:numAttributes
          attrib = theAttributes.item(count-1);
          attributes(count).Name = char(attrib.getName);
          attributes(count).Value = char(attrib.getValue);
       end
    end
end

如上若有错误,恳请指正!! !