Skip to main content

세그멘테이션 변환 (비디오)

비디오 세그멘테이션 어노테이션의 V1/V2 양방향 변환 가이드입니다.

데이터 구조

V1 구조

# annotations
{
"id": "vid_seg_1",
"tool": "segmentation",
"isLocked": False,
"isVisible": True,
"isValid": True,
"classification": {
"class": "action",
"action_type": "walking"
},
"label": ["action"]
}

# annotationsData
{
"id": "vid_seg_1",
"section": {
"startFrame": 100,
"endFrame": 250
}
}

V2 구조

{
"id": "vid_seg_1",
"classification": "action",
"attrs": [
{"name": "action_type", "value": "walking"}
],
"data": {
"startFrame": 100,
"endFrame": 250
}
}

변환 규칙

V1 → V2

V1 필드V2 필드
section.startFramedata.startFrame
section.endFramedata.endFrame
classification.classclassification
classification.{other}attrs[{name, value}]

V2 → V1

V2 필드V1 필드
data.startFramesection.startFrame
data.endFramesection.endFrame
classificationclassification.class
attrs[{name, value}]classification.{name: value}

사용 예제

기본 변환

from synapse_sdk.utils.converters.dm import convert_v1_to_v2, convert_v2_to_v1

# V1 비디오 세그멘테이션 데이터
v1_data = {
"annotations": {
"video_1": [
{
"id": "VidSeg123",
"tool": "segmentation",
"classification": {"class": "action", "action_type": "walking"}
}
]
},
"annotationsData": {
"video_1": [
{
"id": "VidSeg123",
"section": {"startFrame": 100, "endFrame": 250}
}
]
}
}

# V2로 변환
result = convert_v1_to_v2(v1_data)
annotation_data = result["annotation_data"]

# V2 결과 확인
seg = annotation_data["videos"][0]["segmentation"][0]
print(seg["data"]) # {"startFrame": 100, "endFrame": 250}
print(seg["classification"]) # "action"

여러 구간 처리

# 비디오 내 여러 액션 구간
v1_multi = {
"annotations": {
"video_1": [
{"id": "seg_walk", "tool": "segmentation", "classification": {"class": "walking"}},
{"id": "seg_run", "tool": "segmentation", "classification": {"class": "running"}},
{"id": "seg_stand", "tool": "segmentation", "classification": {"class": "standing"}}
]
},
"annotationsData": {
"video_1": [
{"id": "seg_walk", "section": {"startFrame": 0, "endFrame": 100}},
{"id": "seg_run", "section": {"startFrame": 101, "endFrame": 200}},
{"id": "seg_stand", "section": {"startFrame": 201, "endFrame": 300}}
]
}
}

# V2로 변환
result = convert_v1_to_v2(v1_multi)
segments = result["annotation_data"]["videos"][0]["segmentation"]

for seg in segments:
print(f"{seg['classification']}: frame {seg['data']['startFrame']}-{seg['data']['endFrame']}")
# walking: frame 0-100
# running: frame 101-200
# standing: frame 201-300

라운드트립 검증

def verify_video_seg_roundtrip(v1_original):
"""비디오 세그멘테이션 라운드트립 검증"""
# V1 → V2 → V1
v2_result = convert_v1_to_v2(v1_original)
v1_restored = convert_v2_to_v1(v2_result)

# 섹션 비교
orig_section = v1_original["annotationsData"]["video_1"][0]["section"]
rest_section = v1_restored["annotationsData"]["video_1"][0]["section"]

assert orig_section["startFrame"] == rest_section["startFrame"]
assert orig_section["endFrame"] == rest_section["endFrame"]

print("비디오 세그멘테이션 라운드트립 검증 성공")

verify_video_seg_roundtrip(v1_data)

이미지 vs 비디오 세그멘테이션

특성이미지비디오
V1 데이터 필드pixel_indicessection
V2 data 타입list[int]{startFrame, endFrame}
미디어 IDimage_Nvideo_N
용도픽셀 마스크프레임 구간