From c799751c0cdaf88a06ac4e602641ea86746b1753 Mon Sep 17 00:00:00 2001 From: Nick Herrig Date: Wed, 21 Feb 2024 09:33:19 -0600 Subject: [PATCH 1/4] Add ImageAssets for download --- docs/assets.md | 8 +++- supervision/assets/__init__.py | 2 +- supervision/assets/downloader.py | 22 +++++---- supervision/assets/list.py | 82 +++++++++++++++----------------- 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/docs/assets.md b/docs/assets.md index 7e0d7dffc..d0e8e2d0d 100644 --- a/docs/assets.md +++ b/docs/assets.md @@ -4,7 +4,7 @@ comments: true # Assets -Supervision offers an assets download utility that allows you to download video files +Supervision offers an assets download utility that allows you to download image and video files that you can use in your demos. ## Install extra @@ -29,3 +29,9 @@ as an extra within the Supervision package. :::supervision.assets.list.VideoAssets + +
+

ImageAssets

+
+ +:::supervision.assets.list.ImageAssets diff --git a/supervision/assets/__init__.py b/supervision/assets/__init__.py index 3b76c5aba..b285bfa66 100644 --- a/supervision/assets/__init__.py +++ b/supervision/assets/__init__.py @@ -1,2 +1,2 @@ from supervision.assets.downloader import download_assets -from supervision.assets.list import VideoAssets +from supervision.assets.list import VideoAssets, ImageAssets diff --git a/supervision/assets/downloader.py b/supervision/assets/downloader.py index 8e86359a3..2c5b7ad6a 100644 --- a/supervision/assets/downloader.py +++ b/supervision/assets/downloader.py @@ -4,7 +4,7 @@ from shutil import copyfileobj from typing import Union -from supervision.assets.list import VIDEO_ASSETS, VideoAssets +from supervision.assets.list import Assets, ASSETS, VideoAssets, ImageAssets try: from requests import get @@ -41,12 +41,12 @@ def is_md5_hash_matching(filename: str, original_md5_hash: str) -> bool: return computed_md5_hash.hexdigest() == original_md5_hash -def download_assets(asset_name: Union[VideoAssets, str]) -> str: +def download_assets(asset_name: Union[VideoAssets, ImageAssets, str]) -> str: """ Download a specified asset if it doesn't already exist or is corrupted. Parameters: - asset_name (Union[VideoAssets, str]): The name or type of the asset to be + asset_name (Union[VideoAssets, ImageAssets, str]): The name or type of the asset to be downloaded. Returns: @@ -54,18 +54,21 @@ def download_assets(asset_name: Union[VideoAssets, str]) -> str: Example: ```python - from supervision.assets import download_assets, VideoAssets + from supervision.assets import download_assets, VideoAssets, ImageAssets download_assets(VideoAssets.VEHICLES) "vehicles.mp4" + + download_assets(ImageAssets.PEOPLE_WALKING) + "people-walking.jpg" ``` """ - filename = asset_name.value if isinstance(asset_name, VideoAssets) else asset_name + filename = asset_name.filename if isinstance(asset_name, Assets) else asset_name - if not Path(filename).exists() and filename in VIDEO_ASSETS: + if not Path(filename).exists() and filename in ASSETS: print(f"Downloading {filename} assets \n") - response = get(VIDEO_ASSETS[filename][0], stream=True, allow_redirects=True) + response = get(ASSETS[filename][0], stream=True, allow_redirects=True) response.raise_for_status() file_size = int(response.headers.get("Content-Length", 0)) @@ -79,7 +82,8 @@ def download_assets(asset_name: Union[VideoAssets, str]) -> str: copyfileobj(raw_resp, file) elif Path(filename).exists(): - if not is_md5_hash_matching(filename, VIDEO_ASSETS[filename][1]): + + if not is_md5_hash_matching(filename, ASSETS[filename][1]): print("File corrupted. Re-downloading... \n") os.remove(filename) return download_assets(filename) @@ -87,7 +91,7 @@ def download_assets(asset_name: Union[VideoAssets, str]) -> str: print(f"{filename} asset download complete. \n") else: - valid_assets = ", ".join(asset.value for asset in VideoAssets) + valid_assets = ", ".join(filename for filename in ASSETS.keys()) raise ValueError( f"Invalid asset. It should be one of the following: {valid_assets}." ) diff --git a/supervision/assets/list.py b/supervision/assets/list.py index 83518cdbb..2110f2c42 100644 --- a/supervision/assets/list.py +++ b/supervision/assets/list.py @@ -2,14 +2,19 @@ from typing import Dict, Tuple BASE_VIDEO_URL = "https://media.roboflow.com/supervision/video-examples/" +BASE_IMAGE_URL = "https://media.roboflow.com/inference/" +class Assets(Enum): + def __init__(self, filename: str, hash: str): + self.filename = filename + self.hash = hash -class VideoAssets(Enum): +class VideoAssets(Assets): """ - Each member of this enum represents a video asset. The value associated with each - member is the filename of the video. + Each member of this class represents a video asset. The value associated with each + member has a filename and hash of the video. File names and links can be seen below. - | Enum Member | Video Filename | Video URL | + | Asset | Video Filename | Video URL | |------------------------|----------------------------|---------------------------------------------------------------------------------------| | `VEHICLES` | `vehicles.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/vehicles.mp4) | | `MILK_BOTTLING_PLANT` | `milk-bottling-plant.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/milk-bottling-plant.mp4) | @@ -20,46 +25,35 @@ class VideoAssets(Enum): | `PEOPLE_WALKING` | `people-walking.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/people-walking.mp4) | """ # noqa: E501 // docs - VEHICLES = "vehicles.mp4" - MILK_BOTTLING_PLANT = "milk-bottling-plant.mp4" - VEHICLES_2 = "vehicles-2.mp4" - GROCERY_STORE = "grocery-store.mp4" - SUBWAY = "subway.mp4" - MARKET_SQUARE = "market-square.mp4" - PEOPLE_WALKING = "people-walking.mp4" + VEHICLES = ("vehicles.mp4", "8155ff4e4de08cfa25f39de96483f918") + MILK_BOTTLING_PLANT = ("milk-bottling-plant.mp4", "9e8fb6e883f842a38b3d34267290bdc7") + VEHICLES_2 = ("vehicles-2.mp4", "830af6fba21ffbf14867a7fea595937b") + GROCERY_STORE = ("grocery-store.mp4", "453475750691fb23c56a0cffef089194") + SUBWAY = ("subway.mp4", "453475750691fb23c56a0cffef089194") + MARKET_SQUARE = ("market-square.mp4", "859179bf4a21f80a8baabfdb2ed716dc") + PEOPLE_WALKING = ("people-walking.mp4", "0574c053c8686c3f1dc0aa3743e45cb9") - @classmethod - def list(cls): - return list(map(lambda c: c.value, cls)) +class ImageAssets(Assets): + """ + Each member of this enum represents a image asset. The value associated with each + member is the filename of the image. + + | Asset | Image Filename | Video URL | + |------------------------|----------------------------|---------------------------------------------------------------------------------------| + | `PEOPLE_WALKING` | `people-walking.jpg` | [Link](https://media.roboflow.com/inference/people-walking.jpg) | + + """ # noqa: E501 // docs + + PEOPLE_WALKING = ("people-walking.jpg", "e6bda00b47f2908eeae7df86ef995dcd") -VIDEO_ASSETS: Dict[str, Tuple[str, str]] = { - VideoAssets.VEHICLES.value: ( - f"{BASE_VIDEO_URL}{VideoAssets.VEHICLES.value}", - "8155ff4e4de08cfa25f39de96483f918", - ), - VideoAssets.VEHICLES_2.value: ( - f"{BASE_VIDEO_URL}{VideoAssets.VEHICLES_2.value}", - "830af6fba21ffbf14867a7fea595937b", - ), - VideoAssets.MILK_BOTTLING_PLANT.value: ( - f"{BASE_VIDEO_URL}{VideoAssets.MILK_BOTTLING_PLANT.value}", - "9e8fb6e883f842a38b3d34267290bdc7", - ), - VideoAssets.GROCERY_STORE.value: ( - f"{BASE_VIDEO_URL}{VideoAssets.GROCERY_STORE.value}", - "11402e7b861c1980527d3d74cbe3b366", - ), - VideoAssets.SUBWAY.value: ( - f"{BASE_VIDEO_URL}{VideoAssets.SUBWAY.value}", - "453475750691fb23c56a0cffef089194", - ), - VideoAssets.MARKET_SQUARE.value: ( - f"{BASE_VIDEO_URL}{VideoAssets.MARKET_SQUARE.value}", - "859179bf4a21f80a8baabfdb2ed716dc", - ), - VideoAssets.PEOPLE_WALKING.value: ( - f"{BASE_VIDEO_URL}{VideoAssets.PEOPLE_WALKING.value}", - "0574c053c8686c3f1dc0aa3743e45cb9", - ), -} +ASSETS: Dict[str, Tuple[str, str]] = { + **{ + asset.value[0]: (f"{BASE_VIDEO_URL}{asset.value[0]}", asset.value[1]) + for asset in VideoAssets + }, + **{ + asset.value[0]: (f"{BASE_IMAGE_URL}{asset.value[0]}", asset.value[1]) + for asset in ImageAssets + }, +} \ No newline at end of file From 29cd88ffdb8b138e2dbaeef41dbfe4cea6d6e9a6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:40:21 +0000 Subject: [PATCH 2/4] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto=20?= =?UTF-8?q?format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/assets/__init__.py | 2 +- supervision/assets/downloader.py | 3 +-- supervision/assets/list.py | 12 +++++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/supervision/assets/__init__.py b/supervision/assets/__init__.py index b285bfa66..31f070d7f 100644 --- a/supervision/assets/__init__.py +++ b/supervision/assets/__init__.py @@ -1,2 +1,2 @@ from supervision.assets.downloader import download_assets -from supervision.assets.list import VideoAssets, ImageAssets +from supervision.assets.list import ImageAssets, VideoAssets diff --git a/supervision/assets/downloader.py b/supervision/assets/downloader.py index 2c5b7ad6a..aefa3daae 100644 --- a/supervision/assets/downloader.py +++ b/supervision/assets/downloader.py @@ -4,7 +4,7 @@ from shutil import copyfileobj from typing import Union -from supervision.assets.list import Assets, ASSETS, VideoAssets, ImageAssets +from supervision.assets.list import ASSETS, Assets, ImageAssets, VideoAssets try: from requests import get @@ -82,7 +82,6 @@ def download_assets(asset_name: Union[VideoAssets, ImageAssets, str]) -> str: copyfileobj(raw_resp, file) elif Path(filename).exists(): - if not is_md5_hash_matching(filename, ASSETS[filename][1]): print("File corrupted. Re-downloading... \n") os.remove(filename) diff --git a/supervision/assets/list.py b/supervision/assets/list.py index 2110f2c42..de56afb58 100644 --- a/supervision/assets/list.py +++ b/supervision/assets/list.py @@ -4,15 +4,17 @@ BASE_VIDEO_URL = "https://media.roboflow.com/supervision/video-examples/" BASE_IMAGE_URL = "https://media.roboflow.com/inference/" + class Assets(Enum): def __init__(self, filename: str, hash: str): self.filename = filename self.hash = hash + class VideoAssets(Assets): """ Each member of this class represents a video asset. The value associated with each - member has a filename and hash of the video. File names and links can be seen below. + member has a filename and hash of the video. File names and links can be seen below. | Asset | Video Filename | Video URL | |------------------------|----------------------------|---------------------------------------------------------------------------------------| @@ -26,13 +28,17 @@ class VideoAssets(Assets): """ # noqa: E501 // docs VEHICLES = ("vehicles.mp4", "8155ff4e4de08cfa25f39de96483f918") - MILK_BOTTLING_PLANT = ("milk-bottling-plant.mp4", "9e8fb6e883f842a38b3d34267290bdc7") + MILK_BOTTLING_PLANT = ( + "milk-bottling-plant.mp4", + "9e8fb6e883f842a38b3d34267290bdc7", + ) VEHICLES_2 = ("vehicles-2.mp4", "830af6fba21ffbf14867a7fea595937b") GROCERY_STORE = ("grocery-store.mp4", "453475750691fb23c56a0cffef089194") SUBWAY = ("subway.mp4", "453475750691fb23c56a0cffef089194") MARKET_SQUARE = ("market-square.mp4", "859179bf4a21f80a8baabfdb2ed716dc") PEOPLE_WALKING = ("people-walking.mp4", "0574c053c8686c3f1dc0aa3743e45cb9") + class ImageAssets(Assets): """ Each member of this enum represents a image asset. The value associated with each @@ -56,4 +62,4 @@ class ImageAssets(Assets): asset.value[0]: (f"{BASE_IMAGE_URL}{asset.value[0]}", asset.value[1]) for asset in ImageAssets }, -} \ No newline at end of file +} From 8aac5e8e815e86c0fe5d78d03a738ed5c1f79683 Mon Sep 17 00:00:00 2001 From: Nick Herrig Date: Wed, 21 Feb 2024 21:53:48 -0600 Subject: [PATCH 3/4] Update directory for consistency with video assets directory and add soccer image --- supervision/assets/list.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/supervision/assets/list.py b/supervision/assets/list.py index de56afb58..55b32f544 100644 --- a/supervision/assets/list.py +++ b/supervision/assets/list.py @@ -2,7 +2,7 @@ from typing import Dict, Tuple BASE_VIDEO_URL = "https://media.roboflow.com/supervision/video-examples/" -BASE_IMAGE_URL = "https://media.roboflow.com/inference/" +BASE_IMAGE_URL = "https://media.roboflow.com/supervision/image-examples/" class Assets(Enum): @@ -44,13 +44,15 @@ class ImageAssets(Assets): Each member of this enum represents a image asset. The value associated with each member is the filename of the image. - | Asset | Image Filename | Video URL | - |------------------------|----------------------------|---------------------------------------------------------------------------------------| - | `PEOPLE_WALKING` | `people-walking.jpg` | [Link](https://media.roboflow.com/inference/people-walking.jpg) | + | Asset | Image Filename | Video URL | + |--------------------|------------------------|---------------------------------------------------------------------------------------| + | `PEOPLE_WALKING` | `people-walking.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/people-walking.jpg) | + | `SOCCER` | `soccer.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/soccer.jpg) | """ # noqa: E501 // docs PEOPLE_WALKING = ("people-walking.jpg", "e6bda00b47f2908eeae7df86ef995dcd") + SOCCER = ("soccer.jpg", "0f5a4b98abf3e3973faf9e9260a7d876") ASSETS: Dict[str, Tuple[str, str]] = { From d048e45d4b8c6c6a6ec69170a729d7ee0636912f Mon Sep 17 00:00:00 2001 From: Nick Herrig Date: Wed, 21 Feb 2024 21:56:36 -0600 Subject: [PATCH 4/4] Fix unaligned table --- supervision/assets/list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/supervision/assets/list.py b/supervision/assets/list.py index 55b32f544..94d24ea4a 100644 --- a/supervision/assets/list.py +++ b/supervision/assets/list.py @@ -46,8 +46,8 @@ class ImageAssets(Assets): | Asset | Image Filename | Video URL | |--------------------|------------------------|---------------------------------------------------------------------------------------| - | `PEOPLE_WALKING` | `people-walking.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/people-walking.jpg) | - | `SOCCER` | `soccer.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/soccer.jpg) | + | `PEOPLE_WALKING` | `people-walking.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/people-walking.jpg) | + | `SOCCER` | `soccer.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/soccer.jpg) | """ # noqa: E501 // docs