Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/kabr_tools/cvat2slowfast.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def cvat2slowfast(path_to_mini_scenes: str, path_to_new_dataset: str,
charades_df = pd.DataFrame(data=headers)
video_id = 1
folder_name = 1
flag = not no_images

for i, folder in enumerate(natsorted(os.listdir(path_to_mini_scenes))):
if os.path.exists(f"{path_to_mini_scenes}/{folder}/actions"):
Expand Down Expand Up @@ -105,7 +104,7 @@ def cvat2slowfast(path_to_mini_scenes: str, path_to_new_dataset: str,
size = int(vc.get(cv2.CAP_PROP_FRAME_COUNT))

while vc.isOpened():
if flag is False:
if no_images:
if index < size:
returned = True
frame = None
Expand All @@ -125,7 +124,7 @@ def cvat2slowfast(path_to_mini_scenes: str, path_to_new_dataset: str,
behavior = old2new[behavior]

if behavior in label2number.keys():
if flag:
if not no_images:
cv2.imwrite(f"{output_folder}/{adjusted_index}.jpg", frame)

# TODO: Major slow down here. Add to a list rather than dataframe,
Expand Down
49 changes: 49 additions & 0 deletions tests/examples/DETECTOR1/DJI_tracks.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version='1.0' encoding='UTF-8'?>
<annotations>
<track id="0" label="Grevy" source="manual">
<box frame="0" outside="0" occluded="0" keyframe="1" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
<box frame="1" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
<box frame="2" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
<box frame="3" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2133.00" ybr="1978.00" z_order="0"/>
<box frame="4" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="5" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="6" outside="0" occluded="0" keyframe="0" xtl="2011.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="7" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="8" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="9" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1883.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="10" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="21" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="22" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2134.00" ybr="1978.00" z_order="0"/>
<box frame="23" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2135.00" ybr="1978.00" z_order="0"/>
<box frame="24" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
<box frame="25" outside="0" occluded="0" keyframe="0" xtl="2012.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
<box frame="26" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
<box frame="27" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
<box frame="28" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
<box frame="29" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
<box frame="30" outside="0" occluded="0" keyframe="0" xtl="2013.00" ytl="1882.00" xbr="2135.00" ybr="1977.00" z_order="0"/>
</track>
<track id="1" label="Grevy" source="manual">
<box frame="0" outside="0" occluded="0" keyframe="1" xtl="2513.00" ytl="1921.00" xbr="2615.00" ybr="1991.00" z_order="0"/>
<box frame="1" outside="0" occluded="0" keyframe="0" xtl="2513.00" ytl="1921.00" xbr="2615.00" ybr="1991.00" z_order="0"/>
<box frame="2" outside="0" occluded="0" keyframe="0" xtl="2512.00" ytl="1921.00" xbr="2614.00" ybr="1991.00" z_order="0"/>
<box frame="3" outside="0" occluded="0" keyframe="0" xtl="2512.00" ytl="1921.00" xbr="2613.00" ybr="1991.00" z_order="0"/>
<box frame="4" outside="0" occluded="0" keyframe="0" xtl="2511.00" ytl="1921.00" xbr="2613.00" ybr="1991.00" z_order="0"/>
<box frame="5" outside="0" occluded="0" keyframe="0" xtl="2510.00" ytl="1921.00" xbr="2612.00" ybr="1991.00" z_order="0"/>
<box frame="6" outside="0" occluded="0" keyframe="0" xtl="2510.00" ytl="1921.00" xbr="2612.00" ybr="1991.00" z_order="0"/>
<box frame="7" outside="0" occluded="0" keyframe="0" xtl="2509.00" ytl="1921.00" xbr="2611.00" ybr="1991.00" z_order="0"/>
<box frame="8" outside="0" occluded="0" keyframe="0" xtl="2508.00" ytl="1921.00" xbr="2610.00" ybr="1991.00" z_order="0"/>
<box frame="9" outside="0" occluded="0" keyframe="0" xtl="2508.00" ytl="1921.00" xbr="2610.00" ybr="1991.00" z_order="0"/>
<box frame="10" outside="0" occluded="0" keyframe="0" xtl="2507.00" ytl="1921.00" xbr="2609.00" ybr="1991.00" z_order="0"/>
<box frame="11" outside="0" occluded="0" keyframe="0" xtl="2507.00" ytl="1921.00" xbr="2608.00" ybr="1991.00" z_order="0"/>
<box frame="12" outside="0" occluded="0" keyframe="0" xtl="2506.00" ytl="1921.00" xbr="2608.00" ybr="1991.00" z_order="0"/>
<box frame="13" outside="0" occluded="0" keyframe="0" xtl="2505.00" ytl="1921.00" xbr="2607.00" ybr="1991.00" z_order="0"/>
<box frame="14" outside="0" occluded="0" keyframe="0" xtl="2505.00" ytl="1921.00" xbr="2607.00" ybr="1991.00" z_order="0"/>
<box frame="15" outside="0" occluded="0" keyframe="0" xtl="2504.00" ytl="1920.00" xbr="2606.00" ybr="1991.00" z_order="0"/>
<box frame="16" outside="0" occluded="0" keyframe="0" xtl="2503.00" ytl="1920.00" xbr="2605.00" ybr="1991.00" z_order="0"/>
<box frame="17" outside="0" occluded="0" keyframe="0" xtl="2503.00" ytl="1920.00" xbr="2605.00" ybr="1991.00" z_order="0"/>
<box frame="18" outside="0" occluded="0" keyframe="0" xtl="2502.00" ytl="1920.00" xbr="2604.00" ybr="1991.00" z_order="0"/>
<box frame="19" outside="0" occluded="0" keyframe="0" xtl="2502.00" ytl="1920.00" xbr="2603.00" ybr="1990.00" z_order="0"/>
<box frame="20" outside="0" occluded="0" keyframe="0" xtl="2501.00" ytl="1920.00" xbr="2603.00" ybr="1990.00" z_order="0"/>
</track>
</annotations>
53 changes: 45 additions & 8 deletions tests/test_cvat2slowfast.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import unittest
import sys
import os
import json
import pandas as pd
import cv2
from kabr_tools import cvat2slowfast
from tests.test_tracks_extractor import (
scene_width,
scene_height
)
from tests.utils import (
get_behavior,
del_dir,
del_file
del_file,
dir_exists,
file_exists,
get_behavior
)


Expand Down Expand Up @@ -50,6 +59,40 @@ def test_run(self):
"--classes", self.classes]
run()

# check output dirs
self.assertTrue(dir_exists(self.dataset))
self.assertTrue(dir_exists(f"{self.dataset}/annotation"))
self.assertTrue(dir_exists(f"{self.dataset}/dataset/image"))
self.assertTrue(file_exists(f"{self.dataset}/annotation/classes.json"))
self.assertTrue(file_exists(f"{self.dataset}/annotation/data.csv"))

# check classes.json
with open(f"{self.dataset}/annotation/classes.json", "r", encoding="utf-8") as f:
classes = json.load(f)
with open(self.classes, "r", encoding="utf-8") as f:
ethogram = json.load(f)
self.assertEqual(classes, ethogram)

# check data.csv
with open(f"{self.dataset}/annotation/data.csv", "r", encoding="utf-8") as f:
df = pd.read_csv(f, sep=" ")

video_id = 1
for i, row in df.iterrows():
self.assertEqual(row["original_vido_id"], f"Z{video_id:04d}")
self.assertEqual(row["video_id"], video_id)
self.assertEqual(row["frame_id"], i+1)
self.assertEqual(row["path"], f"Z{video_id:04d}/{i+1}.jpg")
self.assertEqual(row["labels"], 1)
self.assertEqual(i, 90)

# check dataset
for i in range(1, 92):
data_im = f"{self.dataset}/dataset/image/Z{video_id:04d}/{i}.jpg"
self.assertTrue(file_exists(data_im))
data_im = cv2.imread(data_im)
self.assertEqual(data_im.shape, (scene_height, scene_width, 3))

def test_parse_arg_min(self):
# parse arguments
sys.argv = [self.tool,
Expand All @@ -67,9 +110,6 @@ def test_parse_arg_min(self):
self.assertEqual(args.old2new, None)
self.assertTrue(not args.no_images)

# run cvat2slowfast
run()

def test_parse_arg_full(self):
# parse arguments
sys.argv = ["cvat2slowfast.py",
Expand All @@ -86,6 +126,3 @@ def test_parse_arg_full(self):
self.assertEqual(args.classes, self.classes)
self.assertEqual(args.old2new, self.old2new)
self.assertTrue(args.no_images)

# run cvat2slowfast
run()
79 changes: 75 additions & 4 deletions tests/test_cvat2ultralytics.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import unittest
import sys
import os
from lxml import etree
import pandas as pd
import cv2
from kabr_tools import cvat2ultralytics
from tests.utils import (
del_dir,
del_file,
get_detection
get_detection,
dir_exists,
file_exists
)


Expand All @@ -32,7 +37,7 @@ def setUp(self):
self.video = TestCvat2Ultralytics.dir
self.annotation = TestCvat2Ultralytics.dir
self.dataset = "tests/ultralytics"
self.skip = "5"
self.skip = "1"
self.label2index = "ethogram/label2index.json"

def tearDown(self):
Expand All @@ -44,9 +49,75 @@ def test_run(self):
sys.argv = [self.tool,
"--video", self.video,
"--annotation", self.annotation,
"--dataset", "tests/ultralytics"]
"--dataset", "tests/ultralytics",
"--skip", self.skip]
run()

# check for output dirs
self.assertTrue(dir_exists(self.dataset))
self.assertTrue(dir_exists(f"{self.dataset}/images/test"))
self.assertTrue(dir_exists(f"{self.dataset}/images/train"))
self.assertTrue(dir_exists(f"{self.dataset}/images/val"))
self.assertTrue(dir_exists(f"{self.dataset}/labels/test"))
self.assertTrue(dir_exists(f"{self.dataset}/labels/train"))
self.assertTrue(dir_exists(f"{self.dataset}/labels/val"))

# check output
annotations = etree.parse(TestCvat2Ultralytics.annotation).getroot()
tracks = [list(track.findall("box")) for track in annotations.findall("track")]
self.assertEqual(len(tracks[0]), 21)
self.assertEqual(len(tracks[0]), len(tracks[1]))
original_size = annotations.find("meta").find("task").find("original_size")
height = int(original_size.find("height").text)
width = int(original_size.find("width").text)
for i in range(len(tracks[0])):
# check existence
if i < 16:
data_im = f"{self.dataset}/images/train/DJI_0068_{i}.jpg"
self.assertTrue(file_exists(data_im))
data_label = f"{self.dataset}/labels/train/DJI_0068_{i}.txt"
self.assertTrue(file_exists(data_label))
elif i < 18:
data_im = f"{self.dataset}/images/val/DJI_0068_{i}.jpg"
self.assertTrue(file_exists(data_im))
data_label = f"{self.dataset}/labels/val/DJI_0068_{i}.txt"
self.assertTrue(file_exists(data_label))
else:
data_im = f"{self.dataset}/images/test/DJI_0068_{i}.jpg"
self.assertTrue(file_exists(data_im))
data_label = f"{self.dataset}/labels/test/DJI_0068_{i}.txt"
self.assertTrue(file_exists(data_label))

# check image
data_im = cv2.imread(data_im)
self.assertEqual(data_im.shape, (height, width, 3))

# check label
data_label = pd.read_csv(data_label, sep = " ", header = None)
annotation_label = []
for track in tracks:
box = track[i]
x_start = float(box.attrib["xtl"])
y_start = float(box.attrib["ytl"])
x_end = float(box.attrib["xbr"])
y_end = float(box.attrib["ybr"])
x_center = (x_start + (x_end - x_start) / 2) / width
y_center = (y_start + (y_end - y_start) / 2) / height
w = (x_end - x_start) / width
h = (y_end - y_start) / height
annotation_label.append(
[0, x_center, y_center, w, h]
)
self.assertEqual(len(data_label.index), len(annotation_label))

for i, label in enumerate(annotation_label):
self.assertEqual(label[0], annotation_label[i][0])
self.assertAlmostEqual(label[1], annotation_label[i][1], places=4)
self.assertAlmostEqual(label[2], annotation_label[i][2], places=4)
self.assertAlmostEqual(label[3], annotation_label[i][3], places=4)
self.assertAlmostEqual(label[4], annotation_label[i][4], places=4)


def test_parse_arg_min(self):
# parse arguments
sys.argv = [self.tool,
Expand Down Expand Up @@ -81,7 +152,7 @@ def test_parse_arg_full(self):
self.assertEqual(args.video, self.video)
self.assertEqual(args.annotation, self.annotation)
self.assertEqual(args.dataset, self.dataset)
self.assertEqual(args.skip, 5)
self.assertEqual(args.skip, int(self.skip))
self.assertEqual(args.label2index, self.label2index)

# run cvat2ultralytics
Expand Down
Loading