BasicAI 标注数据格式规范

AI 的两大基石是算法和数据,BasicAI 作为一个 AI 数据标注平台,存在许多复杂结构的数据,这些数据基本都是半结构化的 JSON。本文讲解了 BasicAI 核心的 Data、Dataset、Classification、Class、Object 等对象的数据结构,以便第三方系统对接 BasicAI 平台,或者业内同行参考。

BasicAI 标注数据格式规范

通用约定

  1. 时间使用 UTC 时区的 ISO 8601 格式,比如 2012-03-29T10:05:45Z
  2. 需要 UUID 的地方统一使用 V4 版本,比如 6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b
  3. 所有类型常量使用大写+下划线方式,比如 3D_BOX

Classification(类别) 定义

Classification 只有一个属性(Attribute),但属性可以多层嵌套,也就是选项(Option)还可以带属性。

{
    "id": 1,
    "attribute": {
        // ID
        "id": "64a16626-153f-4136-b7b4-572c10db08c3",
        // 名称
        "name": "品牌",
        // 类型
        // RADIO,DROPDOWN,TEXT,MULTI_SELECTION
        "type": "RADIO",
        // 是否必需
        "isRequired": true,
        // 选项
        "options": [
            {
                "id": "92f6b36c-0589-4310-bdc9-5b6918a9a2be",
                "name": "奔驰",
                "attributes": [
                    {
                        "id": "0fcb5add-4d2a-4d15-85e7-a8db966e6178",
                        "name": "型号",
                        "type": "RADIO",
                        "isRequired": false,
                        "options": [
                            {
                                "id": "b21e87ad-e096-44ba-a8aa-5adf7e7f5e10",
                                "name": "C300",
                                "attributes": [
                                    {
                                        "id": "69607032-9b53-4c95-90a8-6e378c19aa08",
                                        "name": "颜色",
                                        "type": "RADIO",
                                        "isRequired": false,
                                        "options": [
                                            {
                                                "id": "beb371c0-5cda-4738-987c-9b9022a4b2d4",
                                                "name": "黑色"
                                            },
                                            {
                                                "id": "d819cf06-ef0c-4e01-b787-8c89cfbf8578",
                                                "name": "白色"
                                            }
                                        ]
                                    }
                                ]
                            },
                            {
                                "id": "6798d905-9532-4ba0-bc1f-81bdb849e165",
                                "name": "GLE450",
                                "attributes": [
                                    {
                                        "id": "37d18428-b2e7-4fa0-93ce-9033497df1ec",
                                        "name": "颜色",
                                        "type": "RADIO",
                                        "isRequired": false,
                                        "options": [
                                            {
                                                "id": "6d007c39-d7cd-461a-9a07-1253718ae9cc",
                                                "name": "黑色"
                                            },
                                            {
                                                "id": "6e6533bf-e194-4294-be0e-941f09a00f9a",
                                                "name": "红色"
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "id": "24ce829b-9b60-4b88-99f7-379b144a3cb3",
                        "name": "级别",
                        "type": "RADIO",
                        "isRequired": false,
                        "options": [
                            {
                                "id": "9dbdbe60-9a95-4f6f-9a4e-6bf84efb8382",
                                "name": "轿车"
                            },
                            {
                                "id": "e4497a0f-5c66-40a3-bce7-d9abc59ebbb3",
                                "name": "SUV"
                            }
                        ]
                    },
                    {
                        "id": "0669d8b1-f175-4f46-a8d2-cea7bf9dc1e2",
                        "name": "动力",
                        "type": "MULTI_SELECTION",
                        "isRequired": false,
                        "options": [
                            {
                                "id": "14c9b60d-b4cb-475d-9cad-6dc8be58d67b",
                                "name": "汽油",
                                "attributes": [
                                    {
                                        "id": "9c0d296f-7141-4fd9-9cbe-c3d96a93d411",
                                        "name": "排量",
                                        "type": "RADIO",
                                        "isRequired": false,
                                        "options": [
                                            {
                                                "id": "bd290f13-5c04-4828-bf2c-2ccfbca31ef3",
                                                "name": "1.0L"
                                            },
                                            {
                                                "id": "4858b7e1-c86c-40a9-96cf-7d1c2aa6ec77",
                                                "name": "1.5L"
                                            },
                                            {
                                                "id": "973100cc-ae0a-4379-995f-a98fcf0c4944",
                                                "name": "2.0L"
                                            }
                                        ]
                                    }
                                ]
                            },
                            {
                                "id": "65f62053-e37a-42cf-98a4-b6e87e8b27a5",
                                "name": "柴油"
                            },
                            {
                                "id": "98b033e7-6c1c-4ade-95d5-684a5e6a26e0",
                                "name": "电池",
                                "attributes": [
                                    {
                                        "id": "8e790d10-9931-43f6-82bb-60619f1a25ea",
                                        "name": "容量",
                                        "type": "RADIO",
                                        "isRequired": false,
                                        "options": [
                                            {
                                                "id": "ea9080e5-ce3b-4df8-a55e-b4f53a1f1213",
                                                "name": "<20kWh"
                                            },
                                            {
                                                "id": "fec71b3d-a7db-4d6c-a68a-d9c66ec49c6e",
                                                "name": "20~50kWh"
                                            },
                                            {
                                                "id": "d995f663-766b-403c-bfef-ee6aa1ae0379",
                                                "name": "50~100kWh"
                                            },
                                            {
                                                "id": "7f90dbcd-f81e-4638-b342-4dad454bf728",
                                                "name": ">=100kWh"
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            },
            {
                "id": "f7192a9a-ecee-4eb3-825c-5007c47c1c86",
                "name": "宝马"
            }
        ]
    }
}

Class(分类) 定义

Class 包含多个属性,暂不支持属性多层嵌套。

{
    // ID
    "id": 1,
    // Name
    "name": "Car",
    // 颜色
    "color": "#7dfaf2",
    // 工具类型
    // BOUNDING_BOX,CUBOID,POLYLINE
    "toolType": "CUBOID",
    // 工具选项
    "toolOptions": {},
    // 属性
    "attributes": [
        {
            "id": "bdc9acdf-4337-42de-8964-a1b5b6820287",
            "name": "品牌",
            "type": "RADIO",
            "isRequired": true,
            "options": [
                {
                    "id": "92f6b36c-0589-4310-bdc9-5b6918a9a2be",
                    "name": "奔驰"
                },
                {
                    "id": "f7192a9a-ecee-4eb3-825c-5007c47c1c86",
                    "name": "宝马"
                }
            ]
        },
        {
            "id": "0fcb5add-4d2a-4d15-85e7-a8db966e6178",
            "name": "型号",
            "type": "RADIO",
            "isRequired": true,
            "options": [
                {
                    "id": "b21e87ad-e096-44ba-a8aa-5adf7e7f5e10",
                    "name": "C300"
                },
                {
                    "id": "6798d905-9532-4ba0-bc1f-81bdb849e165",
                    "name": "GLE450"
                }
            ]
        },
        {
            "id": "24ce829b-9b60-4b88-99f7-379b144a3cb3",
            "name": "级别",
            "type": "RADIO",
            "isRequired": true,
            "options": [
                {
                    "id": "9dbdbe60-9a95-4f6f-9a4e-6bf84efb8382",
                    "name": "轿车"
                },
                {
                    "id": "e4497a0f-5c66-40a3-bce7-d9abc59ebbb3",
                    "name": "SUV"
                }
            ]
        },
        {
            "id": "0669d8b1-f175-4f46-a8d2-cea7bf9dc1e2",
            "name": "动力",
            "type": "MULTI_SELECTION",
            "isRequired": true,
            "options": [
                {
                    "id": "14c9b60d-b4cb-475d-9cad-6dc8be58d67b",
                    "name": "汽油"
                },
                {
                    "id": "65f62053-e37a-42cf-98a4-b6e87e8b27a5",
                    "name": "柴油"
                },
                {
                    "id": "98b033e7-6c1c-4ade-95d5-684a5e6a26e0",
                    "name": "电池"
                }
            ]
        }
    ]
}

Data 信息格式

由于单个数据集下的数据量可能会非常大,所以无法直接导出数据文件,只能导出数据信息,里面包含数据的下载地址。

{
    // 格式版本
    "version": "1.0",
    // 数据 ID ,导入时无用
    "dataId": 1,
    // 类型
    // LIDAR_BASIC 纯点云数据,LIDAR_FUSION 点云融合数据,IMAGE 图片数据
    "type": "LIDAR_FUSION",
    // 名称
    "name": "08",
    
    // 以下为纯点云数据特有
    // 点云文件下载地址
    "pointCloudUrl": "https://basicai-prod-app-dataset.s3.us-west-2.amazonaws.com/1657877637263-90050/point_cloud/08.pcd"
    // 点云文件压缩包内路径,压缩包上传才有,导入时无用
    "pointCloudZipPath": "2022-11-11/point_cloud/08.pcd",
    
    // 以下为点云融合数据特有
    // 相机参数文件下载地址
    "cameraConfigUrl": "https://basicai-prod-app-dataset.s3.us-west-2.amazonaws.com/1657877637263-90050/camera_config/08.json",
    // 相机参数文件压缩包内路径,压缩包上传才有,导入时无用
    "cameraConfigZipPath": "2022-11-11/camera_config/08.json",
    // 相机图片信息,按相机编号排序
    "cameraImages": [
        {
            // 相机图片下载地址
            "url": "https://basicai-prod-app-dataset.s3.us-west-2.amazonaws.com/1657877637263-90050/image0/08.jpg",
            // 相机图片压缩包内路径,压缩包上传才有,导入时无用
            "zipPath": "2022-11-11/image0/08.jpg",
            "width": 1920,
            "height": 1080
        }
    ],
    // 点云文件下载地址
    "pointCloudUrl": "https://basicai-prod-app-dataset.s3.us-west-2.amazonaws.com/1657877637263-90050/point_cloud/08.pcd"
    // 点云文件压缩包内路径,压缩包上传才有,导入时无用
    "pointCloudZipPath": "2022-11-11/point_cloud/08.pcd",
    
    // 以下为图片数据特有    
    // 图片文件下载地址
    "imageUrl": "https://basicai-prod-app-dataset.s3.us-west-2.amazonaws.com/1657877637263-90050/point_cloud/08.pcd"
    // 图片文件压缩包内路径,压缩包上传才有,导入时无用
    "imageZipPath": "2022-11-11/point_cloud/08.pcd",
    "imageWidth": 1920,
    "imageHeight": 1080
}

Data 标注结果格式

由于标注结果以 Data 为粒度存储,因此 Data 标注结果格式需要同时支持内部存储和导入/导出两种场景。一个 Data 可能会通过多个来源标注,需要按来源区分标注结果。

  1. Object 表示框,每个框都归属到某个 Tracking Object,注意单帧里一个 Tracking Object 也可能包含多个框(比如点云 2/3D 融合标注),Object ID 为 UUID;
  2. 导入/导出基于内部存储格式,但去掉了仅内部使用的信息,比如 meta
  3. 有些信息在导入时无用,但内部存储又需要,会在导入时自动补上,比如 Object idversioncreatedBycreatedAt 等,反之,有些冗余信息内部存储里没有,但导出时需要加上;
  4. 点云分割需要将其中的点信息存放到单独的文件中,并在 JSON 里记录文件 URL,以避免 JSON 过大,导入/导出时如果是按 Data 划分文件可以直接将点信息放在文件中;
{
    // 格式版本
    "version": "1.0",
    // 数据 ID ,导入时无用
    "dataId": 1,
    // 结果来源 ID,导入时无用
    "sourceId": 1,
    // 结果来源类型,导入时只能为 EXTERNAL 相关类型
    // DATA_FLOW 数据流,TASK 工作流,MODEL 模型识别,EXTERNAL_GROUND_TRUTH 外部人工,EXTERNAL_MODEL 外部模型识别
    "sourceType": "TASK",
    // 结果来源名称
    "sourceName": "20221009000000",
   
    // 有效性,暂不支持导入
    "validity": "VALID",
    
    // 类别属性值,导入时如果提供,需同时在外层提供相关类别信息来新建,暂不支持导入
    "classificationValues": [
        {
            // 类别 ID
            "id": 1,
            // 类别取值,每层属性及其取值形成一个节点,节点之间通过 pid(属性 ID) 和 pvalue(属性值) 建立父子关系
            "values": [
                {
                    // 属性 ID
                    "id": "64a16626-153f-4136-b7b4-572c10db08c3",
                    // 父属性 ID,为 null 的是根节点
                    "pid": null,
                    // 仅用于父属性值为多选时,用来表示关联到哪个值
                    "pvalue": null,
                    "name": "品牌",
                    "type": "RADIO",
                    "value": "奔驰",
                    "alias": "牌子",
                    // 是否为叶子节点,注意定义里有可能为非叶子节点
                    "isLeaf": false
                },
                {
                    "id": "0fcb5add-4d2a-4d15-85e7-a8db966e6178",
                    "pid": "64a16626-153f-4136-b7b4-572c10db08c3",
                    "pvalue": null,
                    "name": "型号",
                    "type": "RADIO",
                    "value": "GLE450",
                    "alias": null,
                    "isLeaf": false
                },
                {
                    "id": "69607032-9b53-4c95-90a8-6e378c19aa08",
                    "pid": "0fcb5add-4d2a-4d15-85e7-a8db966e6178",
                    "pvalue": null,
                    "name": "颜色",
                    "type": "RADIO",
                    "value": "黑色",
                    "alias": null,
                    "isLeaf": true
                },
                {
                    "id": "24ce829b-9b60-4b88-99f7-379b144a3cb3",
                    "pid": "64a16626-153f-4136-b7b4-572c10db08c3",
                    "pvalue": null,
                    "name": "级别",
                    "type": "RADIO",
                    "value": "轿车",
                    "alias": null,
                    "isLeaf": true
                },
                {
                    "id": "0669d8b1-f175-4f46-a8d2-cea7bf9dc1e2",
                    "pid": "64a16626-153f-4136-b7b4-572c10db08c3",
                    "pvalue": null,
                    "name": "动力",
                    "type": "MULTI_SELECTION",
                    "value": ["汽油", "电池"],
                    "alias": null,
                    "isLeaf": false
                },
                {
                    "id": "9c0d296f-7141-4fd9-9cbe-c3d96a93d411",
                    "pid": "0669d8b1-f175-4f46-a8d2-cea7bf9dc1e2",
                    "pvalue": "汽油",
                    "name": "排量",
                    "type": "RADIO",
                    "value": "2.0L",
                    "alias": null,
                    "isLeaf": true
                },
                {
                    "id": "8e790d10-9931-43f6-82bb-60619f1a25ea",
                    "pid": "0669d8b1-f175-4f46-a8d2-cea7bf9dc1e2",
                    "pvalue": "电池",
                    "name": "容量",
                    "type": "RADIO",
                    "value": "20~50kWh",
                    "alias": null,
                    "isLeaf": true
                }
            ]
        }
    ],
    
    // 对象(框)列表
    "objects": [
        // 3D 框
        {
            // ID,导入时无用,会自动补上
            "id": "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b",
            // 类型
            // 3D_BOX 3D 框,2D_RECT 2D 框,3D_SEGMENT_POINTS 3D 分割点云
            "type": "3D_BOX",
            // 更新版本,初始为 0,每改一次 +1,导入时无用,会自动补上
            "version": 1,
            // 创建者,导入时无用,会自动补上
            "createdBy": 1,
            // 创建时间,导入时无用,会自动补上
            "createdAt": "2012-03-29T10:05:45Z",
            
            // 追踪对象 ID
            "trackId": "J0lkBP7r",
            // 追踪对象名称
            "trackName": "Car 1",

            // 分类 ID,导入时如果提供,需同时在外层提供相关分类信息来新建
            "classId": 1,
            // 分类名称,存储和导入时无用,导出时自动补上
            "className": "Car",
            // 分类属性值,类似于 Classification,暂不支持多层嵌套
            "classValues": [
                {
                    "id": "bdc9acdf-4337-42de-8964-a1b5b6820287",
                    "pid": null,
                    "pvalue": null,
                    "name": "品牌",
                    "type": "RADIO",
                    "value": "奔驰",
                    "alias": "牌子",
                    "isLeaf": true
                },
                {
                    "id": "0fcb5add-4d2a-4d15-85e7-a8db966e6178",
                    "pid": null,
                    "pvalue": null,
                    "name": "型号",
                    "type": "RADIO",
                    "value": "GLE450",
                    "alias": null,
                    "isLeaf": true
                },
                {
                    "id": "24ce829b-9b60-4b88-99f7-379b144a3cb3",
                    "pid": null,
                    "pvalue": null,
                    "name": "级别",
                    "type": "RADIO",
                    "value": "轿车",
                    "alias": null,
                    "isLeaf": true
                },
                {
                    "id": "0669d8b1-f175-4f46-a8d2-cea7bf9dc1e2",
                    "pid": null,
                    "pvalue": null,
                    "name": "动力",
                    "type": "MULTI_SELECTION",
                    "value": ["汽油", "电池"],
                    "alias": null,
                    "isLeaf": true
                }
            ],
            
            // 模型识别置信度,只有模型识别时才有
            "modelConfidence": 0.83232,
            // 模型识别出来的分类,只有模型识别时才有
            "modelClass": "Person",
            
            // 轮廓信息,依具体框类型而不同
            "contour": {
                "points": [],
                "pointN": 3057,
                "size3D": { "x": 2.2125, "y": 4.993, "z": 1.38 },
                "center3D": { "x": 3.9220652257399284, "y": -6.013346632547687, "z": 0.39 },
                "rotation3D": { "x": 0, "y": 0, "z": -1.6622375116055483 }
            },
                        
            // 元信息,仅用于内部存储,导入/导出时无用
            "meta": {
                // 标注类型
                // 3D_LABEL 3D 标注,2D_LABEL 2D 标注,3D_SEGMENT 3D 分割,2D_SEGMENT 2D 分割
                "annotateType": "3D_LABEL",
                "classType":"",
                // "valid": true,
                // "checked": false,
                // "isProjection": false,
                // "invisibleFlag": false,
                // "resultType": "Dynamic",
                // "attrs": { "color": "#123" },
                // "resultStatus": "True_value",
                // "isStandard": false,
            }
        },
        
        // 2D 框
        {
            "id": "62383691-8077-44c2-ad8a-a6a7f54390c5",
            "type": "2D_BOX",
            "annotateType": "2D_LABEL",
            "version": "1",
            "createdBy": 1,
            "createdAt": "2012-03-29T10:05:45Z",
            
            "trackId": "c0627d18-1aa1-4788-ac88-09e8772ed9bb",
            "trackName": "Car 1",

            "classId": 1,
            "className": "",
            "classValues": {},

            "contour": {
                "points": [
                    { "x": 976.6271156786534, "y": 509.30442784738 },
                    { "x": 976.9704479066531, "y": 518.6737077997769 }
                ],
                "viewIndex": 3
            },
            
            "meta": {}
        },
        
        // 3D 点云分割
        {
            "id": "0d2c92c4-e96d-4672-abc7-a3480f412753",
            "type": "3D_SEGMENT_POINTS",
            "annotateType": "3D_SEGMENT",
            "version": "1",
            "createdBy": 1,
            "createdAt": "2012-03-29T10:05:45Z",
            
            "trackId": "c0627d18-1aa1-4788-ac88-09e8772ed9bb",
            "trackName": "Car 1",

            "classId": 1,
            "className": "",
            "classValues": {},

            "contour": {
                // 点云分割数据量较大,存放到文件中,仅用于内部存储
                "url": "https://basicai-prod-app-annotation.s3.us-west-2.amazonaws.com/tenant-1/dataset-1/data-flow/data-2/segment-points-0d2c92c4-e96d-4672-abc7-a3480f412753.json"
                // 用于导入/导出,由于点信息数据量较大,导出数据集标注结果时建议按 Data 划分 JSON 文件
                "points": []
            },
            
            "meta": {}
        }
    ]
}

Dataset 标注结果格式

Dataset 标注结果通过合并其下所有 Data 的标注结果来得到,不需要单独存储,因此只需支持导入/导出场景。

单个 JSON 文件

所有 Data 的标注结果合并到一个大的 JSON 文件中,适合数据量比较少的场景,比如 Data 数量不超过 1000 个。

  1. 将不同类型的信息独立开,避免互相干扰,降低理解成本,比如分离结果和数据信息使得结果信息可以采用简单的扁平结构,而数据信息可以采用多层结构(连续帧);
  2. JSON 里包含的 Data ID、Class ID 等均为外部 ID,即便是内部 ID,一旦导出就变成了外部 ID,再导入时会生成新的内部 ID,不能覆盖原有的记录。各类对象之间通过外部 ID 进行关联,比如 Object 所属的 Class;
{
    // 格式版本
    "version": "1.0",
    // 数据集 ID,导入时无用
    "datasetId": 1,
    // 数据集名字,导入时无用
    "datasetName": "LiDAR Fusion Trial",
    // 导出时间,导入时无用
    "exportTime": "2022-11-22T06:12:13.447Z",
    
    // 类别信息,具体结构参考 Classification 定义
    "classifications": [],
    
    // 分类信息,具体结构参考 Class 定义
    "classes": [],
    
    // 数据信息,具体结构参考 Data 信息格式
    "data": [],
    
    // 结果信息,具体结构参考 Data 标注结果格式
    "results": []
}

多个 JSON 文件

对于数据量很大的 Dataset,如果采用单个 JSON 文件,文件会非常大,打开时的资源消耗很大,甚至无法打开,特别是点云分割场景数据量就更大了,因此建议按 Data 划分 JSON 文件,然后打包成一个压缩包。

  1. 导入结果时需要同时导入数据,不支持将结果关联到已有数据;
  2. 对于大数据集,只导出数据信息,不导出数据文件,否则压缩包会非常大,需要的话可以依据数据信息里的地址去下载;
  3. 导出时不保留连续帧结构,因为连续帧只在标注时才有用,使用结果时不关心;
  4. 不支持基于数据信息的导入,因为要从网络下载大量文件,耗时很长且容易出错;
  5. 考虑到数据名称可能重复,因此导出时采用名称 + ID 的方式来作为单个 Data 导出文件的名称,导入时可以不管 ID,只要保证本次导入中文件名没有重复即可;

基于数据文件

点云数据集

.
├── camera_config // 相机参数
│   ├── 00-1.json
│   └── 01-2.json
├── image0 // 相机0图片
│   ├── 00-1.jpg
│   └── 01-2.jpg
├── image1 // 相机1图片
│   ├── 00-1.jpg
│   └── 01-2.jpg
├── image2 // 相机2图片
│   ├── 00-1.jpg
│   └── 01-2.jpg
├── point_cloud // 点云
│   ├── 00-1.pcd
│   └── 01-2.pcd
├── scene1 // 连续帧,其下结构参考根目录
├── result // 标注结果,具体结构参考 Data 标注结果格式
     ├── 00-1.json
     └── 01-2.json

图片数据集

.
├── image // 图片
│   ├── 00-1.jpg
│   └── 01-2.jpg
├── scene1 // 连续帧,其下结构参考根目录
└── result // 标注结果,具体结构参考 Data 标注结果格式
     ├── 00-1.json
     └── 01-2.json

基于数据信息

.
├── data // 数据信息,具体结构参考 Data 信息格式
│   ├── 00-1.json
│   └── 01-2.json
└── result // 标注结果,具体结构参考 Data 标注结果格式
     ├── 00-1.json
     └── 01-1.json