Search code examples
xmlannotationsdatasetxmlstarlet

Xml file handling - xmlstarlet attribute division (for image annotation)


I have an XML file (like the following)

<annotation>
<folder>Definitiva</folder>
<filename>armas (1)</filename>
<path>C:\Users\Rob\Desktop\Definitiva\armas (1).jpg</path>
<source>
  <database>Unknown</database>
</source>
<size>
  <width>240</width>
  <height>145</height>
  <depth>3</depth>
</size>
<segmented>0</segmented>
<object>
  <name>pistol</name>
  <pose>Unspecified</pose>
  <truncated>0</truncated>
  <difficult>0</difficult>
  <bndbox>
    <xmin>3</xmin>
    <ymin>1</ymin>
    <xmax>128</xmax>
    <ymax>100</ymax>
  </bndbox>
</object>

and I want to make the bounding box coordinates from relative to absolute. In other words, I need to update the xmin value by diving its current value (=3) with the image's width (=240). I am using xmlstarlet and bash (I have done other, easier, modifications and worked well) but the script I have written produces an error (actually, it totally deletes the xmin attribute). Do you have any idea what's going wrong?

for name in *.xml; do X='/annotation/object/bndbox/xmin' 
Y='/annotation/size/width' Z=$X/$Y xmlstarlet ed --inplace -u 
'/annotation/object/bndbox/xmin' -v "$Z" "$name"; done

Thank you.


Solution

  • xmlstarlet solution:

    xmlstarlet ed -u '/annotation/object/bndbox/xmin' -x '. div /annotation/size/width' input.xml
    

    The output (for demonstration purpose):

    <?xml version="1.0"?>
    <annotation>
      <folder>Definitiva</folder>
      <filename>armas (1)</filename>
      <path>C:\Users\Rob\Desktop\Definitiva\armas (1).jpg</path>
      <source>
        <database>Unknown</database>
      </source>
      <size>
        <width>240</width>
        <height>145</height>
        <depth>3</depth>
      </size>
      <segmented>0</segmented>
      <object>
        <name>pistol</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
          <xmin>0.0125</xmin>
          <ymin>1</ymin>
          <xmax>128</xmax>
          <ymax>100</ymax>
        </bndbox>
      </object>
    </annotation>
    

    • div - Xpath arithmetic division operator (<operand_1> div <operand_2>)