首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用图像数据将JSON矩形转换为labelMe labelImg多边形

使用图像数据将JSON矩形转换为labelMe labelImg多边形
EN

Stack Overflow用户
提问于 2020-07-24 03:05:45
回答 1查看 2K关注 0票数 4

我已经在labelImg工具中对图像进行了注释,并以可扩展标记语言的形式获得注释。我需要将它转换为imageData编码的LabelMe JSON格式。

示例输入:

示例XML:

代码语言:javascript
复制
<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>

所需的示例输出:

代码语言:javascript
复制
{'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'}]}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-24 03:05:45

这就是我解决这个问题的方法。

步骤1:将XML转换为CSV格式

代码语言:javascript
复制
### 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

调用函数获取转换后的CSV

代码语言:javascript
复制
xml_path='/path/to/sample_annotation.xml'
xml_csv=xml2csv(xml_path)

中间CSV如下所示:

代码语言:javascript
复制
                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

第2步: CSV到LabelMe JSON

代码语言:javascript
复制
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

调用JSON转换器

代码语言:javascript
复制
image_path='path/to/sample_annotation.jpg'
image=cv2.imread(image_path)
csv_json=df2labelme(xml_csv,image_path,image)

最终输出

代码语言:javascript
复制
{'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'}]}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63061428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档