Reputation: 11
I am working on data augmentation. I want to edit an XML file and save it to a new XML file. Here is an example of original XML file:
<object>
<name>car</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>670</xmin>
<ymin>108</ymin>
<xmax>947</xmax>
<ymax>265</ymax>
</bndbox>
</object>
<object>
<name>number_plate</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>808</xmin>
<ymin>210</ymin>
<xmax>865</xmax>
<ymax>232</ymax>
</bndbox>
</object>
Also, I want to change the value of xmin to xmin+100 and xmax to xmax+100. I tried the following code which does not generate any results:
from PIL import Image
import numpy as np
import os
import xml.etree.ElementTree as ET
filename = ("/home/omarubuntu/PFEomar/depassement_stationnemen/conv-video_frame/Annotationflip_xml/")
for image_name in os.listdir(filename):
tree = ET.parse(filename+image_name)
objs = tree.findall('object')
for ix, obj in enumerate(objs):
bbox = obj.find('bndbox')
new_x1 = 1280-int(bbox.find('xmin').text)
nex_y1 = int(bbox.find('ymin').text)
new_x2 = 1280 - int(bbox.find('xmax').text)
new_y2 = int(bbox.find('ymax').text)
tree.write("/home/omarubuntu/PFEomar/depassement_stationnement/conv-video_frame/Annotationflip1_xml/"+image_name)
Upvotes: 1
Views: 691
Reputation: 10314
If you only need to add 100 to xmin/xmax elements, you could use the xslt identity transform pattern and let libxml do the heavy lifting:
from lxml import etree
xsl = etree.XML('''
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<!-- match xmin and xmax elements -->
<xsl:template match="xmin|xmax">
<xsl:copy>
<!-- add 100 to the value of the current node -->
<xsl:value-of select=". + 100" />
</xsl:copy>
</xsl:template>
<!-- recursively copy the rest of the xml document -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
''')
transform = etree.XSLT(xsl)
with open("original.xml") as f:
print(transform(etree.parse(f)), end='')
Testing with diff
:
diff original.xml <(./augmentation.py)
0a1
> <?xml version="1.0"?>
8c9
< <xmin>670</xmin>
---
> <xmin>770</xmin>
10c11
< <xmax>947</xmax>
---
> <xmax>1047</xmax>
20c21
< <xmin>808</xmin>
---
> <xmin>908</xmin>
22c23
< <xmax>865</xmax>
---
> <xmax>965</xmax>
If the stylesheet is stored in a file, augmentation.xsl, you can get the same results using the libxml utility, xsltproc:
diff original.xml <(xsltproc augmentation.xsl original.xml)
Upvotes: 1
Reputation: 142651
You get value from tree
and change it but you are not putting it back to tree
- ie.
xmin = bbox.find('xmin')
xmin.text = str(1280 - int(xmin.text))
And you are not using new name for file to save it.
This is your code with changes but I did't run it
import os
import xml.etree.ElementTree as ET
dirname = "/home/omarubuntu/PFEomar/depassement_stationnemen/conv-video_frame/Annotationflip_xml/"
for image_name in os.listdir(dirname):
fullpath = os.path.join(dirname, image_name)
tree = ET.parse(fullpath)
objs = tree.findall('object')
for ix, obj in enumerate(objs):
bbox = obj.find('bndbox')
xmin = bbox.find('xmin')
xmin.text = str(1280 - int(xmin.text))
xmax = bbox.find('xmax')
xmax.text = str(1280 - int(xmax.text))
new_fullpath = ospath.join(dirname, 'new_'+image_name)
tree.write(new_fullpath)
This is code which I used to test it and it display xml
with new values
import xml.etree.ElementTree as ET
text = '''<root>
<object>
<name>car</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>670</xmin>
<ymin>108</ymin>
<xmax>947</xmax>
<ymax>265</ymax>
</bndbox>
</object>
<object>
<name>number_plate</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>808</xmin>
<ymin>210</ymin>
<xmax>865</xmax>
<ymax>232</ymax>
</bndbox>
</object>
</root>'''
tree = ET.fromstring(text)
objs = tree.findall('object')
for ix, obj in enumerate(objs):
bbox = obj.find('bndbox')
xmin = bbox.find('xmin')
xmin.text = str(1280 - int(xmin.text))
xmax = bbox.find('xmax')
xmax.text = str(1280 - int(xmax.text))
print(ET.tostring(tree).decode())
Upvotes: 2