공통 어노테이터 스키마
공통 어노테이터 스키마
Section titled “공통 어노테이터 스키마”본 문서는 Datamaker의 모든 어노테이터(이미지, 비디오, 텍스트, 프롬프트, PCD 등)가 공통적으로 따라야 하는 데이터 모델을 정의합니다.
각 어노테이터별 스펙은 이 스키마를 상속하고, 도구별(툴별) 고유 필드를 추가로 확장합니다.
-
classification 구조는 tool(도구)와 무관하며, 관리자(운영자) 페이지에서 직접 정의한 class, attributes, options로 구성됩니다.
-
attributes, options 등 모든 하위 구조 역시 사용자가 직접 정의합니다.
-
실제 어노테이션 데이터의 classification 필드는 트리 구조를 flatten(평탄화)한 key-value 쌍으로 저장됩니다.
-
특정 class가 선택된 경우, 필수 하위 속성(종속성)은 프로젝트별 dm-schema 확장 JSON Schema로 관리됩니다.
전체 구조 개요 (Mermaid)
Section titled “전체 구조 개요 (Mermaid)”flowchart TD
Schema["관리자 정의 분류 스키마 (트리)"]
Data["실제 어노테이션 데이터 (Flatten)"]
Schema -->|Flatten 규칙| Data
Schema -->|종속성 규칙| JSONSchema["dm-schema 확장 JSON Schema"]
Data -->|유효성 검증| JSONSchema
데이터 흐름
Section titled “데이터 흐름”┌─────────────────────────────────────────────────────────────┐│ annotatorData (최상위) │├─────────────────────────────────────────────────────────────┤│ extra → 에셋별 추가 메타데이터 ││ annotations → 어노테이션 메타 정보 (id, tool, 분류 등) ││ annotationsData → 어노테이션 실제 좌표/데이터 ││ relations → 어노테이션 간 관계 ││ annotationGroups → 어노테이션 그룹 정보 ││ assignmentId → 작업 식별자 │└─────────────────────────────────────────────────────────────┘공통 데이터 모델
Section titled “공통 데이터 모델”1. 최상위 구조
Section titled “1. 최상위 구조”모든 어노테이션 작업은 하나의 JSON 객체로 저장되며, 최상위 키는 어노테이터 종류와 관계없이 동일합니다.
| 키 | 타입 | 설명 |
|---|---|---|
extra | Record<string, unknown> | 에셋별 메타데이터 |
relations | Record<string, RelationItem[]> | 어노테이션 간 관계 |
annotations | Record<string, AnnotationBase[]> | 에셋 단위의 어노테이션 목록 |
annotationsData | Record<string, AnnotationDataItem[]> | 어노테이션 실제 좌표/데이터 |
annotationGroups | Record<string, AnnotationGroupItem[]> | 어노테이션 그룹화 |
assignmentId | string | 작업 식별자 |
2. 공통 스키마 구조
Section titled “2. 공통 스키마 구조”2.1 최상위 구조
Section titled “2.1 최상위 구조”type AnnotatorData = { extra: Record<AssetId, unknown> annotations: Record<AssetId, AnnotationBase[]> annotationsData: Record<AssetId, AnnotationDataItem[]> relations: Record<AssetId, RelationItem[]> annotationGroups: Record<AssetId, AnnotationGroupItem[]> assignmentId: number | string}
// AssetId 예시: "image_1", "video_1", "text_1", "pcd"2.2 AnnotationBase (공통 메타 정보)
Section titled “2.2 AnnotationBase (공통 메타 정보)”소스코드 src/app/core/lib/data.js에서 확인된 구조:
type AnnotationBase = { id: string // 10자 랜덤 문자열 (예: "Cd1qfFQFI4") tool: string // 사용된 도구 코드 isLocked: boolean // 편집 잠금 여부 (기본값: false) isVisible: boolean // 화면 표시 여부 (기본값: true) isValid?: boolean // 유효성 여부 (기본값: false) isDrawCompleted?: boolean // 그리기 완료 여부 classification: ClassificationObject | null label?: string[] // 분류 기반 생성된 라벨 배열
// Sequential Data 전용 sequenceIndex?: number // 시퀀스 인덱스 instanceId?: string // 인스턴스 ID (자동 생성)}2.3 RelationItem (관계 객체)
Section titled “2.3 RelationItem (관계 객체)”type RelationItem = { id: string // 소스ID + 타겟ID 조합 (예: "Cd1qfFQFI4AUjPgaMzQa") tool: 'relation' // 항상 "relation" 고정 isLocked: boolean isVisible: boolean isValid?: boolean annotationId: string // 출발(소스) 어노테이션 ID targetAnnotationId: string // 도착(타겟) 어노테이션 ID classification: ClassificationObject | null label?: string[]}2.4 AnnotationGroupItem (그룹 객체)
Section titled “2.4 AnnotationGroupItem (그룹 객체)”type AnnotationGroupItem = { id: string tool: 'annotationGroup' // 항상 "annotationGroup" 고정 isLocked: boolean isValid?: boolean annotationList: GroupMemberItem[] classification: ClassificationObject | null}
type GroupMemberItem = { annotationId: string children: GroupMemberItem[] // 계층 구조 지원}2.5 AnnotationDataBase (공통 데이터 필드)
Section titled “2.5 AnnotationDataBase (공통 데이터 필드)”annotationsData 배열 내 각 항목이 가질 수 있는 공통 필드입니다:
type AnnotationDataBase = { id: string // AnnotationBase.id와 1:1 매칭
// 데이터 압축 (전역 공통 필드) isCompressed?: boolean // 압축 여부 compressionFormat?: CompressionFormat // 압축 포맷}
type CompressionFormat = | 'rle' // Run-Length Encoding (현재 지원)2.6 데이터 압축 공통 규격
Section titled “2.6 데이터 압축 공통 규격”⚠️ 적용 범위: 현재 Image Annotator의
segmentation도구에서 사용 중이며, 향후 모든 어노테이터에서 공통적으로 적용될 예정입니다.
압축 필드 명세
Section titled “압축 필드 명세”| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
isCompressed | boolean | 조건부 | 데이터 압축 여부. true일 경우 compressionFormat 필수 |
compressionFormat | string | 조건부 | 압축 알고리즘 식별자. isCompressed: true일 때 필수 |
압축 포맷 종류
Section titled “압축 포맷 종류”| 포맷 | 상태 | 설명 | 적용 대상 |
|---|---|---|---|
rle | ✅ 사용 중 | Run-Length Encoding | 연속된 인덱스/픽셀 데이터 |
압축 데이터 처리 흐름
Section titled “압축 데이터 처리 흐름”┌────────────────┐ ┌─────────────┐ ┌─────────────┐│ 원본 데이터 │ ──▶ │ 인코딩 │ ──▶ │ 저장/전송 ││ (pixel_indices)│ │ (RLE 등) │ │ (압축 상태) │└────────────────┘ └─────────────┘ └─────────────┘ │┌───────────────┐ ┌─────────────┐ ││ 사용 가능 │ ◀── │ 디코딩 │ ◀─────────┘│ (복원된 배열) │ │ (압축 해제) │└───────────────┘ └─────────────┘압축 적용 예시
Section titled “압축 적용 예시”압축 전 (Raw):
{ "id": "seg_001", "pixel_indices": [100, 101, 102, 103, 104, 200, 201, 202]}압축 후 (RLE):
{ "id": "seg_001", "pixel_indices": [100, 5, 200, 3], "isCompressed": true, "compressionFormat": "rle"}RLE 형식:
[시작인덱스, 연속개수, 시작인덱스, 연속개수, ...]
Classification 및 Label 처리
Section titled “Classification 및 Label 처리”Classification 구조
Section titled “Classification 구조”관리자가 정의한 트리 구조의 분류 스키마는 1-depth key-value 쌍으로 평탄화됩니다:
{ "class": "boundingbox", "text": "설명 텍스트", "multiple": ["option1", "option2"], "single_radio": "selected_option", "single_dropdown": "dropdown_value"}Label 자동 생성
Section titled “Label 자동 생성”classification 기반으로 label 배열이 자동 생성됩니다:
if (annotation.classification) { annotation.label = getLabel(variables, annotation.id, annotation.tool, annotation.classification)}데이터 전처리 및 후처리
Section titled “데이터 전처리 및 후처리”beforeAction Hook
Section titled “beforeAction Hook”모든 어노테이터는 definedHooks.beforeAction을 통해 저장 전 데이터 정리를 수행합니다:
definedHooks: { beforeAction: (annotatorData, variables) => { return dataGrooming(annotatorData, variables) }}어노테이터별 특수 처리
Section titled “어노테이터별 특수 처리”| 어노테이터 | 전처리 내용 |
|---|---|
| Image | dataGrooming 실행 |
| Video | bakeInterpolatedFrames (bounding_box 키프레임 보간) + dataGrooming |
| Text | dataGrooming 실행 |
| PCD | 빈 points 배열 가진 3d_segmentation 삭제 + dataGrooming |
| Prompt | dataGrooming 실행 |
| Audio | dataGrooming 실행 |