Skip to content

Commit

Permalink
Merge branch 'main' into mmdet_tensorrt_support
Browse files Browse the repository at this point in the history
  • Loading branch information
fcakyon authored Nov 22, 2024
2 parents d774316 + 8d9c892 commit e610e23
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 907 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,6 @@ jobs:
run: >
pip install ultralytics==8.0.207
- name: Install super-gradients(3.3.1)
run: >
pip install super-gradients==3.3.1
- name: Unittest for SAHI+YOLOV5/MMDET/Detectron2 on all platforms
run: |
python -m unittest
Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/package_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,6 @@ jobs:
run: >
pip install ultralytics==8.0.207
- name: Install super-gradients(3.3.1)
run: >
pip install super-gradients==3.3.1
- name: Install latest SAHI package
run: >
pip install --upgrade --force-reinstall sahi
Expand Down
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ Object detection and instance segmentation are by far the most important applica

| Command | Description |
|---|---|
| [predict](https://github.com/obss/sahi/blob/main/docs/cli.md#predict-command-usage) | perform sliced/standard video/image prediction using any [yolov5](https://github.com/ultralytics/yolov5)/[mmdet](https://github.com/open-mmlab/mmdetection)/[detectron2](https://github.com/facebookresearch/detectron2)/[huggingface](https://huggingface.co/models?pipeline_tag=object-detection&sort=downloads) model |
| [predict-fiftyone](https://github.com/obss/sahi/blob/main/docs/cli.md#predict-fiftyone-command-usage) | perform sliced/standard prediction using any [yolov5](https://github.com/ultralytics/yolov5)/[mmdet](https://github.com/open-mmlab/mmdetection)/[detectron2](https://github.com/facebookresearch/detectron2)/[huggingface](https://huggingface.co/models?pipeline_tag=object-detection&sort=downloads) model and explore results in [fiftyone app](https://github.com/voxel51/fiftyone) |
| [predict](https://github.com/obss/sahi/blob/main/docs/cli.md#predict-command-usage) | perform sliced/standard video/image prediction using any [ultralytics](https://github.com/ultralytics/ultralytics)/[mmdet](https://github.com/open-mmlab/mmdetection)/[detectron2](https://github.com/facebookresearch/detectron2)/[huggingface](https://huggingface.co/models?pipeline_tag=object-detection&sort=downloads)/[torchvision](https://pytorch.org/vision/stable/models.html#object-detection) model |
| [predict-fiftyone](https://github.com/obss/sahi/blob/main/docs/cli.md#predict-fiftyone-command-usage) | perform sliced/standard prediction using any [ultralytics](https://github.com/ultralytics/ultralytics)/[mmdet](https://github.com/open-mmlab/mmdetection)/[detectron2](https://github.com/facebookresearch/detectron2)/[huggingface](https://huggingface.co/models?pipeline_tag=object-detection&sort=downloads)/[torchvision](https://pytorch.org/vision/stable/models.html#object-detection) model and explore results in [fiftyone app](https://github.com/voxel51/fiftyone) |
| [coco slice](https://github.com/obss/sahi/blob/main/docs/cli.md#coco-slice-command-usage) | automatically slice COCO annotation and image files |
| [coco fiftyone](https://github.com/obss/sahi/blob/main/docs/cli.md#coco-fiftyone-command-usage) | explore multiple prediction results on your COCO dataset with [fiftyone ui](https://github.com/voxel51/fiftyone) ordered by number of misdetections |
| [coco evaluate](https://github.com/obss/sahi/blob/main/docs/cli.md#coco-evaluate-command-usage) | evaluate classwise COCO AP and AR for given predictions and ground truth |
| [coco analyse](https://github.com/obss/sahi/blob/main/docs/cli.md#coco-analyse-command-usage) | calculate and export many error analysis plots |
| [coco yolov5](https://github.com/obss/sahi/blob/main/docs/cli.md#coco-yolov5-command-usage) | automatically convert any COCO dataset to [yolov5](https://github.com/ultralytics/yolov5) format |
| [coco yolov5](https://github.com/obss/sahi/blob/main/docs/cli.md#coco-yolov5-command-usage) | automatically convert any COCO dataset to [ultralytics](https://github.com/ultralytics/ultralytics) format |

## <div align="center">Quick Start Examples</div>

[📜 List of publications that cite SAHI (currently 150+)](https://scholar.google.com/scholar?hl=en&as_sdt=2005&sciodt=0,5&cites=14065474760484865747&scipsc=&q=&scisbd=1)
[📜 List of publications that cite SAHI (currently 200+)](https://scholar.google.com/scholar?hl=en&as_sdt=2005&sciodt=0,5&cites=14065474760484865747&scipsc=&q=&scisbd=1)

[🏆 List of competition winners that used SAHI](https://github.com/obss/sahi/discussions/688)

Expand Down Expand Up @@ -80,9 +80,7 @@ Object detection and instance segmentation are by far the most important applica

- `RT-DETR` + `SAHI` walkthrough: <a href="https://colab.research.google.com/github/obss/sahi/blob/main/demo/inference_for_rtdetr.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="sahi-rtdetr"></a> (NEW)

- `YOLOv8` + `SAHI` walkthrough: <a href="https://colab.research.google.com/github/obss/sahi/blob/main/demo/inference_for_yolov8.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="sahi-yolov8"></a> (NEW)

- `SuperGradients/YOLONAS` + `SAHI`: <a href="https://colab.research.google.com/github/obss/sahi/blob/main/demo/inference_for_yolonas.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="sahi-yolonas"></a> (NEW)
- `YOLOv8` + `SAHI` walkthrough: <a href="https://colab.research.google.com/github/obss/sahi/blob/main/demo/inference_for_yolov8.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="sahi-yolov8"></a>

- `DeepSparse` + `SAHI` walkthrough: <a href="https://colab.research.google.com/github/obss/sahi/blob/main/demo/inference_for_sparse_yolov5.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="sahi-deepsparse"></a>

Expand Down
713 changes: 0 additions & 713 deletions demo/inference_for_yolonas.ipynb

This file was deleted.

6 changes: 3 additions & 3 deletions sahi/models/detectron2.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ def _create_object_prediction_list_from_original_predictions(
object_prediction_list = [
ObjectPrediction(
bbox=box.tolist() if mask is None else None,
segmentation=get_coco_segmentation_from_bool_mask(mask.detach().cpu().numpy())
if mask is not None
else None,
segmentation=(
get_coco_segmentation_from_bool_mask(mask.detach().cpu().numpy()) if mask is not None else None
),
category_id=category_id.item(),
category_name=self.category_mapping[str(category_id.item())],
shift_amount=shift_amount,
Expand Down
21 changes: 0 additions & 21 deletions sahi/utils/coco.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,28 +224,7 @@ def __init__(
self._shapely_annotation = shapely_annotation

def get_sliced_coco_annotation(self, slice_bbox: List[int]):
def filter_polygons(geometry):
"""
Filters out and returns only Polygon or MultiPolygon components of a geometry.
If geometry is a Polygon, it converts it into a MultiPolygon.
If it's a GeometryCollection, it filters to create a MultiPolygon from any Polygons in the collection.
Returns an empty MultiPolygon if no Polygon or MultiPolygon components are found.
"""
if isinstance(geometry, Polygon):
return MultiPolygon([geometry])
elif isinstance(geometry, MultiPolygon):
return geometry
elif isinstance(geometry, GeometryCollection):
polygons = [geom for geom in geometry.geoms if isinstance(geom, Polygon)]
return MultiPolygon(polygons) if polygons else MultiPolygon()
return MultiPolygon()

shapely_polygon = box(slice_bbox[0], slice_bbox[1], slice_bbox[2], slice_bbox[3])
samp = self._shapely_annotation.multipolygon
if not samp.is_valid:
valid = make_valid(samp)
valid = filter_polygons(valid)
self._shapely_annotation.multipolygon = valid
intersection_shapely_annotation = self._shapely_annotation.get_intersection(shapely_polygon)
return CocoAnnotation.from_shapely_annotation(
intersection_shapely_annotation,
Expand Down
26 changes: 24 additions & 2 deletions sahi/utils/shapely.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

from typing import List

from shapely.geometry import CAP_STYLE, JOIN_STYLE, MultiPolygon, Polygon, box
from shapely.geometry import CAP_STYLE, JOIN_STYLE, GeometryCollection, MultiPolygon, Polygon, box
from shapely.validation import make_valid


def get_shapely_box(x: int, y: int, width: int, height: int) -> Polygon:
Expand All @@ -21,15 +22,36 @@ def get_shapely_box(x: int, y: int, width: int, height: int) -> Polygon:

def get_shapely_multipolygon(coco_segmentation: List[List]) -> MultiPolygon:
"""
Accepts coco style polygon coords and converts it to shapely multipolygon object
Accepts coco style polygon coords and converts it to valid shapely multipolygon object
"""

def filter_polygons(geometry):
"""
Filters out and returns only Polygon or MultiPolygon components of a geometry.
If geometry is a Polygon, it converts it into a MultiPolygon.
If it's a GeometryCollection, it filters
to create a MultiPolygon from any Polygons in the collection.
Returns an empty MultiPolygon if no Polygon or MultiPolygon components are found.
"""
if isinstance(geometry, Polygon):
return MultiPolygon([geometry])
elif isinstance(geometry, MultiPolygon):
return geometry
elif isinstance(geometry, GeometryCollection):
polygons = [geom for geom in geometry.geoms if isinstance(geom, Polygon)]
return MultiPolygon(polygons) if polygons else MultiPolygon()
return MultiPolygon()

polygon_list = []
for coco_polygon in coco_segmentation:
point_list = list(zip(coco_polygon[0::2], coco_polygon[1::2]))
shapely_polygon = Polygon(point_list)
polygon_list.append(shapely_polygon)
shapely_multipolygon = MultiPolygon(polygon_list)

if not shapely_multipolygon.is_valid:
shapely_multipolygon = filter_polygons(make_valid(shapely_multipolygon))

return shapely_multipolygon


Expand Down
6 changes: 6 additions & 0 deletions tests/test_shapelyutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ def test_get_shapely_multipolygon(self):
self.assertEqual(shapely_multipolygon.area, 41177.5)
self.assertTupleEqual(shapely_multipolygon.bounds, (1, 1, 325, 200))

def test_get_shapely_multipolygon_naughty(self):
# self-intersection case
coco_segmentation = [[3559.0, 2046.86, 3.49, 2060.0, 3540.9, 3249.7, 2060.0, 3239.61, 2052.87]]
shapely_multipolygon = get_shapely_multipolygon(coco_segmentation)
self.assertTrue(shapely_multipolygon.is_valid)

def test_shapely_annotation(self):
# init shapely_annotation from coco segmentation
segmentation = [[1, 1, 325, 125.2, 250, 200, 5, 200]]
Expand Down
153 changes: 0 additions & 153 deletions tests/test_yolonasmodel.py

This file was deleted.

0 comments on commit e610e23

Please sign in to comment.