Skip to content

Commit

Permalink
add coco subsampling, update docs, update tests (#46)
Browse files Browse the repository at this point in the history
* add coco subsampling method

* update docs

* update deprecated np.bool

* update test_utils to utils

* update mmdet test config
  • Loading branch information
fcakyon authored Apr 27, 2021
1 parent e7cd79b commit 166c0e6
Show file tree
Hide file tree
Showing 25 changed files with 49,595 additions and 582 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,20 @@ jobs:
run: >
pip install -e .
- name: Test SAHI scripts for mmdet < 2.9.0
- name: Test SAHI scripts for mmdet <= 2.8.0
if: matrix.mmdet-version == '2.8.0'
run: |
# predict
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v280.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v280.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v280.py
- name: Test SAHI scripts for mmdet => 2.9.0
- name: Test SAHI scripts for mmdet > 2.8.0
if: matrix.mmdet-version == '2.11.0'
run: |
# predict
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v290.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v290.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v290.py
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
# coco2yolov5
python scripts/coco2yolov5.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --train_split 0.9
16 changes: 8 additions & 8 deletions .github/workflows/package_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,20 @@ jobs:
pip install pytest
python -m unittest
- name: Test SAHI scripts for mmdet < 2.9.0
- name: Test SAHI scripts for mmdet <= 2.8.0
if: matrix.mmdet-version == '2.8.0'
run: |
# predict
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v280.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v280.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v280.py
- name: Test SAHI scripts for mmdet => 2.9.0
- name: Test SAHI scripts for mmdet > 2.8.0
if: matrix.mmdet-version == '2.11.0'
run: |
# predict
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v290.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v290.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco_v290.py
python scripts/predict.py --source tests/data/ --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/terrain1.jpg --novisual --pickle --crop --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
python scripts/predict.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --model_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_2x_coco_20200131-fdb43119.pth --config_path tests/data/models/mmdet_retinanet/retinanet_r50_fpn_1x_coco.py
# coco2yolov5
python scripts/coco2yolov5.py --source tests/data/coco_utils/ --coco_file tests/data/coco_utils/combined_coco.json --train_split 0.9
65 changes: 0 additions & 65 deletions COCO.md

This file was deleted.

48 changes: 4 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,53 +94,13 @@ coco_dict, coco_path = slice_coco(
)
```

### `predict.py` script usage:
## Scripts

```bash
python scripts/predict.py --source image/file/or/folder --model_path path/to/model --config_path path/to/config
```

will perform sliced inference on default parameters and export the prediction visuals to runs/predict/exp folder.

You can specify sliced inference parameters as:

```bash
python scripts/predict.py --slice_width 256 --slice_height 256 --overlap_height_ratio 0.1 --overlap_width_ratio 0.1 --iou_thresh 0.25 --source image/file/or/folder --model_path path/to/model --config_path path/to/config
```

If you want to export prediction pickles and cropped predictions add `--pickle` and `--crop` arguments. If you want to change crop extension type, set it as `--visual_export_format JPG`.

If you want to perform standard prediction instead of sliced prediction, add `--standard_pred` argument.

```bash
python scripts/predict.py --coco_file path/to/coco/file --source coco/images/directory --model_path path/to/model --config_path path/to/config
```

will perform inference using provided coco file, then export results as a coco json file to runs/predict/exp/results.json

If you don't want to export prediction visuals, add `--novisual` argument.

### `coco2yolov5.py` script usage:

```bash
python scripts/coco2yolov5.py --coco_file path/to/coco/file --source coco/images/directory --train_split 0.9
```

will convert given coco dataset to yolov5 format and export to runs/coco2yolov5/exp folder.

### `coco_error_analysis.py` script usage:

```bash
python scripts/coco_error_analysis.py results.json output/folder/directory --ann coco/annotation/path
```

will calculate coco error plots and export them to given output folder directory.

If you want to specify mAP result type, set it as `--types bbox mask`.
Find detailed info on script usage (predict, coco2yolov5, coco_error_analysis) at [SCRIPTS.md](docs/SCRIPTS.md).

If you want to export extra mAP bar plots and annotation area stats add `--extraplots` argument.
## COCO Utilities

If you want to specify area regions, set it as `--areas 1024 9216 10000000000`.
Find detailed info on COCO utilities (yolov5 conversion, slicing, subsampling, merging, splitting) at [COCO.md](docs/COCO.md).

## Adding new detection framework support

Expand Down
8 changes: 4 additions & 4 deletions demo/inference.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"outputs": [],
"source": [
"# arrange an instance segmentation model for test\n",
"from tests.test_utils import (\n",
"from tests.utils import (\n",
" download_mmdet_cascade_mask_rcnn_model,\n",
" MmdetTestConstants\n",
")\n",
Expand Down Expand Up @@ -453,9 +453,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python3.8 (coco-slicing)",
"display_name": "Python3.8 (sahi)",
"language": "python",
"name": "coco-slicing"
"name": "sahi"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -467,7 +467,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.6"
"version": "3.8.8"
}
},
"nbformat": 4,
Expand Down
156 changes: 156 additions & 0 deletions docs/COCO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# COCO Utilities

## COCO dataset creation steps:

- import required classes:

```python
from sahi.utils.coco import Coco, CocoCategory, CocoImage, CocoAnnotation
```

- init Coco object:

```python
coco = Coco()
```

- add categories starting from id 0:

```python
coco.add_category(CocoCategory(id=0, name='human'))
coco.add_category(CocoCategory(id=1, name='vehicle'))
```

- create a coco image:

```python
coco_image = CocoImage(file_name="image1.jpg", height=1080, width=1920)
```

- add annotations to coco image:

```python
coco_image.add_annotation(
CocoAnnotation(
bbox=[x_min, y_min, width, height],
category_id=0,
category_name='human'
)
)
coco_image.add_annotation(
CocoAnnotation(
bbox=[x_min, y_min, width, height],
category_id=1,
category_name='vehicle'
)
)
```

- add coco image to Coco object:

```python
coco.add_image(coco_image)
```

- after adding all images, convert coco object to coco json:

```python
coco_json = coco.json
```

- you can export it as json file:

```python
from sahi.utils.file import save_json

save_json(coco_json, "coco_dataset.json")
```

## Slice COCO dataset images and annotations into grids:

```python
from sahi.slicing import slice_coco

coco_dict, coco_path = slice_coco(
coco_annotation_file_path="coco.json",
image_dir="source/coco/image/dir",
slice_height=256,
slice_width=256,
overlap_height_ratio=0.2,
overlap_width_ratio=0.2,
)
```

## Split COCO dataset into train/val:

```python
from sahi.utils.coco import Coco

# specify coco dataset path
coco_path = "coco.json"

# init Coco object
coco = Coco.from_coco_dict_or_path(coco_path)

# split and export COCO dataset into given target_dir with a 85% train/15% val split
coco.split_coco_as_train_val(
file_name="splitted_coco",
target_dir="output/folder/dir",
train_split_rate=0.85
)
```

## Combine COCO dataset files:

```python
from sahi.utils.coco import Coco
from sahi.utils.file import save_json

# specify coco dataset json paths
coco_path_1 = "coco1.json"
coco_path_2 = "coco2.json"
coco_path_3 = "coco3.json"

# init Coco object with a list of Coco path
combined_coco = Coco.from_coco_dict_or_path([coco_path_1, coco_path_2, coco_path_3])

# export combined COCO dataset
save_json(combined_coco.json, "combined_coco.json")
```

## Convert COCO dataset to ultralytics/yolov5 format:

```python
from sahi.utils.coco import Coco

# specify coco dataset path
coco_path = "coco.json"

# init Coco object
coco = Coco.from_coco_dict_or_path(coco_path)

# export converted YoloV5 formatted dataset into given output_dir with a 85% train/15% val split
coco.export_as_yolov5(
image_dir="source/coco/image/dir",
output_dir="output/folder/dir",
train_split_rate=0.85
)
```

## Subsample COCO dataset file:

```python
from sahi.utils.coco import Coco

# specify coco dataset path
coco_path = "coco.json"

# init Coco object
coco = Coco.from_coco_dict_or_path(coco_path)

# create a Coco object with 1/10 of total images
subsampled_coco = coco.get_subsampled_coco(subsample_ratio=10)

# export subsampled COCO dataset
save_json(subsampled_coco.json, "subsampled_coco.json")
```
Loading

0 comments on commit 166c0e6

Please sign in to comment.