Sre*_*ran 4 python xml opencv computer-vision pandas
我已经在 labelImg 工具中对图像进行了注释,并以 XML 形式获得了注释。我需要将其转换为 LabelMe JSON 格式,并在其中编码 imageData。
样本输入:
示例 XML:
<annotation>
<folder>blocks</folder>
<filename>sample_annotation.jpg</filename>
<path>/path/sample_annotation.jpg</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>720</width>
<height>540</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>cube</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>90</xmin>
<ymin>87</ymin>
<xmax>196</xmax>
<ymax>194</ymax>
</bndbox>
</object>
<object>
<name>cube</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>498</xmin>
<ymin>188</ymin>
<xmax>607</xmax>
<ymax>296</ymax>
</bndbox>
</object>
</annotation>Run Code Online (Sandbox Code Playgroud)
所需的示例输出:
{'imageData': '/9j/2w.........../9k=',
'imageHeight': 540,
'imagePath': 'sample_annotation.jpg',
'imageWidth': 720,
'shapes': [{'group_id': None,
'label': 'cube',
'points': [[90, 87], [196, 194]],
'shape_type': 'rectangle'},
{'group_id': None,
'label': 'cube',
'points': [[498, 188], [607, 296]],
'shape_type': 'rectangle'}]}
Run Code Online (Sandbox Code Playgroud)
我就是这样解决的。
### xml to csv
import cv2
import os
import pandas as pd
import xml.etree.ElementTree as ET
def xml2csv(xml_path):
"""Convert XML to CSV
Args:
xml_path (str): Location of annotated XML file
Returns:
pd.DataFrame: converted csv file
"""
print("xml to csv {}".format(xml_path))
xml_list = []
xml_df=pd.DataFrame()
try:
tree = ET.parse(xml_path)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
int(root.find('size')[0].text),
int(root.find('size')[1].text),
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
xml_list.append(value)
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xml_df = pd.DataFrame(xml_list, columns=column_name)
except Exception as e:
print('xml conversion failed:{}'.format(e))
return pd.DataFrame(columns=['filename,width,height','class','xmin','ymin','xmax','ymax'])
return xml_df
Run Code Online (Sandbox Code Playgroud)
xml_path='/path/to/sample_annotation.xml'
xml_csv=xml2csv(xml_path)
Run Code Online (Sandbox Code Playgroud)
filename width height class xmin ymin xmax ymax
0 sample_annotation.jpg 720 540 cube 90 87 196 194
1 sample_annotation.jpg 720 540 cube 498 188 607 296
Run Code Online (Sandbox Code Playgroud)
import cv2
import numpy as np
import os
import json
import pandas as pd
import base64
def df2labelme(symbolDict,image_path,image):
""" convert annotation in CSV format to labelme JSON
Args:
symbolDict (dataframe): annotations in dataframe
image_path (str): path to image
image (np.ndarray): image read as numpy array
Returns:
JSON: converted labelme JSON
"""
try:
symbolDict['min']= symbolDict[['xmin','ymin']].values.tolist()
symbolDict['max']= symbolDict[['xmax','ymax']].values.tolist()
symbolDict['points']= symbolDict[['min','max']].values.tolist()
symbolDict['shape_type']='rectangle'
symbolDict['group_id']=None
height,width,_=image.shape
symbolDict['height']=height
symbolDict['width']=width
encoded = base64.b64encode(open(image_path, "rb").read())
symbolDict.loc[:,'imageData'] = encoded
symbolDict.rename(columns = {'class':'label','filename':'imagePath','height':'imageHeight','width':'imageWidth'},inplace=True)
converted_json = (symbolDict.groupby(['imagePath','imageWidth','imageHeight','imageData'], as_index=False)
.apply(lambda x: x[['label','points','shape_type','group_id']].to_dict('r'))
.reset_index()
.rename(columns={0:'shapes'})
.to_json(orient='records'))
converted_json = json.loads(converted_json)[0]
except Exception as e:
converted_json={}
print('error in labelme conversion:{}'.format(e))
return converted_json
Run Code Online (Sandbox Code Playgroud)
image_path='path/to/sample_annotation.jpg'
image=cv2.imread(image_path)
csv_json=df2labelme(xml_csv,image_path,image)
Run Code Online (Sandbox Code Playgroud)
{'imageData': '/9j/2w.........../9k=',
'imageHeight': 540,
'imagePath': 'sample_annotation.jpg',
'imageWidth': 720,
'shapes': [{'group_id': None,
'label': 'cube',
'points': [[90, 87], [196, 194]],
'shape_type': 'rectangle'},
{'group_id': None,
'label': 'cube',
'points': [[498, 188], [607, 296]],
'shape_type': 'rectangle'}]}
Run Code Online (Sandbox Code Playgroud)