Skip to content

Commit

Permalink
Fix MOT and CVAT imports (#20)
Browse files Browse the repository at this point in the history
* Fix MOT and CVAT import

* Change packaging from poetry to hatch

* Add changelog

* Fix readme

* Fix CI env
  • Loading branch information
tadejsv authored Sep 29, 2022
1 parent 6982be7 commit 879a161
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 48 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ jobs:
uses: mamba-org/provision-with-micromamba@main
with:
environment-file: env.yaml
- name: Install package with requirements
run: poetry install
- name: Lint
run: make lint

Expand All @@ -46,6 +44,6 @@ jobs:
environment-file: env.yaml
extra-specs: python=${{ matrix.python-version }}
- name: Install package with requirements
run: poetry install
run: pip install -e .
- name: Run PyTest
run: pytest
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [0.1.5] - 2022-09-29

## Changed

* Fix correct 1-index frame handling for MOT-based files ([#20](https://github.com/tadejsv/EvalDeT/pull/20))
* Fix handling of "outside" detections in CVAT format ([#20](https://github.com/tadejsv/EvalDeT/pull/20))

* Switch to `hatch` for packaging ([#20](https://github.com/tadejsv/EvalDeT/pull/20))


## [0.1.4] - 2022-08-29

### Changed
Expand Down
15 changes: 13 additions & 2 deletions env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@ name: EvalDeT
channels:
- conda-forge
dependencies:
- python
- python<3.11
- pip
- poetry
- hatch=1.5.0
- numpy=1.23.2
- scipy=1.9.0
- flake8=5.0.4
- black=22.8.0
- pytest=7.1.3
- isort=5.10.1
- mypy=0.971
- pre-commit=2.20.0
- Sphinx=5.2.2
- pydata-sphinx-theme=0.10.1
- sphinx-autodoc-typehints=1.19.4
54 changes: 32 additions & 22 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
[build-system]
requires = ["poetry-core>=1.1.0"]
build-backend = "poetry.core.masonry.api"
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.poetry]
[project]
name = "evaldet"
version = "0.1.4"
description = "Evaluation for Detection and Tracking"
license = "Apache-2.0"
authors = ["Tadej Svetina <[email protected]>"]
authors = [
{ name = "Tadej", email = "[email protected]" },
]
readme = "README.md"
repository = "https://github.com/tadejsv/evaldet"
documentation = "https://evaldet.readthedocs.io"
keywords = ["evaluation", "tracking", "object detection", "computer vision"]
classifiers = [
"License :: OSI Approved :: Apache Software License",
Expand All @@ -20,23 +19,34 @@ classifiers = [
"Development Status :: 4 - Beta",
"Topic :: Scientific/Engineering :: Image Recognition",
]
include = ["README.md", "LICENSE"]
dependencies = [
"numpy~=1.23.2",
"scipy~=1.9.0",
]
dynamic = ["version"]

[tool.hatch.version]
path = "src/evaldet/__init__.py"

[tool.poetry.dependencies]
python = ">=3.9,<3.11"
numpy = "^1.23.2"
scipy = "^1.9.0"
[project.urls]
Documentation = "https://evaldet.readthedocs.io"
Issues = "https://github.com/tadejsv/evaldet/issues"
Source = "https://github.com/sasp-ai/evaldet"

[tool.poetry.dev-dependencies]
pytest = "^7.1.2"
flake8 = "^5.0.4"
black = "^22.6.0"
isort = "^5.10.1"
mypy = "^0.971"
Sphinx = "^5.1.1"
pydata-sphinx-theme = "^0.9.0"
sphinx-autodoc-typehints = "^1.19.2"
pre-commit = "^2.20.0"
[project.optional-dependencies]
ci = [
"flake8~=5.0.4",
"pytest~=7.1.2",
"black~=22.0.6",
"isort~=5.10.1",
"mypy~=0.971",
"pre-commit~=2.20.0"
]
docs = [
"Shpinx~=5.1.1",
"pydata-sphinx-theme~=0.9.2",
"sphinx-autodoc-typehints~=1.19.1",
]

[tool.isort]
profile = "black"
Expand Down
2 changes: 1 addition & 1 deletion src/evaldet/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.1.4"
__version__ = "0.1.5"

from .metrics import MOTMetrics # noqa: F401
from .tracks import Tracks # noqa: F401
34 changes: 30 additions & 4 deletions src/evaldet/tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ class Tracks:
- CVAT's version of the MOT format (as described `here <https://openvinotoolkit.github.io/cvat/docs/manual/advanced/formats/format-mot/>`__)
- CVAT for Video format (as described `here <https://openvinotoolkit.github.io/cvat/docs/manual/advanced/xml_format/>`__)
- UA-DETRAC XML format (you can download an example `here <https://detrac-db.rit.albany.edu/Tracking>`__)
The frame numbers will be zero-indexed internally, so for the MOT files 1 will be
subtracted from all frame numbers.
"""

@classmethod
def from_csv(
cls,
csv_file: Union[str, Path],
fieldnames: list[str],
zero_indexed: bool = True,
) -> "Tracks":
"""Get detections from a CSV file.
Expand All @@ -61,6 +65,9 @@ def from_csv(
- ``class``: for the class label of the item
- ``id``: for the id of the item
- ``frame``: for the frame number
zero_indexed: If the frame numbers are zero indexed. Otherwise they are
assumed to be 1 indexed, and 1 will be subtracted from all frame numbers
to make them zero indexed.
"""
tracks = cls()
with open(csv_file, newline="") as file:
Expand All @@ -86,8 +93,13 @@ def from_csv(
if _CLASS_KEY in fieldnames:
extra_vals["classes"] = frames[frame]["classes"]

if zero_indexed:
frame_num = frame
else:
frame_num = frame - 1

tracks.add_frame(
frame,
frame_num,
ids=frames[frame]["ids"],
detections=np.array(frames[frame]["detections"]),
**extra_vals,
Expand All @@ -106,6 +118,9 @@ def from_mot(cls, file_path: Union[Path, str]) -> "Tracks":
Note that all values above are expected to be **numeric** - string values will
cause an error. The values for ``x``, ``y`` and ``z`` will be ignored.
The frame numbers will be zero-indexed internally, so 1 will be subtracted from
all frame numbers.
Args:
file_path: Path where the detections file is located. The file should be
in the format described above, and should not have a header.
Expand All @@ -122,7 +137,7 @@ def from_mot(cls, file_path: Union[Path, str]) -> "Tracks":
"_",
]

return cls.from_csv(file_path, fieldnames)
return cls.from_csv(file_path, fieldnames, zero_indexed=False)

@classmethod
def from_mot_gt(cls, file_path: Union[Path, str]) -> "Tracks":
Expand All @@ -136,6 +151,9 @@ def from_mot_gt(cls, file_path: Union[Path, str]) -> "Tracks":
Note that all values above are expected to be **numeric** - string values will
cause an error. The value for ``visibility`` will be ignored.
The frame numbers will be zero-indexed internally, so 1 will be subtracted from
all frame numbers.
Args:
file_path: Path where the detections file is located. The file should be
in the format described above, and should not have a header.
Expand All @@ -153,7 +171,7 @@ def from_mot_gt(cls, file_path: Union[Path, str]) -> "Tracks":
"visibility",
]

return cls.from_csv(file_path, fieldnames)
return cls.from_csv(file_path, fieldnames, zero_indexed=False)

@classmethod
def from_mot_cvat(cls, file_path: Union[Path, str]) -> "Tracks":
Expand All @@ -168,6 +186,9 @@ def from_mot_cvat(cls, file_path: Union[Path, str]) -> "Tracks":
optional. The values for ``not ignored``, ``visibility`` and ``skipped`` will be
ignored.
The frame numbers will be zero-indexed internally, so 1 will be subtracted from
all frame numbers.
Args:
file_path: Path where the detections file is located. The file should be
in the format described above, and should not have a header.
Expand All @@ -184,7 +205,7 @@ def from_mot_cvat(cls, file_path: Union[Path, str]) -> "Tracks":
_CLASS_KEY,
]

return cls.from_csv(file_path, fieldnames)
return cls.from_csv(file_path, fieldnames, zero_indexed=False)

@classmethod
def from_ua_detrac(
Expand Down Expand Up @@ -332,6 +353,8 @@ def from_cvat_video(
``classes_list`` - a list of all possible class values. The class attribute will
then be replaced by the index of the label in this list.
Elements with "outside=1" will be ignored.
Args:
file_path: Path where the detections file is located
classes_list: The list of all possible class values. The values from that
Expand All @@ -350,6 +373,9 @@ def from_cvat_video(
track_class = classes_list.index(track_cvat.attrib["label"])

for box in track_cvat.findall("box"):
if int(box.attrib["outside"]) == 1:
continue

frame_num = int(box.attrib[_FRAME_KEY])
xmin, ymin = float(box.attrib["xtl"]), float(box.attrib["ytl"])
width = float(box.attrib["xbr"]) - xmin
Expand Down
16 changes: 8 additions & 8 deletions tests/data/tracks/cvat_mot_sample.csv
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
660,1,323.83,104.06,43.77000000000004,35.43000000000001,1,2,1.0
660,2,273.1,88.77,55.589999999999975,24.320000000000007,1,2,1.0
660,3,375.24,80.43,26.409999999999968,22.239999999999995,1,2,1.0
661,1,320.98,105.24,44.66999999999996,35.709999999999994,1,2,1.0
661,2,273.1,88.88,55.69999999999999,24.52000000000001,1,2,1.0
661,3,374.69,80.78,26.399999999999977,22.230000000000004,1,2,1.0
800,2,329.27,96.65,56.53000000000003,32.44999999999999,1,2,1.0
800,4,0.0,356.7,76.6,122.67000000000002,1,2,1.0
661,1,323.83,104.06,43.77000000000004,35.43000000000001,1,2,1.0
661,2,273.1,88.77,55.589999999999975,24.320000000000007,1,2,1.0
661,3,375.24,80.43,26.409999999999968,22.239999999999995,1,2,1.0
662,1,320.98,105.24,44.66999999999996,35.709999999999994,1,2,1.0
662,2,273.1,88.88,55.69999999999999,24.52000000000001,1,2,1.0
662,3,374.69,80.78,26.399999999999977,22.230000000000004,1,2,1.0
801,2,329.27,96.65,56.53000000000003,32.44999999999999,1,2,1.0
801,4,0.0,356.7,76.6,122.67000000000002,1,2,1.0
1 change: 1 addition & 0 deletions tests/data/tracks/cvat_video_sample.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<track id="3" label="Car" source="manual">
<box frame="660" outside="0" occluded="0" keyframe="1" xtl="375.24" ytl="80.43" xbr="401.65" ybr="102.67" z_order="0"> </box>
<box frame="661" outside="0" occluded="0" keyframe="1" xtl="374.69" ytl="80.78" xbr="401.09" ybr="103.01" z_order="0"> </box>
<box frame="662" outside="1" occluded="0" keyframe="1" xtl="374.69" ytl="80.78" xbr="401.09" ybr="103.01" z_order="0"> </box>
</track>
<track id="4" label="Car" source="manual">
<box frame="800" outside="0" occluded="0" keyframe="1" xtl="0.0" ytl="356.7" xbr="76.6" ybr="479.37" z_order="0"> </box>
Expand Down
16 changes: 8 additions & 8 deletions tests/data/tracks/mot_sample.csv
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
660,1,323.83,104.06,43.77000000000004,35.43000000000001,0,-1,-1,-1
660,2,273.1,88.77,55.589999999999975,24.320000000000007,0,-1,-1,-1
660,3,375.24,80.43,26.409999999999968,22.239999999999995,0,-1,-1,-1
661,1,320.98,105.24,44.66999999999996,35.709999999999994,0,-1,-1,-1
661,2,273.1,88.88,55.69999999999999,24.52000000000001,0,-1,-1,-1
661,3,374.69,80.78,26.399999999999977,22.230000000000004,0,-1,-1,-1
800,2,329.27,96.65,56.53000000000003,32.44999999999999,0,-1,-1,-1
800,4,0.0,356.7,76.6,122.67000000000002,0,-1,-1,-1
661,1,323.83,104.06,43.77000000000004,35.43000000000001,0,-1,-1,-1
661,2,273.1,88.77,55.589999999999975,24.320000000000007,0,-1,-1,-1
661,3,375.24,80.43,26.409999999999968,22.239999999999995,0,-1,-1,-1
662,1,320.98,105.24,44.66999999999996,35.709999999999994,0,-1,-1,-1
662,2,273.1,88.88,55.69999999999999,24.52000000000001,0,-1,-1,-1
662,3,374.69,80.78,26.399999999999977,22.230000000000004,0,-1,-1,-1
801,2,329.27,96.65,56.53000000000003,32.44999999999999,0,-1,-1,-1
801,4,0.0,356.7,76.6,122.67000000000002,0,-1,-1,-1

0 comments on commit 879a161

Please sign in to comment.