拓冰建站拓冰建站
首页 / 资讯中心 / 正文

CVAT 新标注格式接入指南:从 registry 注册到 TaskData 数据模型的完整实现路径

CVAT 新标注格式接入指南从 registry 注册到 TaskData 数据模型的完整实现路径【免费下载链接】cvatComputer Vision Annotation Tool (CVAT) is a leading platform for building high-quality visual datasets for vision AI. It offers open-source, cloud, and enterprise products, as well as labeling services, for image, video, and 3D annotation with AI-assisted labeling, quality assurance, team collaboration, analytics, and developer APIs.项目地址: https://gitcode.com/GitHub_Trending/cvat/cvat本篇围绕 CVAT 官方文档《How to add a new annotation format support》展开系统讲解如何在cvat/apps/dataset_manager/formats目录中为平台新增一个标注格式从编写导入/导出函数、使用importer/exporter装饰器注册到深入理解TaskData/CommonData数据模型的实际字段定义。读完本文你将能够独立实现一个可导入、可导出的标注格式并理解 CVAT 导出/导入任务背后的真实调用链与 Datumaro 集成方式。一、总体流程三步接入一个新格式官方文档给出的接入步骤非常简洁在cvat/apps/dataset_manager/formats目录下新增一个 Python 脚本实现该格式的导入器importer和导出器exporter在 registry.py 中添加该脚本的 import 语句注册动作就发生在这一步按格式要求实现相应的 importer 和 exporter它们可以是函数也可以是带有__call__方法的类并用 registry.py 提供的importer/exporter装饰器进行装饰。每个格式都由一个 importer 一个 exporter共同支撑。文档给出的最小示例如下importer(nameMyFormat, version1.0, extZIP) def my_importer(file_object, task_data, **options): ... importer(nameMyFormat, version2.0, extXML) class my_importer: def __call__(self, file_object, task_data, **options): ... exporter(nameMyFormat, version1.0, extZIP): def my_exporter(file_object, task_data, **options): ...需要说明的是上面的签名是文档层面的契约示意。从当前仓库源码看注册后格式的实际调用签名已经演化为包含临时工作目录与回调的形式。registry.py 中Importer/Exporter基类定义的__call__签名为class Importer(_Format): def __call__(self, src_file, temp_dir, instance_data, load_data_callbackNone, **options): raise NotImplementedError() class Exporter(_Format): def __call__(self, dst_file, temp_dir, instance_data, **options): raise NotImplementedError()即当前实现中导出器接收dst_file目标文件、temp_dir临时目录用于解压/中间产物、instance_data即TaskData/ProjectData等数据对象以及**options如save_images导入器额外接收load_data_callback用于在解析完成后回填数据并支持大数据集的分块回调。编写新格式时应以仓库中最新格式模块如 yolo.py、mask.py的签名为准。装饰器参数详解装饰器定义了格式的全部可见参数。对照 registry.py 的exporter/importer函数签名def exporter(name, version, ext, display_nameNone, enabledTrue, dimensionDimensionType.DIM_2D): ... def importer(name, version, ext, display_nameNone, enabledTrue, dimensionDimensionType.DIM_2D): ...各参数含义参数说明name格式名称用于内部注册与make_importer/make_exporter查找version格式版本号与name共同构成展示名ext文件扩展名对 importer 可以是逗号分隔的列表表示接受多种文件后缀display_name显式指定展示名。默认由DISPLAY_NAME {NAME} {VERSION}模板生成前端下拉框显示的就是这个值enabled是否启用该格式默认True可用于灰度下线某个格式dimension维度类型默认DimensionType.DIM_2D3D 或音频类格式需显式指定从源码结构看_wrap_format会校验NAME、VERSION、EXT、DISPLAY_NAME均非空并以DISPLAY_NAME作为EXPORT_FORMATS/IMPORT_FORMATS两个全局字典的 key同名同展示名的格式重复注册会直接触发断言失败因此不同版本必须使用不同的 name/version 组合。二、注册机制import 语句为什么就是注册文档要求在 registry.py 中添加 import 语句其原理在 registry.py 文件末尾可以清楚看到——它直接列出了所有内置格式模块的导入# pylint: disableunused-import import cvat.apps.dataset_manager.formats.audio_tsv import cvat.apps.dataset_manager.formats.camvid import cvat.apps.dataset_manager.formats.cityscapes import cvat.apps.dataset_manager.formats.coco ... import cvat.apps.dataset_manager.formats.yolo由于importer/exporter装饰器在模块被 import 时立即执行把包装后的类/函数写入EXPORT_FORMATS/IMPORT_FORMATS因此导入模块即完成注册。运行时task.py 中的export_task与import_task_annotations通过make_exporter(format_name)/make_importer(format_name)按展示名实例化对应格式def export_task(task_id, dst_file, *, format_name, server_urlNone, save_imagesFalse, temp_dirNone): from cvat.apps.dataset_manager.formats.registry import make_exporter task TaskAnnotation(task_id) task.init_from_db(streamingTrue) exporter make_exporter(format_name) with open(dst_file, wb) as f: task.export(f, exporter, hostserver_url, save_imagessave_images, temp_dirtemp_dir)所以新增一个格式的完整落地步骤是新建cvat/apps/dataset_manager/formats/my_format.py实现并装饰 importer/exporter在 registry.py 末尾追加import cvat.apps.dataset_manager.formats.my_format重启后端后新格式即出现在 REST API 的formats列表中可被导入/导出接口选用。从源码结构看若格式导出过程需要 Datumaro 的dm_envEnvironment()实例registry.py 已在模块级创建了共享实例dm_env Environment()新格式模块直接from .registry import dm_env, exporter, importer即可。三、TaskData 数据模型格式模块与平台数据之间的桥梁文档的核心章节介绍了TaskDatabindings.py它提供任务属性以及读写标注的接口。文档列出的公共成员与当前源码中的定义对应关系如下Attributename, value二元组表示形状/标签上的一个属性值LabeledShapetype, frame, label, points, occluded, attributes, group, z_order表示某一帧上的一个独立标注形状非 trackTrackedShapetype, points, occluded, frame, attributes, outside, keyframe, z_order表示 track 中某一帧的关键帧形状Tracklabel, group, shapes由多个TrackedShape组成的轨迹Tagframe, label, attributes, group帧级标签Frameframe, name, width, height, labeled_shapes, tagsgroup_by_frame()产出的逐帧聚合对象track 形状在此会被展平为LabeledShape。对应的方法与属性task_data.shapes/tracks/tags各自的迭代器、task_data.meta任务元信息字典、task_data.group_by_frame()按帧聚合的迭代器、以及导入侧的add_tag(tag)、add_shape(shape)、add_track(track)。对照当前 bindings.py 的实现TaskData继承自CommonData这些结构以NamedTuple定义CommonData.LabeledShape、CommonData.TrackedShape、CommonData.Track、CommonData.Tag并随版本演进扩展了更多字段LabeledShape新增source标注来源如manual或模型名、rotation、elements子元素形状用于 skeleton 等、score、id、outside等TrackedShape新增track_id、rotation、source、elements还新增了面向音频类格式如 audio_tsv.py的LabeledInterval结构以timedelta表示起止时间戳配合add_interval()方法完成音频区间标注的导入。理解这些扩展字段对编写现代格式很重要例如 track 的形状需要keyframe标记关键帧CVAT 在导出时会插值非关键帧3D 格式的points是 6n 长度的[x1,y1,z1,x2,y2,z2,...]。此外bindings.py中定义的CVAT_INTERNAL_ATTRIBUTESoccluded、outside、keyframe、track_id、rotation、source、score是平台内部属性集合导入时这些属性名会走特殊处理逻辑自定义格式不应把它们当作普通用户属性透传。一个值得注意的细节导入入口会统一校正points的类型。CommonData._ensure_points_converted_to_floats的注释明确指出历史上存在未把 points 转成 int/float 的 importer因此新写的 importer 必须返回tuple[int | float] | list[int | float] | LazyList类型的 points否则会被记录错误日志并强制转换。四、导出器实现遍历帧与形状的完整范式文档给出的导出示例代码继承自官方文档此处完整保留... # dump meta info if necessary ... # iterate over all frames for frame_annotation in task_data.group_by_frame(): # get frame info image_name frame_annotation.name image_width frame_annotation.width image_height frame_annotation.height # iterate over all shapes on the frame for shape in frame_annotation.labeled_shapes: label shape.label xtl shape.points[0] ytl shape.points[1] xbr shape.points[2] ybr shape.points[3] # iterate over shape attributes for attr in shape.attributes: attr_name attr.name attr_value attr.value ... # dump annotation code file_object.write(...) ...save_images是 options 中最重要的开关它决定导出的是完整数据集含媒体文件还是仅标注文件。逐帧迭代group_by_frame()是导出 2D 格式的标准范式对于 3D/音频等不适合逐帧迭代的格式则可以直接使用shapes/tracks/tags迭代器或meta字典meta中包含labels、original_size、subset等任务信息TaskData.meta_for_task 展示了 meta 的完整字段构成。真实格式参考一YOLODatumaro 后端模式当前仓库中多数格式已经迁移到基于 Datumaro 的实现。yolo.py 展示了这个模式的标准结构def _export_common(dst_file, temp_dir, instance_data, format_name, *, save_imagesFalse, **kwargs): with GetCVATDataExtractor(instance_data, include_imagessave_images) as extractor: dataset StreamDataset.from_extractors(extractor, envdm_env) dataset.export(temp_dir, format_name, save_mediasave_images, **kwargs) make_zip_archive(temp_dir, dst_file) exporter(nameYOLO, extZIP, version1.1) def _export_yolo(*args, **kwargs): _export_common(*args, format_nameyolo, **kwargs) importer(nameYOLO, extZIP, version1.1) def _import_yolo(*args, **kwargs): _import_common(*args, format_nameyolo, **kwargs)导出侧的关键调用链是GetCVATDataExtractor把TaskData/ProjectData适配成 Datumaro 的 extractor →StreamDataset.from_extractors构造流式数据集 →dataset.export交给 Datumaro 内置的 yolo 格式写出 →make_zip_archive打包为 ZIP 写入dst_file。导入侧_import_common则演示了更完整的流程shutil.unpack_archive解压上传的 ZIP 到temp_dirdetect_dataset做目录结构预校验校验失败能给出更友好的错误提示find_dataset_rootmatch_dm_item把数据集中的图像文件名匹配回任务帧号match_dm_item底层依赖instance_data.match_frame/match_frame_fuzzy支持根路径提示与模糊后缀匹配StreamDataset.import_from解析为 Datumaro 数据集必要时经过SetKeyframeForEveryTrackShape等 transformation 修正load_data_callback分块回填与import_dm_annotations把解析结果写入 CVAT 数据库。真实格式参考二Segmentation masktransformations 用法mask.py 很短但展示了如何用 Datumaro 的 transformation 链在导出前做几何转换exporter(nameSegmentation mask, extZIP, version1.1) def _export(dst_file, temp_dir, instance_data, save_imagesFalse): with GetCVATDataExtractor(instance_data, include_imagessave_images) as extractor: dataset Dataset.from_extractors(extractor, envdm_env) dataset.transform(RotatedBoxesToPolygons) dataset.transform(polygons_to_masks) dataset.transform(boxes_to_masks) dataset.transform(EllipsesToMasks) dataset.transform(merge_instance_segments) dataset.export(temp_dir, voc_segmentation, save_mediasave_images, apply_colormapTrue, label_mapmake_colormap(instance_data)) make_zip_archive(temp_dir, dst_file)其中 transformations.py 提供了平台自研的转换算子如EllipsesToMasks、SetKeyframeForEveryTrackShapeutils.py 提供make_colormap等工具函数。如果你的新格式需要形状→掩码之类的中间转换优先复用这些已有组件。五、导入器实现构造并回填标注文档给出的导入示例代码完整保留... #read file_object ... for parsed_shape in parsed_shapes: shape task_data.LabeledShape( typerectangle, points[0, 0, 100, 100], occludedFalse, attributes[], labelcar, outsideFalse, frame99, ) task_data.add_shape(shape)实现要点结合当前源码补充帧号换算导入器拿到的frame是任务绝对帧号CommonData._import_shape内部会通过rel_frame_id校验并转换为 job 相对帧号超出范围的帧会抛ValueError因此导入前最好先做帧匹配参考 yolo.py 中match_dm_item的用法标签匹配label必须是任务已注册的标签名_get_label_id找不到会抛ValueError(Label ... is not registered)属性匹配只有任务中已定义的属性或开启soft_attribute_import时可软导入的属性才会被保留其余属性在_import_attribute阶段被过滤大数据集分块CommonData内置_MAX_ANNO_SIZE 30000的批量控制add_shape/add_tag/add_track达到阈值时自动序列化并回调create_callback分块落库导入器本身无需关心错误类型导入失败应抛出 Datumaro 的DatasetImportError等标准异常import_task_annotationstask.py会捕获并包装为带格式的CvatImportError返回给 API 调用方。六、格式文档与内置格式清单按仓库规范每个格式还应配套一份格式说明文档放入site/content/en/docs/dataset_management/formats/目录文档中的 Format specifications 章节即链接到这些页面。当前仓库已内置的格式文档包括CVAT 格式Datumaro 格式LabelMe 格式MOT 格式MOTS 格式COCO 格式PASCAL VOC 与 mask 格式YOLO 格式ImageNet 格式CamVid 格式WIDER Face 格式VGGFace2 格式Market-1501 格式ICDAR13/15 格式formats 目录 下实际存在 22 个格式实现模块含 Cityscapes、KITTI、Open Images、LFW、PointCloud、Velodyne、Audio TSV 等可逐个作为实现范本参考。其中 2D 图像/视频格式、3D 点云格式pointcloud.py、velodynepoint.py注意其dimension参数为DIM_3D与音频格式audio_tsv.py分别演示了不同维度类型下TaskData的用法差异。七、小结新格式落地检查清单结合本文内容新增一个标注格式时可按以下清单自检模块位置cvat/apps/dataset_manager/formats/name.pyimporter 与 exporter 成对实现装饰器参数name/version/ext齐全display_name不与其他格式冲突dimension与数据维度一致注册registry.py 末尾添加模块导入语句签名对齐导出器(dst_file, temp_dir, instance_data, **options)、导入器(src_file, temp_dir, instance_data, load_data_callbackNone, **options)save_images控制是否携带媒体数据契约importer 产出的points必须为数值类型label/ 帧号需与任务注册信息匹配错误处理抛出DatasetImportError/DatasetExportError等标准异常保证 API 层错误信息可读配套文档在site/content/en/docs/dataset_management/formats/下新增格式说明页与其他 14 个格式文档保持同一风格。掌握以上路径后无论是接入一个新基准数据集格式如某自研检测基准的标注文件还是为现有格式增加新版本例如 YOLO 系列已有YOLO 1.1与多个Ultralytics YOLO *变体并存的做法都可以在 formats 目录 找到成熟范本并快速落地。【免费下载链接】cvatComputer Vision Annotation Tool (CVAT) is a leading platform for building high-quality visual datasets for vision AI. It offers open-source, cloud, and enterprise products, as well as labeling services, for image, video, and 3D annotation with AI-assisted labeling, quality assurance, team collaboration, analytics, and developer APIs.项目地址: https://gitcode.com/GitHub_Trending/cvat/cvat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门