Skip to content

Commit 3425cc5

Browse files
feature: upload polyline annotations
1 parent ed0be8d commit 3425cc5

4 files changed

Lines changed: 89 additions & 0 deletions

File tree

next_cvat/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
LabelAttribute,
1313
Mask,
1414
Polygon,
15+
Polyline,
1516
Project,
1617
Tag,
1718
Task,

next_cvat/client/job_annotations.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,22 @@ def add_mask_(
3535

3636
return self
3737

38+
def add_polyline(
39+
self,
40+
polyline: next_cvat.Polyline,
41+
image_name: str,
42+
group: int = 0,
43+
) -> JobAnnotations:
44+
label = self.job.task.project.label(name=polyline.label)
45+
46+
frame = self.job.task.frame(image_name=image_name)
47+
48+
self.annotations["shapes"].append(
49+
polyline.request(frame=frame.id, label_id=label.id, group=group)
50+
)
51+
52+
return self
53+
3854
def request(self) -> models.LabeledDataRequest:
3955
request = models.LabeledDataRequest()
4056
request.version = self.annotations["version"]

next_cvat/types/polyline.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from typing import List, Tuple
44

5+
import numpy as np
6+
from cvat_sdk.api_client import models
57
from pydantic import BaseModel, field_validator
68

79
from .attribute import Attribute
@@ -33,3 +35,19 @@ def topmost(self) -> float:
3335

3436
def bottommost(self) -> float:
3537
return max([y for _, y in self.points])
38+
39+
def request(
40+
self, frame: int, label_id: int, group: int = 0
41+
) -> models.LabeledShapeRequest:
42+
return models.LabeledShapeRequest(
43+
type="polyline",
44+
occluded=bool(self.occluded),
45+
points=np.array(self.points).flatten().tolist(),
46+
rotation=0.0,
47+
outside=False,
48+
attributes=[attr.model_dump() for attr in self.attributes],
49+
group=group,
50+
source=self.source,
51+
frame=frame,
52+
label_id=label_id,
53+
)

tests/test_add_polyline.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from pathlib import Path
2+
3+
import numpy as np
4+
import pytest
5+
6+
import next_cvat
7+
8+
9+
def test_add_polyline():
10+
if not Path(".env.cvat.secrets").exists():
11+
pytest.skip("No secrets file found")
12+
13+
client = next_cvat.Client.from_env_file(".env.cvat.secrets")
14+
15+
project_id = 198488 # Using the same test project as in test_add_mask
16+
job_id = 1442235
17+
task_id = 999670
18+
deformation_attribute_id = 1389238
19+
20+
job = client.project(project_id).task(task_id).job(job_id)
21+
22+
annotations = job.annotations()
23+
24+
# Create a simple polyline (e.g., a zigzag pattern)
25+
points = np.array(
26+
[
27+
[100, 100],
28+
[200, 150],
29+
[300, 100],
30+
[400, 150],
31+
]
32+
).tolist()
33+
34+
annotations.add_polyline(
35+
next_cvat.Polyline(
36+
points=points,
37+
label="Deformation",
38+
source="manual",
39+
occluded=False,
40+
z_order=0,
41+
attributes=[
42+
next_cvat.Attribute(
43+
name="Severity",
44+
value="High",
45+
spec_id=deformation_attribute_id,
46+
)
47+
],
48+
),
49+
image_name="20240916_000854_2011T_437.bmp",
50+
)
51+
52+
job.update_annotations_(annotations)
53+
54+
print("Successfully added polyline annotation")

0 commit comments

Comments
 (0)