# Tram detector

To utilize a graphic card, special drivers and additional software are often required. The minimum supported Python version is 3.8.16.

## Installation

Make sure your system is up to date. Make a new virtual environment:

`python -m venv venv`

Activate your new virtual environment:

`source venv/bin/activate`

Update pip:

`pip install --upgrade pip`

Install the desired version of PyTorch from <https://pytorch.org/get-started/locally/> using pip. If in doubt, choose the CPU version.

Install the requirements:

`pip install -r requirements.txt`

Decompress the checkpoint archive:

`tar -xf checkpoints.tar.xz`

This archive may or may not be included with this software. The full version of this software can be found at <https://nextcloud.fit.vutbr.cz/s/7BfD7H3nsGgFbFs>.

## Running

Activate the virtual environment created in the installation process:

`source venv/bin/activate`

Run the program with your selected options:

`python run.py [-h] -p MODEL_PATH [-g] [-i INPUT_FILE] [-o OUTPUT_FILE] [-f CAMERA] [-n NTH] [-s] [-w] [-t] [-a TRAIN_DATASET] [-b VALIDATION_DATASET] [-l LEARNING_RATE] [-x BATCH_SIZE] [-e EPOCH_COUNT] [-v] -m {FCOS,Faster_R_CNN_MobileNet,Faster_R_CNN_ResNet,RetinaNet,SSD,SSDLite,TramNet}`

The program may be run in either training or evaluation mode. The default is evaluation mode. To switch to training mode, use `-t`. Options `-p/--model_path` and `-m/--model_name` are mandatory regardless of the mode used. `-p/--model_path` must match the chosen `-p/--model_path`; otherwise, undefined behavior might occur. Use `-h/--help` for more information about options.

### Evaluation mode

This mode requires an input and at least one output. Input can be either a video file or a camera. The resulting frames can be output to any combination of a file, a window, or a standard output. The format of the text output is as follows: All detected trams in a given frame are printed on a single line. Each line corresponds to a distinct frame. A detected tram consists of four coordinates, separated by commas, in the following order: `left_top_x`,`left_top_y`,`right_bottom_x`,`right_bottom_y`. Individual trams are separated by spaces. Some functions require OpenCV to be fully operational on your system. If this isn't the case, one or more of them might not work.

### Training mode

It might be useful to train your chosen model on your own data. Use [LabelMe](http://labelme.csail.mit.edu/Release3.0/) to annotate the data. Images are expected to appear along with their respective JSON files. Only annotate the front or back side of the tram. Validation is performed via counting all the detections in the validation dataset. Various parameters of the training session can be set. After each epoch, the model checkpoint is overritten with the new checkpoint.

## Examples

Detect all trams in `../test.mp4` and output the resulting frames to `test.avi` and the standard output. Only process every fifth frame. Use RetinaNet.

```
python run.py --input_file ../test.mp4 \
			--output_file test.avi \
			-s \
			--nth 5 \
			--model_path checkpoints/retina.pth \
			--model_name RetinaNet
```

Train SSD with data from `dataset/tram`. Perform validation with data from `dataset/tram_val`. Use a GPU. Train with batch size 5, epoch count 5, and learning rate of 0.0001.

```
python run.py --train_dataset dataset/tram \
			--validation_dataset dataset/tram_val \
			-tvg \
			--model_path checkpoints/ssd.pth \
			--model_name SSD \
			--batch_size 5 \
			--epoch_count 5 \
			--learning_rate 0.0001
```