Skip to content

Commit af6eeb8

Browse files
committed
Add further testing
1 parent 67c603b commit af6eeb8

File tree

8 files changed

+594
-25
lines changed

8 files changed

+594
-25
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<annotations>
3+
<track id="0" label="Grevy" source="manual">
4+
<box frame="0" outside="0" occluded="0" keyframe="1" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
5+
<box frame="1" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
6+
<box frame="2" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
7+
<box frame="3" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
8+
<box frame="4" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
9+
<box frame="5" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
10+
<box frame="6" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
11+
<box frame="7" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
12+
<box frame="8" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
13+
<box frame="9" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
14+
<box frame="10" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
15+
<box frame="21" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
16+
<box frame="22" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
17+
<box frame="23" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2135.00" ybr="1978.00" z_order="0"/>
18+
<box frame="24" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
19+
<box frame="25" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
20+
<box frame="26" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
21+
<box frame="27" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
22+
<box frame="28" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
23+
<box frame="29" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
24+
<box frame="30" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
25+
</track>
26+
<track id="1" label="Grevy" source="manual">
27+
<box frame="0" outside="0" occluded="0" keyframe="1" xtl="2513.00" ytl="1921.00" xbr="2615.00" ybr="1991.00" z_order="0"/>
28+
<box frame="1" outside="0" occluded="0" keyframe="0" xtl="2513.00" ytl="1921.00" xbr="2615.00" ybr="1991.00" z_order="0"/>
29+
<box frame="2" outside="0" occluded="0" keyframe="0" xtl="2512.00" ytl="1921.00" xbr="2614.00" ybr="1991.00" z_order="0"/>
30+
<box frame="3" outside="0" occluded="0" keyframe="0" xtl="2512.00" ytl="1921.00" xbr="2613.00" ybr="1991.00" z_order="0"/>
31+
<box frame="4" outside="0" occluded="0" keyframe="0" xtl="2511.00" ytl="1921.00" xbr="2613.00" ybr="1991.00" z_order="0"/>
32+
<box frame="5" outside="0" occluded="0" keyframe="0" xtl="2510.00" ytl="1921.00" xbr="2612.00" ybr="1991.00" z_order="0"/>
33+
<box frame="6" outside="0" occluded="0" keyframe="0" xtl="2510.00" ytl="1921.00" xbr="2612.00" ybr="1991.00" z_order="0"/>
34+
<box frame="7" outside="0" occluded="0" keyframe="0" xtl="2509.00" ytl="1921.00" xbr="2611.00" ybr="1991.00" z_order="0"/>
35+
<box frame="8" outside="0" occluded="0" keyframe="0" xtl="2508.00" ytl="1921.00" xbr="2610.00" ybr="1991.00" z_order="0"/>
36+
<box frame="9" outside="0" occluded="0" keyframe="0" xtl="2508.00" ytl="1921.00" xbr="2610.00" ybr="1991.00" z_order="0"/>
37+
<box frame="10" outside="0" occluded="0" keyframe="0" xtl="2507.00" ytl="1921.00" xbr="2609.00" ybr="1991.00" z_order="0"/>
38+
<box frame="11" outside="0" occluded="0" keyframe="0" xtl="2507.00" ytl="1921.00" xbr="2608.00" ybr="1991.00" z_order="0"/>
39+
<box frame="12" outside="0" occluded="0" keyframe="0" xtl="2506.00" ytl="1921.00" xbr="2608.00" ybr="1991.00" z_order="0"/>
40+
<box frame="13" outside="0" occluded="0" keyframe="0" xtl="2505.00" ytl="1921.00" xbr="2607.00" ybr="1991.00" z_order="0"/>
41+
<box frame="14" outside="0" occluded="0" keyframe="0" xtl="2505.00" ytl="1921.00" xbr="2607.00" ybr="1991.00" z_order="0"/>
42+
<box frame="15" outside="0" occluded="0" keyframe="0" xtl="2504.00" ytl="1920.00" xbr="2606.00" ybr="1991.00" z_order="0"/>
43+
<box frame="16" outside="0" occluded="0" keyframe="0" xtl="2503.00" ytl="1920.00" xbr="2605.00" ybr="1991.00" z_order="0"/>
44+
<box frame="17" outside="0" occluded="0" keyframe="0" xtl="2503.00" ytl="1920.00" xbr="2605.00" ybr="1991.00" z_order="0"/>
45+
<box frame="18" outside="0" occluded="0" keyframe="0" xtl="2502.00" ytl="1920.00" xbr="2604.00" ybr="1991.00" z_order="0"/>
46+
<box frame="19" outside="0" occluded="0" keyframe="0" xtl="2502.00" ytl="1920.00" xbr="2603.00" ybr="1990.00" z_order="0"/>
47+
<box frame="20" outside="0" occluded="0" keyframe="0" xtl="2501.00" ytl="1920.00" xbr="2603.00" ybr="1990.00" z_order="0"/>
48+
</track>
49+
</annotations>

tests/test_cvat2slowfast.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import unittest
22
import sys
33
import os
4+
import json
5+
import pandas as pd
6+
import cv2
47
from kabr_tools import cvat2slowfast
8+
from tests.test_tracks_extractor import (
9+
scene_width,
10+
scene_height
11+
)
512
from tests.utils import (
6-
get_behavior,
713
del_dir,
8-
del_file
14+
del_file,
15+
dir_exists,
16+
file_exists,
17+
get_behavior
918
)
1019

1120

@@ -50,6 +59,40 @@ def test_run(self):
5059
"--classes", self.classes]
5160
run()
5261

62+
# check output dirs
63+
self.assertTrue(dir_exists(self.dataset))
64+
self.assertTrue(dir_exists(f"{self.dataset}/annotation"))
65+
self.assertTrue(dir_exists(f"{self.dataset}/dataset/image"))
66+
self.assertTrue(file_exists(f"{self.dataset}/annotation/classes.json"))
67+
self.assertTrue(file_exists(f"{self.dataset}/annotation/data.csv"))
68+
69+
# check classes.json
70+
with open(f"{self.dataset}/annotation/classes.json", "r", encoding="utf-8") as f:
71+
classes = json.load(f)
72+
with open(self.classes, "r", encoding="utf-8") as f:
73+
ethogram = json.load(f)
74+
self.assertEqual(classes, ethogram)
75+
76+
# check data.csv
77+
with open(f"{self.dataset}/annotation/data.csv", "r", encoding="utf-8") as f:
78+
df = pd.read_csv(f, sep=" ")
79+
80+
video_id = 1
81+
for i, row in df.iterrows():
82+
self.assertEqual(row["original_vido_id"], f"Z{video_id:04d}")
83+
self.assertEqual(row["video_id"], video_id)
84+
self.assertEqual(row["frame_id"], i+1)
85+
self.assertEqual(row["path"], f"Z{video_id:04d}/{i+1}.jpg")
86+
self.assertEqual(row["labels"], 1)
87+
self.assertEqual(i, 90)
88+
89+
# check dataset
90+
for i in range(1, 92):
91+
data_im = f"{self.dataset}/dataset/image/Z{video_id:04d}/{i}.jpg"
92+
self.assertTrue(file_exists(data_im))
93+
data_im = cv2.imread(data_im)
94+
self.assertEqual(data_im.shape, (scene_height, scene_width, 3))
95+
5396
def test_parse_arg_min(self):
5497
# parse arguments
5598
sys.argv = [self.tool,
@@ -67,9 +110,6 @@ def test_parse_arg_min(self):
67110
self.assertEqual(args.old2new, None)
68111
self.assertTrue(not args.no_images)
69112

70-
# run cvat2slowfast
71-
run()
72-
73113
def test_parse_arg_full(self):
74114
# parse arguments
75115
sys.argv = ["cvat2slowfast.py",
@@ -86,6 +126,3 @@ def test_parse_arg_full(self):
86126
self.assertEqual(args.classes, self.classes)
87127
self.assertEqual(args.old2new, self.old2new)
88128
self.assertTrue(args.no_images)
89-
90-
# run cvat2slowfast
91-
run()

tests/test_cvat2ultralytics.py

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import unittest
22
import sys
33
import os
4+
from lxml import etree
5+
import pandas as pd
6+
import cv2
47
from kabr_tools import cvat2ultralytics
58
from tests.utils import (
69
del_dir,
710
del_file,
8-
get_detection
11+
get_detection,
12+
dir_exists,
13+
file_exists
914
)
1015

1116

@@ -32,7 +37,7 @@ def setUp(self):
3237
self.video = TestCvat2Ultralytics.dir
3338
self.annotation = TestCvat2Ultralytics.dir
3439
self.dataset = "tests/ultralytics"
35-
self.skip = "5"
40+
self.skip = "1"
3641
self.label2index = "ethogram/label2index.json"
3742

3843
def tearDown(self):
@@ -44,9 +49,75 @@ def test_run(self):
4449
sys.argv = [self.tool,
4550
"--video", self.video,
4651
"--annotation", self.annotation,
47-
"--dataset", "tests/ultralytics"]
52+
"--dataset", "tests/ultralytics",
53+
"--skip", self.skip]
4854
run()
4955

56+
# check for output dirs
57+
self.assertTrue(dir_exists(self.dataset))
58+
self.assertTrue(dir_exists(f"{self.dataset}/images/test"))
59+
self.assertTrue(dir_exists(f"{self.dataset}/images/train"))
60+
self.assertTrue(dir_exists(f"{self.dataset}/images/val"))
61+
self.assertTrue(dir_exists(f"{self.dataset}/labels/test"))
62+
self.assertTrue(dir_exists(f"{self.dataset}/labels/train"))
63+
self.assertTrue(dir_exists(f"{self.dataset}/labels/val"))
64+
65+
# check output
66+
annotations = etree.parse(TestCvat2Ultralytics.annotation).getroot()
67+
tracks = [list(track.findall("box")) for track in annotations.findall("track")]
68+
self.assertEqual(len(tracks[0]), 21)
69+
self.assertEqual(len(tracks[0]), len(tracks[1]))
70+
original_size = annotations.find("meta").find("task").find("original_size")
71+
height = int(original_size.find("height").text)
72+
width = int(original_size.find("width").text)
73+
for i in range(len(tracks[0])):
74+
# check existence
75+
if i < 16:
76+
data_im = f"{self.dataset}/images/train/DJI_0068_{i}.jpg"
77+
self.assertTrue(file_exists(data_im))
78+
data_label = f"{self.dataset}/labels/train/DJI_0068_{i}.txt"
79+
self.assertTrue(file_exists(data_label))
80+
elif i < 18:
81+
data_im = f"{self.dataset}/images/val/DJI_0068_{i}.jpg"
82+
self.assertTrue(file_exists(data_im))
83+
data_label = f"{self.dataset}/labels/val/DJI_0068_{i}.txt"
84+
self.assertTrue(file_exists(data_label))
85+
else:
86+
data_im = f"{self.dataset}/images/test/DJI_0068_{i}.jpg"
87+
self.assertTrue(file_exists(data_im))
88+
data_label = f"{self.dataset}/labels/test/DJI_0068_{i}.txt"
89+
self.assertTrue(file_exists(data_label))
90+
91+
# check image
92+
data_im = cv2.imread(data_im)
93+
self.assertEqual(data_im.shape, (height, width, 3))
94+
95+
# check label
96+
data_label = pd.read_csv(data_label, sep = " ", header = None)
97+
annotation_label = []
98+
for track in tracks:
99+
box = track[i]
100+
x_start = float(box.attrib["xtl"])
101+
y_start = float(box.attrib["ytl"])
102+
x_end = float(box.attrib["xbr"])
103+
y_end = float(box.attrib["ybr"])
104+
x_center = (x_start + (x_end - x_start) / 2) / width
105+
y_center = (y_start + (y_end - y_start) / 2) / height
106+
w = (x_end - x_start) / width
107+
h = (y_end - y_start) / height
108+
annotation_label.append(
109+
[0, x_center, y_center, w, h]
110+
)
111+
self.assertEqual(len(data_label.index), len(annotation_label))
112+
113+
for i, label in enumerate(annotation_label):
114+
self.assertEqual(label[0], annotation_label[i][0])
115+
self.assertAlmostEqual(label[1], annotation_label[i][1], places=4)
116+
self.assertAlmostEqual(label[2], annotation_label[i][2], places=4)
117+
self.assertAlmostEqual(label[3], annotation_label[i][3], places=4)
118+
self.assertAlmostEqual(label[4], annotation_label[i][4], places=4)
119+
120+
50121
def test_parse_arg_min(self):
51122
# parse arguments
52123
sys.argv = [self.tool,
@@ -81,7 +152,7 @@ def test_parse_arg_full(self):
81152
self.assertEqual(args.video, self.video)
82153
self.assertEqual(args.annotation, self.annotation)
83154
self.assertEqual(args.dataset, self.dataset)
84-
self.assertEqual(args.skip, 5)
155+
self.assertEqual(args.skip, int(self.skip))
85156
self.assertEqual(args.label2index, self.label2index)
86157

87158
# run cvat2ultralytics

0 commit comments

Comments
 (0)