Metadata-Version: 2.4
Name: dnt
Version: 0.3.3
Summary: A Python tool for video-based traffic analytics
Author-email: Zhenyu Wang <wonstran@hotmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/wonstran/dnt
Keywords: traffic,vehicle,trajectory,safety
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: End Users/Desktop
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE.md
Requires-Dist: torch>=2.2
Requires-Dist: torchvision
Requires-Dist: ultralytics<9,>=8.4.14
Requires-Dist: boxmot==16.0.11
Requires-Dist: numpy<3,>=2.2
Requires-Dist: pandas<3,>=2.2
Requires-Dist: opencv-python<5,>=4.7
Requires-Dist: scipy>=1.13
Requires-Dist: filterpy
Requires-Dist: pyyaml
Requires-Dist: tqdm
Requires-Dist: requests
Requires-Dist: Pillow
Requires-Dist: shapely>=2
Requires-Dist: geopandas
Requires-Dist: easyocr
Requires-Dist: dateparser
Requires-Dist: pytz
Requires-Dist: cython_bbox
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: build; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs-material; extra == "docs"
Requires-Dist: mkdocstrings[python]; extra == "docs"
Requires-Dist: mkdocs-with-pdf; extra == "docs"
Dynamic: license-file

# DNT: Dedection and Tracking

Python package for video-based traffic analysis: detection, tracking, labeling, and post-processing.
Surrogate safety measures (SSMs) can be generated using the **Traffic Surrogate Safety Analysis (TSSA)** package.

## Features

- Object detection (`dnt.detect.Detector`, YOLO/RT-DETR backend).
- Multi-object tracking (`dnt.track.Tracker`, BoxMOT backend).
- Video labeling/visualization (`dnt.label.Labeler`).
- Track post-processing:
  - RTS interpolation for trajectory gaps.
  - Tracklet linking (stitching broken IDs).

## Requirements

- OS: Ubuntu 20.04+ (or compatible Linux).
- Python: 3.11+.
- CUDA GPU recommended for detection/tracking speed.

Install dependencies from:
- `requirements.txt`
- `pyproject.toml`

## Installation

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -r requirements.txt
pip install dnt

```
## API Manual

https://wonstran.github.io/dnt/

## Quick Workflow

### 1) Detection

```python
from dnt.detect import Detector

detector = Detector(device="auto")
dets = detector.detect(
    input_video="/path/to/video.mp4",
    iou_file="/path/to/dets.txt",
    verbose=True,
)
```

For long videos, pass `return_df=False` to only write `iou_file` (rows are streamed to disk
batch by batch, and an interrupted run resumes from `/path/to/dets.txt.part` on the next call).

### 2) Tracking

```python
from dnt.track import ByteTrackConfig, Tracker

config = ByteTrackConfig()
tracker = Tracker(config=config, device="auto")
tracks = tracker.track(
    det_file="/path/to/dets.txt",
    out_file="/path/to/tracks.txt",
    video_file="/path/to/video.mp4",
)
```

**Tuning trackers.** Every tuning field defaults to `None`, meaning BoxMOT's own default. Set only what you
want to change, e.g. `ByteTrackConfig(track_thresh=0.5)`. Settings that a tracker ignores raise
`ValueError`. See BoxMOT's documentation for parameter meanings: https://github.com/mikel-brostrom/boxmot

### 3) RTS interpolation (post-process)

```python
from dnt.track.post_process import interpolate_tracks_rts

tracks_interp = interpolate_tracks_rts(
    track_file="/path/to/tracks.txt",
    output_file="/path/to/tracks_interp.txt",
    max_gap=30,        # max consecutive missing frames to fill
    interp_col="interp",
    verbose=True,
)
```

Notes:
- `interp == 1` means interpolated frame.
- Real detections are treated as `interp != 1` (supports legacy `interp=-1` files).
- Output file is written in track-file format (no CSV header), compatible with `Labeler.draw_tracks`.

### 4) Tracklet linking (ID stitching)

```python
from dnt.track.post_process import link_tracklets

tracks_linked = link_tracklets(
    track_file="/path/to/tracks_interp.txt",
    output_file="/path/to/tracks_linked.txt",
    max_gap=20,        # candidate end-start frame gap
    verbose=True,
)
```

`link_tracklets` uses:
- hard gates (time/class/size/motion/IoU),
- cost matrix scoring,
- global 1-to-1 assignment (Hungarian),
- union-find chain merge and ID remap.

### 5) Labeling

```python
from dnt.label import Labeler

labeler = Labeler()
labeler.draw_tracks(
    input_video="/path/to/video.mp4",
    output_video="/path/to/output_labeled.mp4",
    track_file="/path/to/tracks_linked.txt",
    verbose=True,
)
```

## Modules

- `dnt.detect`
- `dnt.track`
- `dnt.label`
- `dnt.track.post_process`

## Author

Zhenyu Wang ([wonstran@hotmail.com](mailto:wonstran@hotmail.com))

## License

MIT License. See `LICENSE.md`.
