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