From 408a7c99bbf6465bf50fdff8926c60f400690c64 Mon Sep 17 00:00:00 2001 From: yihong1120 Date: Tue, 8 Oct 2024 23:39:13 +0800 Subject: [PATCH] Upgrade from YOLOv8 to YOLO11 --- README-zh-tw.md | 32 ++--- README.md | 28 ++-- .../README-zh-tw.md | 4 +- .../README.md | 4 +- .../__init__.py | 0 .../data_augmentation.py | 2 +- .../data_augmentation_albumentations.py | 18 +-- .../visualise_bounding_boxes.py | 0 .../README-zh-tw.md | 14 +- .../README.md | 14 +- .../__init__.py | 0 .../convert_yolo_to_coco.py | 4 +- .../evaluate_sahi_yolo.py} | 4 +- .../evaluate_yolo.py} | 6 +- .../README-zh-tw.md | 16 +-- .../README.md | 16 +-- .../__init__.py | 0 .../app.py | 0 .../auth.py | 0 .../cache.py | 0 .../config.py | 0 .../detection.py | 14 +- .../model_downloader.py | 2 +- .../models.py | 4 +- .../security.py | 0 .../README-zh-tw.md | 10 +- .../{YOLOv8_train => YOLO_train}/README.md | 10 +- .../{YOLOv8_train => YOLO_train}/__init__.py | 0 .../{YOLOv8_train => YOLO_train}/train.py | 16 +-- .../run_augmentation_and_move.sh | 41 ------ .../user_manual_marp.md | 103 -------------- .../YOLOv8_evaluation/user_manual_marp.md | 91 ------------ examples/YOLOv8_train/train_yolo_models.sh | 36 ----- examples/YOLOv8_train/user_manual_marp.md | 91 ------------ requirements.txt | 8 +- src/README-zh-tw.md | 77 ++++++++++ src/README.md | 77 ++++++++++ .../__init__.py | 0 .../data_augmentation_albumentations_test.py | 24 ++-- .../data_augmentation_test.py | 134 +++++++++--------- .../visualise_bounding_boxes_test.py | 24 ++-- .../__init__.py | 0 .../convert_yolo_to_coco_test.py | 14 +- .../evaluate_sahi_yolo_test.py} | 16 +-- .../evaluate_yolo_test.py} | 8 +- .../__init__.py | 0 .../auth_test.py | 20 +-- .../cache_test.py | 2 +- .../config_test.py | 2 +- .../detection_test.py | 16 +-- .../model_downloader_test.py | 24 ++-- .../models_test.py | 16 +-- .../security_test.py | 4 +- .../{YOLOv8_train => YOLO_train}/__init__.py | 0 .../train_test.py | 48 +++---- 55 files changed, 446 insertions(+), 648 deletions(-) rename examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/README-zh-tw.md (90%) rename examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/README.md (90%) rename examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/__init__.py (100%) rename examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/data_augmentation.py (99%) rename examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/data_augmentation_albumentations.py (96%) rename examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/visualise_bounding_boxes.py (100%) rename examples/{YOLOv8_evaluation => YOLO_evaluation}/README-zh-tw.md (66%) rename examples/{YOLOv8_evaluation => YOLO_evaluation}/README.md (69%) rename examples/{YOLOv8_evaluation => YOLO_evaluation}/__init__.py (100%) rename examples/{YOLOv8_evaluation => YOLO_evaluation}/convert_yolo_to_coco.py (98%) rename examples/{YOLOv8_evaluation/evaluate_sahi_yolov8.py => YOLO_evaluation/evaluate_sahi_yolo.py} (98%) rename examples/{YOLOv8_evaluation/evaluate_yolov8.py => YOLO_evaluation/evaluate_yolo.py} (94%) rename examples/{YOLOv8_server_api => YOLO_server_api}/README-zh-tw.md (74%) rename examples/{YOLOv8_server_api => YOLO_server_api}/README.md (81%) rename examples/{YOLOv8_server_api => YOLO_server_api}/__init__.py (100%) rename examples/{YOLOv8_server_api => YOLO_server_api}/app.py (100%) rename examples/{YOLOv8_server_api => YOLO_server_api}/auth.py (100%) rename examples/{YOLOv8_server_api => YOLO_server_api}/cache.py (100%) rename examples/{YOLOv8_server_api => YOLO_server_api}/config.py (100%) rename examples/{YOLOv8_server_api => YOLO_server_api}/detection.py (96%) rename examples/{YOLOv8_server_api => YOLO_server_api}/model_downloader.py (98%) rename examples/{YOLOv8_server_api => YOLO_server_api}/models.py (98%) rename examples/{YOLOv8_server_api => YOLO_server_api}/security.py (100%) rename examples/{YOLOv8_train => YOLO_train}/README-zh-tw.md (77%) rename examples/{YOLOv8_train => YOLO_train}/README.md (77%) rename examples/{YOLOv8_train => YOLO_train}/__init__.py (100%) rename examples/{YOLOv8_train => YOLO_train}/train.py (96%) delete mode 100644 examples/YOLOv8_data_augmentation/run_augmentation_and_move.sh delete mode 100644 examples/YOLOv8_data_augmentation/user_manual_marp.md delete mode 100644 examples/YOLOv8_evaluation/user_manual_marp.md delete mode 100644 examples/YOLOv8_train/train_yolo_models.sh delete mode 100644 examples/YOLOv8_train/user_manual_marp.md create mode 100644 src/README-zh-tw.md create mode 100644 src/README.md rename tests/examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/__init__.py (100%) rename tests/examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/data_augmentation_albumentations_test.py (89%) rename tests/examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/data_augmentation_test.py (78%) rename tests/examples/{YOLOv8_data_augmentation => YOLO_data_augmentation}/visualise_bounding_boxes_test.py (88%) rename tests/examples/{YOLOv8_evaluation => YOLO_evaluation}/__init__.py (100%) rename tests/examples/{YOLOv8_evaluation => YOLO_evaluation}/convert_yolo_to_coco_test.py (92%) rename tests/examples/{YOLOv8_evaluation/evaluate_sahi_yolov8_test.py => YOLO_evaluation/evaluate_sahi_yolo_test.py} (89%) rename tests/examples/{YOLOv8_evaluation/evaluate_yolov8_test.py => YOLO_evaluation/evaluate_yolo_test.py} (90%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/__init__.py (100%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/auth_test.py (92%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/cache_test.py (96%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/config_test.py (98%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/detection_test.py (90%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/model_downloader_test.py (82%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/models_test.py (93%) rename tests/examples/{YOLOv8_server_api => YOLO_server_api}/security_test.py (89%) rename tests/examples/{YOLOv8_train => YOLO_train}/__init__.py (100%) rename tests/examples/{YOLOv8_train => YOLO_train}/train_test.py (92%) diff --git a/README-zh-tw.md b/README-zh-tw.md index 9d0a6a6..37a6cd9 100644 --- a/README-zh-tw.md +++ b/README-zh-tw.md @@ -3,12 +3,12 @@ AI-Driven Construction Safety Banner
- 模型伺服器 | + 模型伺服器 | 串流網頁 | 用戶管理 | - YOLOv8 數據增強 | - YOLOv8 評估 | - YOLOv8 訓練 + YOLO 數據增強 | + YOLO 評估 | + YOLO 訓練

@@ -18,7 +18,7 @@ Python 3.12.7 - YOLOv8 + YOLO11 HDBSCAN sklearn @@ -39,7 +39,7 @@
-"建築工地危險檢測系統" 是一款以人工智慧驅動的工具,旨在提升工地的安全性。該系統利用 YOLOv8 模型進行物件偵測,能夠識別以下潛在危險: +"建築工地危險檢測系統" 是一款以人工智慧驅動的工具,旨在提升工地的安全性。該系統利用 YOLO 模型進行物件偵測,能夠識別以下潛在危險: - 未佩戴安全帽的工人 - 未穿著安全背心的工人 @@ -60,7 +60,7 @@ 多語言支援使該系統在全球範圍內的使用者都能方便使用,提升了不同地區的可用性。 -> **待辦事項**:新增對 WhatsApp 通知的支援。 +> **待辦事項**:新增對 WhatsApp 通知的支援,從YOLOv8轉換至YOLO11

@@ -114,14 +114,14 @@ - video_url: "rtsp://example1.com/stream" # 視頻的 URL image_name: "cam1" # 圖像的名稱 label: "label1" # 視頻的標籤 - model_key: "yolov8n" # 視頻使用的模型鍵 + model_key: "yolo11n" # 視頻使用的模型鍵 line_token: "token1" # 用於通知的 Line Token run_local: True # 本地運行物件檢測 language: "en" # 將語言設置成英文 - video_url: "rtsp://example2.com/stream" image_name: "cam2" label: "label2" - model_key: "yolov8n" + model_key: "yolo11n" line_token: "token2" run_local: True language: "zh-TW" @@ -213,7 +213,7 @@ 6. 要運行物體檢測 API,使用以下命令: ```bash - gunicorn -w 1 -b 0.0.0.0:8001 "examples.YOLOv8_server_api.app:YOLOv8-server-api-app" + gunicorn -w 1 -b 0.0.0.0:8001 "examples.YOLO_server_api.app:YOLO-server-api-app" ``` 7. 使用特定的配置文件運行主應用程序,使用以下命令: @@ -260,11 +260,11 @@ | Model | size
(pixels) | mAPval
50 | mAPval
50-95 | params
(M) | FLOPs
(B) | | ------- | --------------------- | ------------------ | ------------------ | ----------------- | ----------------- | - | YOLOv8n | 640 | 59.3 | 35.0 | 3.2 | 8.7 | - | YOLOv8s | 640 | 73.1 | 47.6 | 11.2 | 28.6 | - | YOLOv8m | 640 | 76.8 | 53.9 | 25.9 | 78.9 | - | YOLOv8l | 640 | // | // | 43.7 | 165.2 | - | YOLOv8x | 640 | 82.9 | 60.9 | 68.2 | 257.8 | + | YOLO11n | 640 | 54.1 | 31.0 | 2.6 | 6.5 | + | YOLO11s | 640 | // | // | 9.4 | 21.6 | + | YOLO11m | 640 | // | // | 20.1 | 68.0 | + | YOLO11l | 640 | // | // | 25.3 | 86.9 | + | YOLO11x | 640 | 76.8 | 52.5 | 56.9 | 194.9 | @@ -280,7 +280,7 @@ ## 開發路線圖 - [x] 數據收集和預處理。 -- [x] 使用建築工地數據訓練 YOLOv8 模型。 +- [x] 使用建築工地數據訓練 YOLO 模型。 - [x] 開發後處理技術以提高準確性。 - [x] 實施實時分析和警報系統。 - [x] 在模擬環境中進行測試和驗證。 diff --git a/README.md b/README.md index 4fbb061..20ef59e 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,12 @@ AI-Driven Construction Safety Banner
- Server-API | + Server-API | Streaming-Web | User-Management | - Data-Augmentation | - Evaluation | - Train + Data-Augmentation | + Evaluation | + Train

@@ -18,7 +18,7 @@ Python 3.12.7 - YOLOv8 + YOLO11 HDBSCAN sklearn @@ -42,7 +42,7 @@
-"Construction-Hazard-Detection" is an AI-powered tool designed to enhance safety on construction sites. By leveraging the YOLOv8 model for object detection, it identifies potential hazards such as: +"Construction-Hazard-Detection" is an AI-powered tool designed to enhance safety on construction sites. By leveraging the YOLO model for object detection, it identifies potential hazards such as: - Workers without helmets - Workers without safety vests @@ -117,14 +117,14 @@ Before running the application, you need to configure the system by specifying t - video_url: "rtsp://example1.com/stream" # URL of the video image_name: "cam1" # Name of the image label: "label1" # Label of the video - model_key: "yolov8n" # Model key for the video + model_key: "yolo11n" # Model key for the video line_token: "token1" # Line token for notification run_local: True # Run object detection locally language: "en" # Set language to English - video_url: "rtsp://example2.com/stream" image_name: "cam2" label: "label2" - model_key: "yolov8n" + model_key: "yolo11n" line_token: "token2" run_local: True language: "zh-TW" @@ -268,11 +268,11 @@ The primary dataset for training this model is the [Construction Site Safety Ima | Model | size
(pixels) | mAPval
50 | mAPval
50-95 | params
(M) | FLOPs
(B) | | ------- | --------------------- | ------------------ | ------------------ | ----------------- | ----------------- | - | YOLOv8n | 640 | 59.3 | 35.0 | 3.2 | 8.7 | - | YOLOv8s | 640 | 73.1 | 47.6 | 11.2 | 28.6 | - | YOLOv8m | 640 | 76.8 | 53.9 | 25.9 | 78.9 | - | YOLOv8l | 640 | // | // | 43.7 | 165.2 | - | YOLOv8x | 640 | 82.9 | 60.9 | 68.2 | 257.8 | + | YOLO11n | 640 | 54.1 | 31.0 | 2.6 | 6.5 | + | YOLO11s | 640 | // | // | 9.4 | 21.6 | + | YOLO11m | 640 | // | // | 20.1 | 68.0 | + | YOLO11l | 640 | // | // | 25.3 | 86.9 | + | YOLO11x | 640 | 76.8 | 52.5 | 56.9 | 194.9 | @@ -290,7 +290,7 @@ We welcome contributions to this project. Please follow these steps: ## Development Roadmap - [x] Data collection and preprocessing. -- [x] Training YOLOv8 model with construction site data. +- [x] Training YOLO model with construction site data. - [x] Developing post-processing techniques for enhanced accuracy. - [x] Implementing real-time analysis and alert system. - [x] Testing and validation in simulated environments. diff --git a/examples/YOLOv8_data_augmentation/README-zh-tw.md b/examples/YOLO_data_augmentation/README-zh-tw.md similarity index 90% rename from examples/YOLOv8_data_augmentation/README-zh-tw.md rename to examples/YOLO_data_augmentation/README-zh-tw.md index 95b342c..4552c61 100644 --- a/examples/YOLOv8_data_augmentation/README-zh-tw.md +++ b/examples/YOLO_data_augmentation/README-zh-tw.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 資料增強範例 +# YOLO 資料增強範例 -本倉庫包含用於對影像資料集進行資料增強的範例和腳本,特別是旨在提高 YOLOv8 物件偵測模型的表現。對於需要豐富資料集以改善模型訓練的機器學習項目尤其有用。 +本倉庫包含用於對影像資料集進行資料增強的範例和腳本,特別是旨在提高 YOLO 物件偵測模型的表現。對於需要豐富資料集以改善模型訓練的機器學習項目尤其有用。 ## 使用方式 diff --git a/examples/YOLOv8_data_augmentation/README.md b/examples/YOLO_data_augmentation/README.md similarity index 90% rename from examples/YOLOv8_data_augmentation/README.md rename to examples/YOLO_data_augmentation/README.md index a89985e..4713c38 100644 --- a/examples/YOLOv8_data_augmentation/README.md +++ b/examples/YOLO_data_augmentation/README.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 Data Augmentation Example +# YOLO Data Augmentation Example -This repository contains examples and scripts for performing data augmentation on image datasets, particularly aimed at enhancing the performance of YOLOv8 object detection models. It is particularly useful for machine learning projects requiring enriched datasets for improved model training. +This repository contains examples and scripts for performing data augmentation on image datasets, particularly aimed at enhancing the performance of YOLO object detection models. It is particularly useful for machine learning projects requiring enriched datasets for improved model training. ## Usage diff --git a/examples/YOLOv8_data_augmentation/__init__.py b/examples/YOLO_data_augmentation/__init__.py similarity index 100% rename from examples/YOLOv8_data_augmentation/__init__.py rename to examples/YOLO_data_augmentation/__init__.py diff --git a/examples/YOLOv8_data_augmentation/data_augmentation.py b/examples/YOLO_data_augmentation/data_augmentation.py similarity index 99% rename from examples/YOLOv8_data_augmentation/data_augmentation.py rename to examples/YOLO_data_augmentation/data_augmentation.py index 2188cc0..36d7a44 100644 --- a/examples/YOLOv8_data_augmentation/data_augmentation.py +++ b/examples/YOLO_data_augmentation/data_augmentation.py @@ -407,4 +407,4 @@ def main(): if __name__ == '__main__': - main() + main() \ No newline at end of file diff --git a/examples/YOLOv8_data_augmentation/data_augmentation_albumentations.py b/examples/YOLO_data_augmentation/data_augmentation_albumentations.py similarity index 96% rename from examples/YOLOv8_data_augmentation/data_augmentation_albumentations.py rename to examples/YOLO_data_augmentation/data_augmentation_albumentations.py index 33a6f34..41a05a1 100644 --- a/examples/YOLOv8_data_augmentation/data_augmentation_albumentations.py +++ b/examples/YOLO_data_augmentation/data_augmentation_albumentations.py @@ -119,7 +119,6 @@ def random_transform(self) -> A.Compose: A.Perspective(scale=(0.05, 0.1), p=1), A.ElasticTransform(alpha=1, sigma=50, alpha_affine=None, p=1), A.Lambda(image=self.random_crop_with_random_size, p=1), - # A.RandomResizedCrop(height=640, width=640, scale=(0.3, 1.0), p=1), A.RandomResizedCrop(size=(640, 640), scale=(0.3, 1.0), p=1), ] @@ -127,8 +126,8 @@ def random_transform(self) -> A.Compose: non_bbox_augmentations = [ # Colour and brightness adjustments A.RandomBrightnessContrast( - brightness_limit=(-0.03, 0.03), - contrast_limit=(-0.03, 0.03), + brightness_limit=(0.0, 0.03), + contrast_limit=(0.0, 0.03), p=1.0 ), A.RGBShift(r_shift_limit=3, g_shift_limit=3, b_shift_limit=3, p=1.0), @@ -137,9 +136,9 @@ def random_transform(self) -> A.Compose: A.PlanckianJitter(p=1), # Blur and noise A.MotionBlur(blur_limit=(3, 7), p=1.0), - A.GaussianBlur(blur_limit=(3, 7), p=1.0), + A.GaussianBlur(blur_limit=(1, 3), p=1.0), A.GaussNoise(var_limit=(10.0, 50.0), p=1.0), - A.ISONoise(color_shift=(0.01, 0.05), intensity=(0.1, 0.5), p=1.0), + A.ISONoise(color_shift=(0.01, 0.05), intensity=(0.05, 0.2), p=1.0), A.MedianBlur(blur_limit=3, p=1.0), # Colour space and contrast adjustments A.CLAHE(clip_limit=2, p=1.0), @@ -150,10 +149,10 @@ def random_transform(self) -> A.Compose: A.Posterize(num_bits=4, p=1.0), A.InvertImg(p=1), # Special effects - A.RandomShadow(shadow_roi=(0.3, 0.3, 0.7, 0.7), num_shadows_limit = (1, 2), shadow_dimension=2, p=1.0), + A.RandomShadow(shadow_roi=(0.3, 0.3, 0.7, 0.7), num_shadows_limit = (1, 1), shadow_dimension=1, p=1.0), # A.RandomFog(fog_coef_lower=0.05, fog_coef_upper=0.1, p=1.0), A.RandomSnow(snow_point_range=(0.05, 0.15), brightness_coeff=1.2, p=1.0), - A.RandomRain(slant_range=(-5,5), drop_length=5, drop_width=1, blur_value=2, p=1.0), + A.RandomRain(slant_range=(-5,5), drop_length=5, drop_width=1, blur_value=1, p=1.0), A.ChannelShuffle(p=1), A.RandomSunFlare(flare_roi=(0.02, 0.04, 0.08, 0.08), angle_range=(0, 1), p=1), A.Defocus(radius=(3, 5), p=1), @@ -161,7 +160,7 @@ def random_transform(self) -> A.Compose: A.RandomToneCurve(scale=0.05, p=1.0), A.RandomGamma(gamma_limit=(90, 110), p=1.0), A.Superpixels(p_replace=0.1, n_segments=100, p=1), - A.ImageCompression(quality_range = (50, 90), p=1.0), + A.ImageCompression(quality_range = (70, 90), p=1.0), A.GlassBlur(sigma=0.5, max_delta=1, p=1.0), A.PixelDropout(dropout_prob=0.05, p=1), A.OpticalDistortion(distort_limit=(0.05, 0.1), shift_limit=(0.05, 0.1), p=1.0) @@ -255,6 +254,9 @@ def augment_image(self, image_path: Path) -> None: image_aug_path = self.train_path / 'images' / aug_image_filename label_aug_path = self.train_path / 'labels' / aug_label_filename + # Convert the image back to uint8 + image_aug = (image_aug * 255).clip(0, 255).astype(np.uint8) + # Save the image using OpenCV cv2.imwrite(str(image_aug_path), cv2.cvtColor(image_aug * 255, cv2.COLOR_RGB2BGR)) self.write_label_file(bboxes_aug, class_labels_aug, str(label_aug_path)) diff --git a/examples/YOLOv8_data_augmentation/visualise_bounding_boxes.py b/examples/YOLO_data_augmentation/visualise_bounding_boxes.py similarity index 100% rename from examples/YOLOv8_data_augmentation/visualise_bounding_boxes.py rename to examples/YOLO_data_augmentation/visualise_bounding_boxes.py diff --git a/examples/YOLOv8_evaluation/README-zh-tw.md b/examples/YOLO_evaluation/README-zh-tw.md similarity index 66% rename from examples/YOLOv8_evaluation/README-zh-tw.md rename to examples/YOLO_evaluation/README-zh-tw.md index 9dbdc21..be527ca 100644 --- a/examples/YOLOv8_evaluation/README-zh-tw.md +++ b/examples/YOLO_evaluation/README-zh-tw.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 評估範例 +# YOLO 評估範例 -此儲存庫提供了用於評估 YOLOv8 物件偵測模型的範例和腳本,特別著重於評估特定數據集上模型的準確度和性能。 +此儲存庫提供了用於評估 YOLO 物件偵測模型的範例和腳本,特別著重於評估特定數據集上模型的準確度和性能。 ## 使用方法 @@ -16,26 +16,26 @@ python convert_yolo_to_coco.py --labels_dir dataset/valid/labels --images_dir da ### 使用 SAHI 評估模型 -要使用 SAHI 庫來評估 YOLOv8 模型,請運行 `evaluate_sahi_yolov8.py` 腳本。提供模型、COCO JSON 和圖片目錄的路徑: +要使用 SAHI 庫來評估 YOLO 模型,請運行 `evaluate_sahi_yolo.py` 腳本。提供模型、COCO JSON 和圖片目錄的路徑: ```bash -python evaluate_sahi_yolov8.py --model_path "../../models/best_yolov8n.pt" --coco_json "dataset/coco_annotations.json" --image_dir "dataset/valid/images" +python evaluate_sahi_yolo.py --model_path "../../models/best_yolov8n.pt" --coco_json "dataset/coco_annotations.json" --image_dir "dataset/valid/images" ``` 此腳本將輸出各種 IoU 閾值下的評估指標,如平均精度和召回率。 ### 使用 Ultralytics YOLO 評估模型 -要使用 Ultralytics 框架進行評估,請執行 `evaluate_yolov8.py` 腳本。同樣地,指定模型和數據配置文件的路徑: +要使用 Ultralytics 框架進行評估,請執行 `evaluate_yolo.py` 腳本。同樣地,指定模型和數據配置文件的路徑: ```bash -python evaluate_yolov8.py --model_path "../../models/best_yolov8n.pt" --data_path "dataset/data.yaml" +python evaluate_yolo.py --model_path "../../models/best_yolov8n.pt" --data_path "dataset/data.yaml" ``` ### 功能 - **YOLO 至 COCO 轉換**:將您的數據集標註從 YOLO 格式轉換為 COCO 格式,以便與各種評估工具兼容。 -- **模型評估**:使用 SAHI 庫或 Ultralytics 框架來評估您的 YOLOv8 模型。 +- **模型評估**:使用 SAHI 庫或 Ultralytics 框架來評估您的 YOLO 模型。 - **性能指標**:透過像是 mAP、精度和召回率等指標,獲得模型性能的深入見解。 - **可自訂的評估**:腳本允許針對您特定的數據集和模型進行靈活的評估設置。 diff --git a/examples/YOLOv8_evaluation/README.md b/examples/YOLO_evaluation/README.md similarity index 69% rename from examples/YOLOv8_evaluation/README.md rename to examples/YOLO_evaluation/README.md index 7e7b11e..3ac6503 100644 --- a/examples/YOLOv8_evaluation/README.md +++ b/examples/YOLO_evaluation/README.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 Evaluation Example +# YOLO Evaluation Example -This repository provides examples and scripts for evaluating YOLOv8 object detection models, particularly focusing on assessing the model's accuracy and performance on specific datasets. +This repository provides examples and scripts for evaluating YOLO object detection models, particularly focusing on assessing the model's accuracy and performance on specific datasets. ## Usage @@ -16,26 +16,26 @@ python convert_yolo_to_coco.py --labels_dir dataset/valid/labels --images_dir da ### Evaluating Models with SAHI -To evaluate a YOLOv8 model using the SAHI library, run the `evaluate_sahi_yolov8.py` script. Provide the paths to the model, COCO JSON, and image directory: +To evaluate a YOLO model using the SAHI library, run the `evaluate_sahi_yolo.py` script. Provide the paths to the model, COCO JSON, and image directory: ```bash -python evaluate_sahi_yolov8.py --model_path "../../models/best_yolov8n.pt" --coco_json "dataset/coco_annotations.json" --image_dir "dataset/valid/images" +python evaluate_sahi_yolo.py --model_path "../../models/best_yolov8n.pt" --coco_json "dataset/coco_annotations.json" --image_dir "dataset/valid/images" ``` This script will output evaluation metrics such as Average Precision and Recall across different IoU thresholds. ### Evaluating Models with Ultralytics YOLO -For evaluation using the Ultralytics framework, execute the `evaluate_yolov8.py` script. Again, specify the model and data configuration file paths: +For evaluation using the Ultralytics framework, execute the `evaluate_yolo.py` script. Again, specify the model and data configuration file paths: ```bash -python evaluate_yolov8.py --model_path "../../models/best_yolov8n.pt" --data_path "dataset/data.yaml" +python evaluate_yolo.py --model_path "../../models/best_yolov8n.pt" --data_path "dataset/data.yaml" ``` ### Features - **YOLO to COCO Conversion**: Convert your dataset annotations from YOLO format to COCO format for compatibility with various evaluation tools. -- **Model Evaluation**: Utilise the SAHI library or Ultralytics framework to evaluate your YOLOv8 models. +- **Model Evaluation**: Utilise the SAHI library or Ultralytics framework to evaluate your YOLO models. - **Performance Metrics**: Gain insights into model performance with metrics like mAP, Precision, and Recall. - **Customisable Evaluation**: Scripts allow for flexible evaluation setups tailored to your specific dataset and model. diff --git a/examples/YOLOv8_evaluation/__init__.py b/examples/YOLO_evaluation/__init__.py similarity index 100% rename from examples/YOLOv8_evaluation/__init__.py rename to examples/YOLO_evaluation/__init__.py diff --git a/examples/YOLOv8_evaluation/convert_yolo_to_coco.py b/examples/YOLO_evaluation/convert_yolo_to_coco.py similarity index 98% rename from examples/YOLOv8_evaluation/convert_yolo_to_coco.py rename to examples/YOLO_evaluation/convert_yolo_to_coco.py index e152040..05dd0dd 100644 --- a/examples/YOLOv8_evaluation/convert_yolo_to_coco.py +++ b/examples/YOLO_evaluation/convert_yolo_to_coco.py @@ -9,7 +9,9 @@ class COCOConverter: - """Converts YOLO format annotations to COCO format.""" + """ + Converts YOLO format annotations to COCO format. + """ def __init__(self, categories: list[str]): """ diff --git a/examples/YOLOv8_evaluation/evaluate_sahi_yolov8.py b/examples/YOLO_evaluation/evaluate_sahi_yolo.py similarity index 98% rename from examples/YOLOv8_evaluation/evaluate_sahi_yolov8.py rename to examples/YOLO_evaluation/evaluate_sahi_yolo.py index 7c92e59..40056f1 100644 --- a/examples/YOLOv8_evaluation/evaluate_sahi_yolov8.py +++ b/examples/YOLO_evaluation/evaluate_sahi_yolo.py @@ -131,7 +131,7 @@ def evaluate(self) -> dict[str, float]: def main(): parser = argparse.ArgumentParser( - description='Evaluates a YOLOv8 model using COCO metrics.', + description='Evaluates a YOLO model using COCO metrics.', ) parser.add_argument( '--model_path', @@ -165,7 +165,7 @@ def main(): main() """example usage -python evaluate_sahi_yolov8.py \ +python evaluate_sahi_yolo.py \ --model_path "../../models/pt/best_yolov8x.pt" \ --coco_json "dataset/coco_annotations.json" \ --image_dir "dataset/valid/images" diff --git a/examples/YOLOv8_evaluation/evaluate_yolov8.py b/examples/YOLO_evaluation/evaluate_yolo.py similarity index 94% rename from examples/YOLOv8_evaluation/evaluate_yolov8.py rename to examples/YOLO_evaluation/evaluate_yolo.py index 689f103..07796a9 100644 --- a/examples/YOLOv8_evaluation/evaluate_yolov8.py +++ b/examples/YOLO_evaluation/evaluate_yolo.py @@ -8,7 +8,7 @@ class ModelEvaluator: """ - A class to evaluate YOLOv8 models using Ultralytics framework. + A class to evaluate YOLO models using Ultralytics framework. """ def __init__(self, model_path: str, data_path: str): @@ -36,7 +36,7 @@ def evaluate(self) -> dict[str, Any]: def main(): - parser = argparse.ArgumentParser(description='Evaluates a YOLOv8 model.') + parser = argparse.ArgumentParser(description='Evaluates a YOLO model.') parser.add_argument( '--model_path', type=str, @@ -64,7 +64,7 @@ def main(): main() """example usage -python evaluate_yolov8.py \ +python evaluate_yolo.py \ --model_path "../../models/pt/best_yolov8x.pt" \ --data_path "dataset/data.yaml" """ diff --git a/examples/YOLOv8_server_api/README-zh-tw.md b/examples/YOLO_server_api/README-zh-tw.md similarity index 74% rename from examples/YOLOv8_server_api/README-zh-tw.md rename to examples/YOLO_server_api/README-zh-tw.md index 33527d0..1299be9 100644 --- a/examples/YOLOv8_server_api/README-zh-tw.md +++ b/examples/YOLO_server_api/README-zh-tw.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 Server API 範例 +# YOLO Server API 範例 -本部分提供一個 YOLOv8 Server API 的範例實作,旨在利用 YOLOv8 模型進行物件檢測。此指南提供有關如何使用、配置和了解該 API 功能的信息。 +本部分提供一個 YOLO Server API 的範例實作,旨在利用 YOLO 模型進行物件檢測。此指南提供有關如何使用、配置和了解該 API 功能的信息。 ## 使用方式 @@ -14,7 +14,7 @@ 或者 ```sh - gunicorn -w 1 -b 0.0.0.0:8000 "examples.YOLOv8_server_api.app:app" + gunicorn -w 1 -b 0.0.0.0:8000 "examples.object_detection__server_api.app:app" ``` 2. **向 API 發送請求:** @@ -28,9 +28,9 @@ - **身份驗證**:使用身份驗證機制來保護 API。 - **快取**:通過快取檢測結果來提高性能。 -- **模型下載**:自動下載和加載 YOLOv8 模型。 +- **模型下載**:自動下載和加載 YOLO 模型。 - **配置**:靈活的配置選項來定制 API。 -- **物件檢測**:使用 YOLOv8 模型對上傳的圖像進行物件檢測。 +- **物件檢測**:使用 YOLO 模型對上傳的圖像進行物件檢測。 - **錯誤處理**:強健的錯誤處理機制來管理各種情況。 ## 配置 @@ -42,7 +42,7 @@ - `PORT`:運行伺服器的端口。默認為 `8000`。 - **模型設置**: - - `MODEL_PATH`:YOLOv8 模型文件的路徑。 + - `MODEL_PATH`:YOLO 模型文件的路徑。 - `CONFIDENCE_THRESHOLD`:物件檢測的置信度閾值。 - **快取設置**: @@ -59,8 +59,8 @@ - **auth.py**:處理身份驗證機制。 - **cache.py**:實現快取功能。 - **config.py**:包含 API 的配置設置。 -- **detection.py**:使用 YOLOv8 模型進行物件檢測。 -- **model_downloader.py**:處理 YOLOv8 模型的下載和加載。 +- **detection.py**:使用 YOLO 模型進行物件檢測。 +- **model_downloader.py**:處理 YOLO 模型的下載和加載。 - **models.py**:定義數據模型和結構。 - **security.py**:實現安全功能。 diff --git a/examples/YOLOv8_server_api/README.md b/examples/YOLO_server_api/README.md similarity index 81% rename from examples/YOLOv8_server_api/README.md rename to examples/YOLO_server_api/README.md index 1b88009..071c145 100644 --- a/examples/YOLOv8_server_api/README.md +++ b/examples/YOLO_server_api/README.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 Server API example +# YOLO Server API example -This section an example implementation of a YOLOv8 Server API, designed to facilitate object detection using the YOLOv8 model. This guide provides information on how to use, configure, and understand the features of this API. +This section an example implementation of a YOLO Server API, designed to facilitate object detection using the YOLO model. This guide provides information on how to use, configure, and understand the features of this API. ## Usage @@ -14,7 +14,7 @@ This section an example implementation of a YOLOv8 Server API, designed to facil or ```sh - gunicorn -w 1 -b 0.0.0.0:8000 "examples.YOLOv8_server_api.app:app" + gunicorn -w 1 -b 0.0.0.0:8000 "examples.object_detection_server_api.app:app" ``` 4. **Send a request to the API:** @@ -28,9 +28,9 @@ This section an example implementation of a YOLOv8 Server API, designed to facil - **Authentication**: Secure the API with authentication mechanisms. - **Caching**: Improve performance with caching of detection results. -- **Model Download**: Automated downloading and loading of the YOLOv8 model. +- **Model Download**: Automated downloading and loading of the YOLO model. - **Configuration**: Flexible configuration options to customise the API. -- **Object Detection**: Perform object detection on uploaded images using YOLOv8. +- **Object Detection**: Perform object detection on uploaded images using YOLO. - **Error Handling**: Robust error handling to manage different scenarios gracefully. ## Configuration @@ -42,7 +42,7 @@ The API can be configured through the `config.py` file. Below are some of the ke - `PORT`: The port to run the server on. Default is `8000`. - **Model Settings**: - - `MODEL_PATH`: Path to the YOLOv8 model file. + - `MODEL_PATH`: Path to the YOLO model file. - `CONFIDENCE_THRESHOLD`: Confidence threshold for object detection. - **Cache Settings**: @@ -59,8 +59,8 @@ The API can be configured through the `config.py` file. Below are some of the ke - **auth.py**: Handles authentication mechanisms. - **cache.py**: Implements caching functionalities. - **config.py**: Contains configuration settings for the API. -- **detection.py**: Performs object detection using the YOLOv8 model. -- **model_downloader.py**: Handles downloading and loading of the YOLOv8 model. +- **detection.py**: Performs object detection using the YOLO model. +- **model_downloader.py**: Handles downloading and loading of the YOLO model. - **models.py**: Defines data models and schemas. - **security.py**: Implements security features. diff --git a/examples/YOLOv8_server_api/__init__.py b/examples/YOLO_server_api/__init__.py similarity index 100% rename from examples/YOLOv8_server_api/__init__.py rename to examples/YOLO_server_api/__init__.py diff --git a/examples/YOLOv8_server_api/app.py b/examples/YOLO_server_api/app.py similarity index 100% rename from examples/YOLOv8_server_api/app.py rename to examples/YOLO_server_api/app.py diff --git a/examples/YOLOv8_server_api/auth.py b/examples/YOLO_server_api/auth.py similarity index 100% rename from examples/YOLOv8_server_api/auth.py rename to examples/YOLO_server_api/auth.py diff --git a/examples/YOLOv8_server_api/cache.py b/examples/YOLO_server_api/cache.py similarity index 100% rename from examples/YOLOv8_server_api/cache.py rename to examples/YOLO_server_api/cache.py diff --git a/examples/YOLOv8_server_api/config.py b/examples/YOLO_server_api/config.py similarity index 100% rename from examples/YOLOv8_server_api/config.py rename to examples/YOLO_server_api/config.py diff --git a/examples/YOLOv8_server_api/detection.py b/examples/YOLO_server_api/detection.py similarity index 96% rename from examples/YOLOv8_server_api/detection.py rename to examples/YOLO_server_api/detection.py index 6d5bab3..c4f6629 100644 --- a/examples/YOLOv8_server_api/detection.py +++ b/examples/YOLO_server_api/detection.py @@ -24,7 +24,7 @@ @limiter.limit('3000 per minute') def detect(): data = request.files['image'].read() - model_key = request.args.get('model', default='yolov8n', type=str) + model_key = request.args.get('model', default='yolo11n', type=str) model = model_loader.get_model(model_key) img = convert_to_image(data) @@ -65,8 +65,8 @@ def get_prediction_result(img, model): return get_sliced_prediction( img, model, - slice_height=376, - slice_width=376, + slice_height=370, + slice_width=370, overlap_height_ratio=0.3, overlap_width_ratio=0.3, ) @@ -74,7 +74,7 @@ def get_prediction_result(img, model): def compile_detection_data(result): """ - Compile detection data in YOLOv8 format. + Compile detection data in YOLO format. Args: result: Prediction result. @@ -112,7 +112,7 @@ def remove_overlapping_labels(datas): Removes overlapping labels for Hardhat and Safety Vest categories. Args: - datas (list): A list of detection data in YOLOv8 format. + datas (list): A list of detection data in YOLO format. Returns: list: A list of detection data with overlapping labels removed. @@ -149,7 +149,7 @@ def get_category_indices(datas): Get indices of different categories in the detection data. Args: - datas (list): A list of detection data in YOLOv8 format. + datas (list): A list of detection data in YOLO format. Returns: dict: Indices of Hardhat, NO-Hardhat, Safety Vest, @@ -285,7 +285,7 @@ def remove_completely_contained_labels(datas): Removes completely contained labels for Hardhat and Safety Vest categories. Args: - datas (list): A list of detection data in YOLOv8 format. + datas (list): A list of detection data in YOLO format. Returns: list: Detection data with fully contained labels removed. diff --git a/examples/YOLOv8_server_api/model_downloader.py b/examples/YOLO_server_api/model_downloader.py similarity index 98% rename from examples/YOLOv8_server_api/model_downloader.py rename to examples/YOLO_server_api/model_downloader.py index f4767c5..7a426cd 100644 --- a/examples/YOLOv8_server_api/model_downloader.py +++ b/examples/YOLO_server_api/model_downloader.py @@ -17,7 +17,7 @@ # Define the directory where the model files are stored MODELS_DIRECTORY = Path('models/pt/') # Define the allowed models -ALLOWED_MODELS = {'best_yolov8l.pt', 'best_yolov8x.pt'} +ALLOWED_MODELS = {'best_yolo11l.pt', 'best_yolo11x.pt'} @models_blueprint.route('/models/', methods=['GET']) diff --git a/examples/YOLOv8_server_api/models.py b/examples/YOLO_server_api/models.py similarity index 98% rename from examples/YOLOv8_server_api/models.py rename to examples/YOLO_server_api/models.py index db3dac8..5c0de59 100644 --- a/examples/YOLOv8_server_api/models.py +++ b/examples/YOLO_server_api/models.py @@ -60,7 +60,9 @@ class DetectionModelManager: def __init__(self): self.base_model_path = Path('models/pt/') self.model_names = [ - 'yolov8x', + 'yolo11x', + 'yolo11n', + 'yolov8x' 'yolov8l', 'yolov8m', 'yolov8s', diff --git a/examples/YOLOv8_server_api/security.py b/examples/YOLO_server_api/security.py similarity index 100% rename from examples/YOLOv8_server_api/security.py rename to examples/YOLO_server_api/security.py diff --git a/examples/YOLOv8_train/README-zh-tw.md b/examples/YOLO_train/README-zh-tw.md similarity index 77% rename from examples/YOLOv8_train/README-zh-tw.md rename to examples/YOLO_train/README-zh-tw.md index 46fbd51..68e5e92 100644 --- a/examples/YOLOv8_train/README-zh-tw.md +++ b/examples/YOLO_train/README-zh-tw.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 微調範例 +# YOLO 微調範例 -此儲存庫包含用於微調 YOLOv8 物件偵測模型的範例和腳本。特別旨在提升模型針對特定資料集或應用的性能。 +此儲存庫包含用於微調 YOLO 物件偵測模型的範例和腳本。特別旨在提升模型針對特定資料集或應用的性能。 ## 使用方式 @@ -11,7 +11,7 @@ 要訓練 YOLO 模型,請使用 `train.py` 腳本。指定模型名稱、訓練週期數及資料配置: ```bash -python train.py --model_name 'yolov8n.pt' --epochs 100 --data_config 'dataset/data.yaml' +python train.py --model_name 'yolo11n.pt' --epochs 100 --data_config 'dataset/data.yaml' ``` ### 使用腳本訓練 YOLO 模型 @@ -29,7 +29,7 @@ bash train_yolo_models.sh 訓練後,您可以使用 `train.py` 腳本將您的 YOLO 模型導出到不同的格式,例如 ONNX: ```bash -python train.py --model_name 'yolov8n.pt' --export_format 'onnx' --onnx_path 'yolov8n.onnx' +python train.py --model_name 'yolo11n.pt' --export_format 'onnx' --onnx_path 'yolo11n.onnx' ``` ### 模型預測 @@ -37,7 +37,7 @@ python train.py --model_name 'yolov8n.pt' --export_format 'onnx' --onnx_path 'yo 要使用 YOLO 模型進行預測,請指定預測的圖片路徑: ```bash -python train.py --model_name 'yolov8n.pt' --predict_image 'path/to/image.jpg' +python train.py --model_name 'yolo11n.pt' --predict_image 'path/to/image.jpg' ``` ## 特點 diff --git a/examples/YOLOv8_train/README.md b/examples/YOLO_train/README.md similarity index 77% rename from examples/YOLOv8_train/README.md rename to examples/YOLO_train/README.md index 9828b8a..2299f46 100644 --- a/examples/YOLOv8_train/README.md +++ b/examples/YOLO_train/README.md @@ -1,8 +1,8 @@ 🇬🇧 [English](./README.md) | 🇹🇼 [繁體中文](./README-zh-tw.md) -# YOLOv8 Train Example +# YOLO Train Example -This repository contains examples and scripts for training YOLOv8 object detection models. It is particularly aimed at enhancing the model's performance for specific datasets or applications. +This repository contains examples and scripts for training YOLO object detection models. It is particularly aimed at enhancing the model's performance for specific datasets or applications. ## Usage @@ -11,7 +11,7 @@ This repository contains examples and scripts for training YOLOv8 object detecti To train a YOLO model, use the `train.py` script. Specify the model name, the number of training epochs, and the data configuration: ```bash -python train.py --model_name 'yolov8n.pt' --epochs 100 --data_config 'dataset/data.yaml' +python train.py --model_name 'yolo11n.pt' --epochs 100 --data_config 'dataset/data.yaml' ``` ### Training YOLO Models with Script @@ -29,7 +29,7 @@ This script will download base models if they are not present and start the trai After training, you can export your YOLO model to different formats, such as ONNX, using the `train.py` script: ```bash -python train.py --model_name 'yolov8n.pt' --export_format 'onnx' --onnx_path 'yolov8n.onnx' +python train.py --model_name 'yolo11n.pt' --export_format 'onnx' --onnx_path 'yolo11n.onnx' ``` ### Model Prediction @@ -37,7 +37,7 @@ python train.py --model_name 'yolov8n.pt' --export_format 'onnx' --onnx_path 'yo To predict using a YOLO model, specify the image path for prediction: ```bash -python train.py --model_name 'yolov8n.pt' --predict_image 'path/to/image.jpg' +python train.py --model_name 'yolo11n.pt' --predict_image 'path/to/image.jpg' ``` ## Features diff --git a/examples/YOLOv8_train/__init__.py b/examples/YOLO_train/__init__.py similarity index 100% rename from examples/YOLOv8_train/__init__.py rename to examples/YOLO_train/__init__.py diff --git a/examples/YOLOv8_train/train.py b/examples/YOLO_train/train.py similarity index 96% rename from examples/YOLOv8_train/train.py rename to examples/YOLO_train/train.py index 2dd0e5d..602ff71 100644 --- a/examples/YOLOv8_train/train.py +++ b/examples/YOLO_train/train.py @@ -126,13 +126,13 @@ def predict_image(self, image_path: str) -> Any: return self.model(image_path) @staticmethod - def predict_image_sahi(yolov8_model_path: str, image_path: str) -> Any: + def predict_image_sahi(yolo_model_path: str, image_path: str) -> Any: """ Makes a prediction using the YOLO model on the specified image with SAHI post-processing. Args: - yolov8_model_path (str): The path to the YOLOv8 model file. + yolo_model_path (str): The path to the YOLO model file. image_path (str): The path to the image file for prediction. Returns: @@ -141,13 +141,13 @@ def predict_image_sahi(yolov8_model_path: str, image_path: str) -> Any: Raises: RuntimeError: If model is not loaded properly before prediction. """ - if not yolov8_model_path: + if not yolo_model_path: raise RuntimeError('The model path is not provided.') # Convert YOLO model to SAHI format; adjust for your YOLO version sahi_model = AutoDetectionModel.from_pretrained( model_type='yolov8', - model_path=yolov8_model_path, + model_path=yolo_model_path, confidence_threshold=0.3, # device="cpu", or 'cuda:0' ) @@ -341,7 +341,7 @@ def cross_validate_model( def main(): parser = argparse.ArgumentParser( - description='YOLOv8 training, validation, prediction, and export.', + description='YOLO training, validation, prediction, and export.', ) parser.add_argument( @@ -359,7 +359,7 @@ def main(): parser.add_argument( '--model_name', type=str, - default='./../../models/pt/best_yolov8x.pt', + default='./../../models/pt/best_yolo11x.pt', help='Name or path of the YOLO model file', ) parser.add_argument( @@ -463,9 +463,9 @@ def main(): # Example command to run the script # python train.py \ - # --data_config=dataset/data.yaml \ + # --data_config=cv_dataset/data.yaml \ # --epochs=100 \ - # --model_name=../../models/pt/best_yolov8x.pt \ + # --model_name=../../models/pt/best_yolo11x.pt \ # --batch_size=16 \ # --optimizer=auto \ # --cross_validate \ diff --git a/examples/YOLOv8_data_augmentation/run_augmentation_and_move.sh b/examples/YOLOv8_data_augmentation/run_augmentation_and_move.sh deleted file mode 100644 index d11aaea..0000000 --- a/examples/YOLOv8_data_augmentation/run_augmentation_and_move.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -# Set the working directory to the directory of this script -cd "$(dirname "$0")" - -# Execute the data augmentation script -echo "Starting data augmentation..." -python ../src/data_augmentation.py -echo "Data augmentation completed." - -# Determine the last file number in the target directories -last_image=$(ls -v ../dataset/train/images/ | tail -n 1) -last_label=$(ls -v ../dataset/train/labels/ | tail -n 1) - -# Extract the number from the file name using regular expressions -[[ $last_image =~ ([0-9]+) ]] -last_num_image=${BASH_REMATCH[1]} - -[[ $last_label =~ ([0-9]+) ]] -last_num_label=${BASH_REMATCH[1]} - -# Calculate the starting number for the next file -next_num=$((last_num_image > last_num_label ? last_num_image : last_num_label)) -next_num=$((next_num + 1)) - -# Move and rename augmented images and label files -echo "Starting to move and rename augmented images and label files..." -for file in dataset_aug/train/images/*; do - filename=$(basename -- "$file") - extension="${filename##*.}" - mv "$file" "../dataset/train/images/$(printf "%06d.%s" "$next_num" "$extension")" - mv "../dataset_aug/train/labels/${filename%.*}.txt" "../dataset/train/labels/$(printf "%06d.txt" "$next_num")" - next_num=$((next_num + 1)) -done -echo "File movement and renaming completed." - -# Optional: Clean the dataset_aug directory -echo "Cleaning augmentation data directory..." -rm -rf ../dataset_aug/train/images/* -rm -rf ../dataset_aug/train/labels/* -echo "Augmentation data directory cleaned." diff --git a/examples/YOLOv8_data_augmentation/user_manual_marp.md b/examples/YOLOv8_data_augmentation/user_manual_marp.md deleted file mode 100644 index 486bb94..0000000 --- a/examples/YOLOv8_data_augmentation/user_manual_marp.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -marp: true -theme: default -class: - - lead - - invert -paginate: true ---- - -# Data Augmentation and Bounding Box Visualisation - ---- - -## Introduction - -- **Objective**: Enhance image datasets for machine learning model training. -- **Components**: - - Data Augmentation - - File Renaming and Organisation - - Bounding Box Visualisation - ---- - -## DataAugmentation.py Overview - -- **Purpose**: Augment image data for better model generalisation. -- **Features**: - - Randomly applies a series of image transformations. - - Supports bounding box adjustments for object detection tasks. -- **Usage**: Customisable for different dataset sizes and augmentation needs. - ---- - -## Running the Data Augmentation Script - -1. Set the dataset path and augmentation count: - `--train_path './dataset_aug/train' --num_augmentations 30` -2. Execute the script: - ```bash - python data_augmentation.py - ``` -3. The script generates augmented images and corresponding label files. - ---- - -## run_augmentation_and_move.sh Overview - -- **Purpose**: Automate augmentation process and integrate new images into the dataset. -- **Features**: - - Executes: - ```bash - data_augmentation.py - ``` - - Renames and moves files to maintain dataset organisation. -- **Usage**: Ensures seamless augmentation and dataset expansion. - ---- - -## Using run_augmentation_and_move.sh - -1. Navigate to the script's directory. -2. Make the script executable: - ```bash - chmod +x run_augmentation_and_move.sh - ``` -3. Run the script: - ```bash - bash ./run_augmentation_and_move.sh - ``` -4. Augmented images are now part of the main dataset. - ---- - -## visualise_bounding_boxes.py Overview - -- **Purpose**: Visualise bounding boxes on images for verification. -- **Features**: - - Draws bounding boxes based on label files. - - Options to save or display the annotated images. -- **Usage**: Helps in verifying the correctness of label data. - ---- - -## Visualising Bounding Boxes - -1. Specify image and label paths: - `--image 'path/to/image.jpg' --label 'path/to/label.txt'` -2. Choose to save or display the result: - `--save` to save or omit to display. -3. Run the script: - ```bash - python visualise_bounding_boxes.py --image '...' --label '...' [--save] - ``` - ---- - -## Conclusion - -- **Efficient Data Augmentation**: Enhances training datasets for improved model performance. -- **Seamless Integration**: Automated scripts for easy augmentation and dataset management. -- **Quality Assurance**: Visualisation tools for bounding box verification. - -Thank you for attending this presentation. diff --git a/examples/YOLOv8_evaluation/user_manual_marp.md b/examples/YOLOv8_evaluation/user_manual_marp.md deleted file mode 100644 index a103b1a..0000000 --- a/examples/YOLOv8_evaluation/user_manual_marp.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -marp: true -theme: default -class: - - lead - - invert -paginate: true ---- - -# YOLO to COCO Conversion and Model Evaluation - ---- - -## Introduction - -- **Objective**: Convert YOLO annotations to COCO format and evaluate object detection models. -- **Scripts**: - - `convert_yolo_to_coco.py` - - `evaluate_sahi_yolov8.py` - - `evaluate_yolov8.py` -- **Usage**: Useful for preparing datasets and assessing model performance. - ---- - -## convert_yolo_to_coco.py Overview - -- **Purpose**: Convert YOLO format annotations to COCO format for compatibility with different tools and frameworks. -- **Features**: - - Parses YOLO annotations and corresponding images. - - Generates a COCO-format JSON file. - ---- - -## Running convert_yolo_to_coco.py - -1. Provide the directories for YOLO labels and images. -2. Specify the output file for COCO formatted annotations. -3. Command: - ```bash - python convert_yolo_to_coco.py --labels_dir --images_dir --output - ``` - ---- - -## evaluate_sahi_yolov8.py Overview - -- **Purpose**: Evaluate object detection models on COCO metrics using the SAHI framework. -- **Features**: - - Sliced prediction for handling large images. - - Computes COCO metrics for model evaluation. - ---- - -## Using evaluate_sahi_yolov8.py - -1. Specify model path, COCO JSON, and image directory. -2. Set optional parameters for slicing and confidence threshold. -3. Command: - ```bash - python evaluate_sahi_yolov8.py --model_path --coco_json --image_dir - ``` - ---- - -## evaluate_yolov8.py Overview - -- **Purpose**: Evaluate YOLOv8 models using the Ultralytics framework. -- **Features**: - - Direct integration with YOLOv8. - - Provides standard evaluation metrics. - ---- - -## Running evaluate_yolov8.py - -1. Input the model and dataset configuration paths. -2. Execute the script to get evaluation metrics. -3. Command: - ```bash - python evaluate_yolov8.py --model_path --data_path - ``` - ---- - -## Conclusion - -- **Data Preparation**: Convert annotations to ensure compatibility with various frameworks. -- **Model Evaluation**: Assess model performance using standard COCO metrics. -- **Optimisation**: Utilise these tools for iterative improvement of object detection models. - -Thank you for attending this presentation. diff --git a/examples/YOLOv8_train/train_yolo_models.sh b/examples/YOLOv8_train/train_yolo_models.sh deleted file mode 100644 index 980ccab..0000000 --- a/examples/YOLOv8_train/train_yolo_models.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Define models and their download links -declare -A models=( - ["yolov8n.pt"]="https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8n.pt" - ["yolov8s.pt"]="https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8s.pt" - ["yolov8m.pt"]="https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8m.pt" - ["yolov8l.pt"]="https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8l.pt" - ["yolov8x.pt"]="https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8x.pt" -) - -# Ensure the models directory exists -mkdir -p ../models - -# Check and use pre-trained models if they exist -for model in "${!models[@]}"; do - trained_model_path="../models/trained_$model" - if [ -f "$trained_model_path" ]; then - echo "Pre-trained model $trained_model_path exists, will be used for training." - model_path="$trained_model_path" # Use the pre-trained model for training - else - echo "Model $model does not exist or hasn't been trained, checking for base model..." - if [ ! -f "../models/$model" ]; then - echo "Base model $model does not exist, downloading..." - wget -O "../models/$model" "${models[$model]}" - fi - model_path="../models/$model" - fi - - # Start training - echo "Starting training $model with $model_path ..." - python ../src/train.py --model_name "$model_path" --epochs 100 --pt_path "$trained_model_path" - echo "$model training completed." -done - -echo "All model training completed." diff --git a/examples/YOLOv8_train/user_manual_marp.md b/examples/YOLOv8_train/user_manual_marp.md deleted file mode 100644 index 7e323cc..0000000 --- a/examples/YOLOv8_train/user_manual_marp.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -marp: true -theme: default -class: - - lead - - invert -paginate: true ---- - -# YOLO Model Handling and Training - ---- - -## Introduction - -- **Objective**: Understand the workflow of training, validating, predicting, and exporting YOLO models. -- **Scripts**: - - `train.py`: Handles YOLO model operations. - - `train_yolo_models.sh`: Batch processes for model training. - ---- - -## train.py Overview - -- **Purpose**: Facilitate YOLO model operations including training, validation, prediction, and exporting. -- **Capabilities**: - - Load and train YOLO models. - - Validate models on a dataset. - - Predict using trained models. - - Export models to ONNX format. - - Implement SAHI for sliced predictions. - ---- - -## Using train.py - -1. Set parameters for model handling: - - Model path, data configuration, epochs, etc. -2. Execute the script for desired operations: - ```bash - python train.py --model_name --data_config --epochs - ``` -3. Review the output for training metrics, predictions, and export paths. - ---- - -## train_yolo_models.sh Overview - -- **Purpose**: Automate the training process for multiple YOLO models. -- **Features**: - - Checks and downloads base models. - - Utilises pre-trained models if available. - - Trains models sequentially. - ---- - -## Executing train_yolo_models.sh - -1. Ensure script permissions: - `chmod +x train_yolo_models.sh` -2. Run the script: - `./train_yolo_models.sh` -3. Monitor the training process for each model listed in the script. - ---- - -## YOLOModelHandler Class Functions - -- **Load Model**: Loads a YOLO model for operations. -- **Train Model**: Trains the model using specified dataset and epochs. -- **Validate Model**: Validates model performance on a dataset. -- **Predict Image**: Generates predictions for a given image. -- **Export Model**: Exports the trained model to different formats. - ---- - -## SAHI Prediction with YOLO - -- Utilise SAHI for improved prediction accuracy on large images. -- Slices large images into smaller segments for detailed analysis. -- Combines predictions from all segments for a comprehensive result. - ---- - -## Conclusion - -- Efficient and structured approach to handling YOLO models. -- Automates training and evaluation for multiple models. -- Employs SAHI for advanced image prediction capabilities. - -Thank you for attending this presentation. diff --git a/requirements.txt b/requirements.txt index 05c4faf..b16b0e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ +albumentations==1.4.17 apscheduler==3.10.4 -albumentations==1.4.16 codecov==2.1.13 eventlet==0.37.0 Flask==3.0.3 # Flask-Cors==4.0.1 -Flask-JWT-Extended ==4.6.0 +Flask-JWT-Extended==4.6.0 Flask-Limiter==3.8.0 Flask-SocketIO==5.3.7 Flask-SQLAlchemy==3.1.1 @@ -26,7 +26,7 @@ pytest-cov==5.0.0 pytest-xdist==3.6.1 python-dotenv==1.0.1 python-telegram-bot==21.6 -redis==5.0.8 +redis==5.1.1 sahi==0.11.18 scikit-learn==1.5.2 speedtest-cli==2.1.3 @@ -35,4 +35,4 @@ tenacity==9.0.0 torch==2.4.1 torchvision==0.19.1 twilio==9.3.2 -ultralytics==8.2.102 +ultralytics==8.3.7 diff --git a/src/README-zh-tw.md b/src/README-zh-tw.md new file mode 100644 index 0000000..f6f981a --- /dev/null +++ b/src/README-zh-tw.md @@ -0,0 +1,77 @@ +🇬🇧 [English](./src/README.md) | 🇹🇼 [繁體中文](./src/README-zh-tw.md) + +## 概述 + +此存儲庫包含多個 Python 腳本,設計用於各種功能,包括即時串流檢測、繪圖管理、模型下載、日誌記錄,以及通過不同平台發送通知。該專案的結構有助於這些功能的簡易整合和使用。 + +## 目錄結構 + +``` +src +├── danger_detector.py +├── drawing_manager.py +├── __init__.py +├── lang_config.py +├── live_stream_detection.py +├── live_stream_tracker.py +├── model_fetcher.py +├── monitor_logger.py +├── notifiers +│ ├── broadcast_notifier.py +│ ├── __init__.py +│ ├── line_notifier.py +│ ├── messenger_notifier.py +│ ├── telegram_notifier.py +│ └── wechat_notifier.py +├── stream_capture.py +└── stream_viewer.py +``` + +## 文件描述 + +### 主要模組 + +- **danger_detector.py**:包含 [`DangerDetector`](./src/danger_detector.py) 類別,用於基於檢測數據發現潛在的安全隱患。 +- **drawing_manager.py**:包含 [`DrawingManager`](./src/drawing_manager.py) 類別,用於在影像上繪製檢測結果並保存它們。 +- **lang_config.py**:語言設置的配置文件。 +- **live_stream_detection.py**:包含 [`LiveStreamDetector`](./src/live_stream_detection.py) 類別,用於使用 YOLOv8 和 SAHI 進行即時串流檢測和追蹤。 +- **live_stream_tracker.py**:包含 [`LiveStreamDetector`](./src/live_stream_tracker.py) 類別,用於使用 YOLOv8 進行即時串流檢測和追蹤。 +- **model_fetcher.py**:包含下載模型文件的函數(如果模型文件尚未存在)。 +- **monitor_logger.py**:包含 [`LoggerConfig`](./src/monitor_logger.py) 類別,用於設置應用日誌記錄,支援控制台和文件輸出。 +- **stream_capture.py**:包含 [`StreamCapture`](./src/stream_capture.py) 類別,用於從視頻串流中捕獲影像。 +- **stream_viewer.py**:包含 [`StreamViewer`](./src/stream_viewer.py) 類別,用於觀看視頻串流。 + +### 通知模組 + +- **notifiers/broadcast_notifier.py**:包含 [`BroadcastNotifier`](./src/notifiers/broadcast_notifier.py) 類別,用於向廣播系統發送訊息。 +- **notifiers/line_notifier.py**:包含 [`LineNotifier`](./src/notifiers/line_notifier.py) 類別,用於通過 LINE Notify 發送通知。 +- **notifiers/messenger_notifier.py**:包含 [`MessengerNotifier`](./src/notifiers/messenger_notifier.py) 類別,用於通過 Facebook Messenger 發送通知。 +- **notifiers/telegram_notifier.py**:包含 [`TelegramNotifier`](./src/notifiers/telegram_notifier.py) 類別,用於通過 Telegram 發送通知。 +- **notifiers/wechat_notifier.py**:包含 [`WeChatNotifier`](./src/notifiers/wechat_notifier.py) 類別,用於通過 WeChat Work 發送通知。 + +## 使用方式 + +### 設定環境變數 + +請確保在專案根目錄中有 `.env` 文件,並包含各通知模組所需的環境變數,例如: + +``` +WECHAT_CORP_ID=your_wechat_corp_id +WECHAT_CORP_SECRET=your_wechat_corp_secret +WECHAT_AGENT_ID=your_wechat_agent_id +TELEGRAM_BOT_TOKEN=your_telegram_bot_token +FACEBOOK_PAGE_ACCESS_TOKEN=your_facebook_page_access_token +LINE_NOTIFY_TOKEN=your_line_notify_token +``` + +### 執行腳本 + +每個腳本可以單獨執行。例如,要執行 `live_stream_tracker.py` 腳本: + +```bash +python live_stream_tracker.py --url --model +``` + +### 使用範例 + +請參考每個腳本中的 `main` 函數以了解使用範例。 diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..b20cc9b --- /dev/null +++ b/src/README.md @@ -0,0 +1,77 @@ +🇬🇧 [English](./src/README.md) | 🇹🇼 [繁體中文](./src/README-zh-tw.md) + +## Overview + +This repository contains a collection of Python scripts designed for various functionalities including live stream detection, drawing management, model fetching, logging, and sending notifications through different platforms. The project is structured to facilitate easy integration and usage of these functionalities. + +## Directory Structure + +``` +src +├── danger_detector.py +├── drawing_manager.py +├── __init__.py +├── lang_config.py +├── live_stream_detection.py +├── live_stream_tracker.py +├── model_fetcher.py +├── monitor_logger.py +├── notifiers +│ ├── broadcast_notifier.py +│ ├── __init__.py +│ ├── line_notifier.py +│ ├── messenger_notifier.py +│   ├── telegram_notifier.py +│   └── wechat_notifier.py +├── stream_capture.py +└── stream_viewer.py +``` + +## File Descriptions + +### Main Modules + +- **danger_detector.py**: Contains the [`DangerDetector`](./src/danger_detector.py) class for detecting potential safety hazards based on detection data. +- **drawing_manager.py**: Contains the [`DrawingManager`](./src/drawing_manager.py) class for drawing detections on frames and saving them. +- **lang_config.py**: Configuration file for language settings. +- **live_stream_detection.py**: Contains the [`LiveStreamDetector`](./src/live_stream_detection.py) class for performing live stream detection and tracking using YOLOv8 with SAHI. +- **live_stream_tracker.py**: Contains the [`LiveStreamDetector`](./src/live_stream_tracker.py) class for performing live stream detection and tracking using YOLOv8. +- **model_fetcher.py**: Contains functions to download model files if they do not already exist. +- **monitor_logger.py**: Contains the [`LoggerConfig`](./src/monitor_logger.py) class for setting up application logging with console and file handlers. +- **stream_capture.py**: Contains the [`StreamCapture`](./src/stream_capture.py) class for capturing frames from a video stream. +- **stream_viewer.py**: Contains the [`StreamViewer`](./src/stream_viewer.py) class for viewing video streams. + +### Notifiers + +- **notifiers/broadcast_notifier.py**: Contains the [`BroadcastNotifier`](./src/notifiers/broadcast_notifier.py) class for sending messages to a broadcast system. +- **notifiers/line_notifier.py**: Contains the [`LineNotifier`](./src/notifiers/line_notifier.py) class for sending notifications via LINE Notify. +- **notifiers/messenger_notifier.py**: Contains the [`MessengerNotifier`](./src/notifiers/messenger_notifier.py) class for sending notifications via Facebook Messenger. +- **notifiers/telegram_notifier.py**: Contains the [`TelegramNotifier`](./src/notifiers/telegram_notifier.py) class for sending notifications via Telegram. +- **notifiers/wechat_notifier.py**: Contains the [`WeChatNotifier`](./src/notifiers/wechat_notifier.py) class for sending notifications via WeChat Work. + +## Usage + +### Setting Up Environment Variables + +Ensure you have a `.env` file in the root directory with the necessary environment variables for the notifiers, such as: + +``` +WECHAT_CORP_ID=your_wechat_corp_id +WECHAT_CORP_SECRET=your_wechat_corp_secret +WECHAT_AGENT_ID=your_wechat_agent_id +TELEGRAM_BOT_TOKEN=your_telegram_bot_token +FACEBOOK_PAGE_ACCESS_TOKEN=your_facebook_page_access_token +LINE_NOTIFY_TOKEN=your_line_notify_token +``` + +### Running the Scripts + +Each script can be run individually. For example, to run the `live_stream_tracker.py` script: + +```bash +python live_stream_tracker.py --url --model +``` + +### Example Usage + +Refer to the `main` function in each script for example usage. diff --git a/tests/examples/YOLOv8_data_augmentation/__init__.py b/tests/examples/YOLO_data_augmentation/__init__.py similarity index 100% rename from tests/examples/YOLOv8_data_augmentation/__init__.py rename to tests/examples/YOLO_data_augmentation/__init__.py diff --git a/tests/examples/YOLOv8_data_augmentation/data_augmentation_albumentations_test.py b/tests/examples/YOLO_data_augmentation/data_augmentation_albumentations_test.py similarity index 89% rename from tests/examples/YOLOv8_data_augmentation/data_augmentation_albumentations_test.py rename to tests/examples/YOLO_data_augmentation/data_augmentation_albumentations_test.py index 5b80a05..055ab03 100644 --- a/tests/examples/YOLOv8_data_augmentation/data_augmentation_albumentations_test.py +++ b/tests/examples/YOLO_data_augmentation/data_augmentation_albumentations_test.py @@ -3,7 +3,7 @@ from unittest.mock import patch, MagicMock from pathlib import Path import numpy as np -from examples.YOLOv8_data_augmentation.data_augmentation_albumentations import DataAugmentation, main +from examples.YOLO_data_augmentation.data_augmentation_albumentations import DataAugmentation, main class TestDataAugmentation(unittest.TestCase): """ @@ -18,7 +18,7 @@ def setUp(self) -> None: self.num_augmentations = 2 self.augmenter = DataAugmentation(self.train_path, self.num_augmentations) - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.cv2.imread') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.cv2.imread') @patch('builtins.print') def test_augment_image_exception(self, mock_print: MagicMock, mock_imread: MagicMock) -> None: """ @@ -49,8 +49,8 @@ def test_augment_image_none(self, mock_print: MagicMock) -> None: self.augmenter.augment_image(None) mock_print.assert_any_call('Error processing image: None') - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.cv2.imread') - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.cv2.cvtColor') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.cv2.imread') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.cv2.cvtColor') def test_augment_image(self, mock_cvtColor: MagicMock, mock_imread: MagicMock) -> None: """ Test augment_image method with valid image data. @@ -69,16 +69,16 @@ def test_augment_image(self, mock_cvtColor: MagicMock, mock_imread: MagicMock) - with patch.object(self.augmenter, 'read_label_file', return_value=(mock_class_labels, mock_bboxes)): with patch.object(self.augmenter, 'write_label_file') as mock_write_label_file: - with patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.cv2.imwrite') as mock_imwrite: + with patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.cv2.imwrite') as mock_imwrite: self.augmenter.augment_image(Path('image.jpg')) self.assertTrue(mock_imread.called) self.assertTrue(mock_cvtColor.called) self.assertTrue(mock_imwrite.called) self.assertTrue(mock_write_label_file.called) - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.cv2.imread') - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.cv2.cvtColor') - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.cv2.imwrite') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.cv2.imread') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.cv2.cvtColor') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.cv2.imwrite') def test_augment_image_with_alpha_channel(self, mock_imwrite: MagicMock, mock_cvtColor: MagicMock, mock_imread: MagicMock) -> None: """ Test augment_image method with an image that has an alpha channel. @@ -143,7 +143,7 @@ def test_random_crop_with_random_size(self) -> None: self.assertTrue(400 <= cropped_image.shape[0] <= 800) self.assertTrue(400 <= cropped_image.shape[1] <= 800) - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.ProcessPoolExecutor') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.ProcessPoolExecutor') def test_augment_data(self, mock_executor: MagicMock) -> None: """ Test augment_data method. @@ -177,7 +177,7 @@ def test_write_label_file(self) -> None: self.augmenter.write_label_file(bboxes_aug, class_labels_aug, label_path) mock_file().write.assert_called_with('0 0.5 0.5 0.2 0.2\n') - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.random.shuffle') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.random.shuffle') def test_shuffle_data(self, mock_shuffle: MagicMock) -> None: """ Test shuffle_data method. @@ -196,7 +196,7 @@ def test_shuffle_data(self, mock_shuffle: MagicMock) -> None: self.assertTrue(mock_shuffle.called) self.assertTrue(mock_rename.called) - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.DataAugmentation') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.DataAugmentation') @patch('argparse.ArgumentParser.parse_args') def test_main(self, mock_parse_args: MagicMock, MockDataAugmentation: MagicMock) -> None: """ @@ -228,7 +228,7 @@ def test_main(self, mock_parse_args: MagicMock, MockDataAugmentation: MagicMock) mock_augmenter.augment_data.assert_called_once_with(batch_size=5) mock_augmenter.shuffle_data.assert_called_once() - @patch('examples.YOLOv8_data_augmentation.data_augmentation_albumentations.DataAugmentation') + @patch('examples.YOLO_data_augmentation.data_augmentation_albumentations.DataAugmentation') @patch('argparse.ArgumentParser.parse_args') def test_main_exception(self, mock_parse_args: MagicMock, MockDataAugmentation: MagicMock) -> None: """ diff --git a/tests/examples/YOLOv8_data_augmentation/data_augmentation_test.py b/tests/examples/YOLO_data_augmentation/data_augmentation_test.py similarity index 78% rename from tests/examples/YOLOv8_data_augmentation/data_augmentation_test.py rename to tests/examples/YOLO_data_augmentation/data_augmentation_test.py index f296020..a89a835 100644 --- a/tests/examples/YOLOv8_data_augmentation/data_augmentation_test.py +++ b/tests/examples/YOLO_data_augmentation/data_augmentation_test.py @@ -9,10 +9,10 @@ import numpy as np -from examples.YOLOv8_data_augmentation.data_augmentation import ( +from examples.YOLO_data_augmentation.data_augmentation import ( DataAugmentation, ) -from examples.YOLOv8_data_augmentation.data_augmentation import main +from examples.YOLO_data_augmentation.data_augmentation import main class TestDataAugmentation(unittest.TestCase): @@ -27,30 +27,30 @@ def setUp(self) -> None: ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.imageio.imread', + 'examples.YOLO_data_augmentation.data_augmentation.imageio.imread', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.imageio.imwrite', + 'examples.YOLO_data_augmentation.data_augmentation.imageio.imwrite', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.glob', + 'examples.YOLO_data_augmentation.data_augmentation.Path.glob', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'iaa.Sequential.__call__', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.open', + 'examples.YOLO_data_augmentation.data_augmentation.Path.open', new_callable=mock_open, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.write_text', + 'examples.YOLO_data_augmentation.data_augmentation.Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.write_bytes', + 'examples.YOLO_data_augmentation.data_augmentation.Path.write_bytes', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.rename', + 'examples.YOLO_data_augmentation.data_augmentation.Path.rename', ) def test_augment_image( self, @@ -98,27 +98,27 @@ def test_augment_image( self.assertEqual(mock_augmented_image.shape[2], 3) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.glob', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'gc.collect', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'DataAugmentation.augment_image', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_bytes', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.rename', ) def test_augment_data( @@ -152,12 +152,12 @@ def test_augment_data( read_data='5 0.5 0.5 0.75 0.75\n', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.exists', return_value=True, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.open', new_callable=mock_open, ) @@ -185,29 +185,29 @@ def test_read_label_file( @patch('builtins.open', new_callable=mock_open) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.exists', return_value=True, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.mkdir', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.parent', new_callable=MagicMock, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_bytes', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.rename', ) def test_write_label_file( @@ -247,23 +247,23 @@ def test_write_label_file( mock_rename.assert_not_called() @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.glob', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'random.shuffle', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.rename', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_bytes', ) def test_shuffle_data( @@ -291,7 +291,7 @@ def test_shuffle_data( ] with patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'uuid.uuid4', side_effect=[f'uuid_{i:02d}' for i in range(5)], ): @@ -312,19 +312,19 @@ def test_shuffle_data( ], ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'DataAugmentation.shuffle_data', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'DataAugmentation.augment_data', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_bytes', ) def test_main( @@ -346,31 +346,31 @@ def test_main( mock_write_bytes.assert_not_called() @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imread', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imwrite', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.glob') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.glob') @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'iaa.Sequential.__call__', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.open', + 'examples.YOLO_data_augmentation.data_augmentation.Path.open', new_callable=unittest.mock.mock_open, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.' + 'examples.YOLO_data_augmentation.data_augmentation.Path.' 'write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.' + 'examples.YOLO_data_augmentation.data_augmentation.Path.' 'write_bytes', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.rename') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.rename') def test_augment_image_resize_small( self, mock_rename: MagicMock, @@ -418,31 +418,31 @@ def test_augment_image_resize_small( mock_rename.assert_not_called() @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imread', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imwrite', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.glob') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.glob') @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'iaa.Sequential.__call__', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.open', + 'examples.YOLO_data_augmentation.data_augmentation.Path.open', new_callable=unittest.mock.mock_open, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_bytes', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.rename') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.rename') def test_augment_image_resize_large( self, mock_rename: MagicMock, @@ -490,31 +490,31 @@ def test_augment_image_resize_large( mock_rename.assert_not_called() @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imread', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imwrite', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.glob') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.glob') @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'iaa.Sequential.__call__', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.open', + 'examples.YOLO_data_augmentation.data_augmentation.Path.open', new_callable=mock_open, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_bytes', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.rename') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.rename') def test_augment_image_none( self, mock_rename: MagicMock, @@ -557,31 +557,31 @@ def test_augment_image_none( mock_rename.assert_not_called() @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imread', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imwrite', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.glob') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.glob') @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.iaa.' + 'examples.YOLO_data_augmentation.data_augmentation.iaa.' 'Sequential.__call__', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.Path.open', + 'examples.YOLO_data_augmentation.data_augmentation.Path.open', new_callable=mock_open, ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_text', ) @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'Path.write_bytes', ) - @patch('examples.YOLOv8_data_augmentation.data_augmentation.Path.rename') + @patch('examples.YOLO_data_augmentation.data_augmentation.Path.rename') def test_augment_image_no_shape( self, mock_rename: MagicMock, @@ -626,7 +626,7 @@ def test_augment_image_no_shape( mock_rename.assert_not_called() @patch( - 'examples.YOLOv8_data_augmentation.data_augmentation.' + 'examples.YOLO_data_augmentation.data_augmentation.' 'imageio.imread', ) @patch('builtins.print') diff --git a/tests/examples/YOLOv8_data_augmentation/visualise_bounding_boxes_test.py b/tests/examples/YOLO_data_augmentation/visualise_bounding_boxes_test.py similarity index 88% rename from tests/examples/YOLOv8_data_augmentation/visualise_bounding_boxes_test.py rename to tests/examples/YOLO_data_augmentation/visualise_bounding_boxes_test.py index 6b983f9..314a9e3 100644 --- a/tests/examples/YOLOv8_data_augmentation/visualise_bounding_boxes_test.py +++ b/tests/examples/YOLO_data_augmentation/visualise_bounding_boxes_test.py @@ -7,10 +7,10 @@ import numpy as np -from examples.YOLOv8_data_augmentation.visualise_bounding_boxes import ( +from examples.YOLO_data_augmentation.visualise_bounding_boxes import ( BoundingBoxVisualiser, ) -from examples.YOLOv8_data_augmentation.visualise_bounding_boxes import main +from examples.YOLO_data_augmentation.visualise_bounding_boxes import main class TestBoundingBoxVisualiser(unittest.TestCase): @@ -39,7 +39,7 @@ def tearDown(self) -> None: self.visualiser = None @patch( - 'examples.YOLOv8_data_augmentation.' + 'examples.YOLO_data_augmentation.' 'visualise_bounding_boxes.cv2.imread', return_value=None, ) @@ -63,7 +63,7 @@ def test_image_loading_failure(self, mock_imread: Any) -> None: read_data='0 0.5 0.5 0.5 0.5\n', ) @patch( - 'examples.YOLOv8_data_augmentation.' + 'examples.YOLO_data_augmentation.' 'visualise_bounding_boxes.cv2.imread', ) def test_draw_bounding_boxes( @@ -90,11 +90,11 @@ def test_draw_bounding_boxes( mock_file.assert_called_once_with('r') @patch( - 'examples.YOLOv8_data_augmentation.' + 'examples.YOLO_data_augmentation.' 'visualise_bounding_boxes.cv2.imwrite', ) @patch( - 'examples.YOLOv8_data_augmentation.' + 'examples.YOLO_data_augmentation.' 'visualise_bounding_boxes.cv2.imread', ) def test_save_image( @@ -119,15 +119,15 @@ def test_save_image( mock_imwrite.assert_called_once_with('output.jpg', mock_image) @patch( - 'examples.YOLOv8_data_augmentation.' + 'examples.YOLO_data_augmentation.' 'visualise_bounding_boxes.plt.show', ) @patch( - 'examples.YOLOv8_data_augmentation.' + 'examples.YOLO_data_augmentation.' 'visualise_bounding_boxes.plt.imshow', ) @patch( - 'examples.YOLOv8_data_augmentation.' + 'examples.YOLO_data_augmentation.' 'visualise_bounding_boxes.cv2.imread', ) def test_display_image( @@ -160,16 +160,16 @@ def test_display_image( ], ) @patch( - 'examples.YOLOv8_data_augmentation.visualise_bounding_boxes.' + 'examples.YOLO_data_augmentation.visualise_bounding_boxes.' 'BoundingBoxVisualiser.__init__', return_value=None, ) @patch( - 'examples.YOLOv8_data_augmentation.visualise_bounding_boxes.' + 'examples.YOLO_data_augmentation.visualise_bounding_boxes.' 'BoundingBoxVisualiser.draw_bounding_boxes', ) @patch( - 'examples.YOLOv8_data_augmentation.visualise_bounding_boxes.' + 'examples.YOLO_data_augmentation.visualise_bounding_boxes.' 'BoundingBoxVisualiser.save_or_display_image', ) def test_main( diff --git a/tests/examples/YOLOv8_evaluation/__init__.py b/tests/examples/YOLO_evaluation/__init__.py similarity index 100% rename from tests/examples/YOLOv8_evaluation/__init__.py rename to tests/examples/YOLO_evaluation/__init__.py diff --git a/tests/examples/YOLOv8_evaluation/convert_yolo_to_coco_test.py b/tests/examples/YOLO_evaluation/convert_yolo_to_coco_test.py similarity index 92% rename from tests/examples/YOLOv8_evaluation/convert_yolo_to_coco_test.py rename to tests/examples/YOLO_evaluation/convert_yolo_to_coco_test.py index bcd7b5e..d8d8be2 100644 --- a/tests/examples/YOLOv8_evaluation/convert_yolo_to_coco_test.py +++ b/tests/examples/YOLO_evaluation/convert_yolo_to_coco_test.py @@ -7,8 +7,8 @@ from unittest.mock import mock_open from unittest.mock import patch -from examples.YOLOv8_evaluation.convert_yolo_to_coco import COCOConverter -from examples.YOLOv8_evaluation.convert_yolo_to_coco import main +from examples.YOLO_evaluation.convert_yolo_to_coco import COCOConverter +from examples.YOLO_evaluation.convert_yolo_to_coco import main class TestCOCOConverter(unittest.TestCase): @@ -26,9 +26,9 @@ def tearDown(self): # Clear the COCO format data to avoid state leakage between tests self.converter.coco_format.clear() - @patch('examples.YOLOv8_evaluation.convert_yolo_to_coco.os.listdir') - @patch('examples.YOLOv8_evaluation.convert_yolo_to_coco.os.path.exists') - @patch('examples.YOLOv8_evaluation.convert_yolo_to_coco.Image.open') + @patch('examples.YOLO_evaluation.convert_yolo_to_coco.os.listdir') + @patch('examples.YOLO_evaluation.convert_yolo_to_coco.os.path.exists') + @patch('examples.YOLO_evaluation.convert_yolo_to_coco.Image.open') @patch( 'builtins.open', new_callable=mock_open, @@ -132,11 +132,11 @@ def test_initialise_categories(self, mock_file): self.assertEqual(categories[i]['id'], i + 1) @patch( - 'examples.YOLOv8_evaluation.convert_yolo_to_coco.' + 'examples.YOLO_evaluation.convert_yolo_to_coco.' 'COCOConverter.convert_annotations', ) @patch( - 'examples.YOLOv8_evaluation.convert_yolo_to_coco.' + 'examples.YOLO_evaluation.convert_yolo_to_coco.' 'COCOConverter.save_to_json', ) @patch('argparse.ArgumentParser.parse_args') diff --git a/tests/examples/YOLOv8_evaluation/evaluate_sahi_yolov8_test.py b/tests/examples/YOLO_evaluation/evaluate_sahi_yolo_test.py similarity index 89% rename from tests/examples/YOLOv8_evaluation/evaluate_sahi_yolov8_test.py rename to tests/examples/YOLO_evaluation/evaluate_sahi_yolo_test.py index 145a165..9d284e5 100644 --- a/tests/examples/YOLOv8_evaluation/evaluate_sahi_yolov8_test.py +++ b/tests/examples/YOLO_evaluation/evaluate_sahi_yolo_test.py @@ -7,8 +7,8 @@ import numpy as np -from examples.YOLOv8_evaluation.evaluate_sahi_yolov8 import COCOEvaluator -from examples.YOLOv8_evaluation.evaluate_sahi_yolov8 import main +from examples.YOLO_evaluation.evaluate_sahi_yolo import COCOEvaluator +from examples.YOLO_evaluation.evaluate_sahi_yolo import main class TestCOCOEvaluator(unittest.TestCase): @@ -29,19 +29,19 @@ def tearDown(self) -> None: del self.evaluator @patch( - 'examples.YOLOv8_evaluation.evaluate_sahi_yolov8.' + 'examples.YOLO_evaluation.evaluate_sahi_yolo.' 'AutoDetectionModel.from_pretrained', ) @patch( - 'examples.YOLOv8_evaluation.evaluate_sahi_yolov8.' + 'examples.YOLO_evaluation.evaluate_sahi_yolo.' 'get_sliced_prediction', ) @patch( - 'examples.YOLOv8_evaluation.evaluate_sahi_yolov8.' + 'examples.YOLO_evaluation.evaluate_sahi_yolo.' 'Coco.from_coco_dict_or_path', ) - @patch('examples.YOLOv8_evaluation.evaluate_sahi_yolov8.COCO') - @patch('examples.YOLOv8_evaluation.evaluate_sahi_yolov8.COCOeval') + @patch('examples.YOLO_evaluation.evaluate_sahi_yolo.COCO') + @patch('examples.YOLO_evaluation.evaluate_sahi_yolo.COCOeval') def test_evaluate( self, mock_cocoeval: MagicMock, @@ -104,7 +104,7 @@ def test_evaluate( self.assertEqual(metrics, expected_metrics) @patch( - 'examples.YOLOv8_evaluation.evaluate_sahi_yolov8.' + 'examples.YOLO_evaluation.evaluate_sahi_yolo.' 'COCOEvaluator.evaluate', ) @patch( diff --git a/tests/examples/YOLOv8_evaluation/evaluate_yolov8_test.py b/tests/examples/YOLO_evaluation/evaluate_yolo_test.py similarity index 90% rename from tests/examples/YOLOv8_evaluation/evaluate_yolov8_test.py rename to tests/examples/YOLO_evaluation/evaluate_yolo_test.py index 7ce127f..25d38fe 100644 --- a/tests/examples/YOLOv8_evaluation/evaluate_yolov8_test.py +++ b/tests/examples/YOLO_evaluation/evaluate_yolo_test.py @@ -6,8 +6,8 @@ from unittest.mock import MagicMock from unittest.mock import patch -from examples.YOLOv8_evaluation.evaluate_yolov8 import main -from examples.YOLOv8_evaluation.evaluate_yolov8 import ModelEvaluator +from examples.YOLO_evaluation.evaluate_yolo import main +from examples.YOLO_evaluation.evaluate_yolo import ModelEvaluator class TestModelEvaluator(unittest.TestCase): @@ -22,7 +22,7 @@ def tearDown(self) -> None: """ self.evaluator = None - @patch('examples.YOLOv8_evaluation.evaluate_yolov8.YOLO') + @patch('examples.YOLO_evaluation.evaluate_yolo.YOLO') def test_evaluate(self, mock_yolo: MagicMock) -> None: """ Test the evaluate method to ensure it returns the expected results. @@ -49,7 +49,7 @@ def test_evaluate(self, mock_yolo: MagicMock) -> None: mock_yolo.assert_called_once_with(self.model_path) self.assertEqual(results, expected_results) - @patch('examples.YOLOv8_evaluation.evaluate_yolov8.ModelEvaluator') + @patch('examples.YOLO_evaluation.evaluate_yolo.ModelEvaluator') @patch('argparse.ArgumentParser.parse_args') def test_main( self, diff --git a/tests/examples/YOLOv8_server_api/__init__.py b/tests/examples/YOLO_server_api/__init__.py similarity index 100% rename from tests/examples/YOLOv8_server_api/__init__.py rename to tests/examples/YOLO_server_api/__init__.py diff --git a/tests/examples/YOLOv8_server_api/auth_test.py b/tests/examples/YOLO_server_api/auth_test.py similarity index 92% rename from tests/examples/YOLOv8_server_api/auth_test.py rename to tests/examples/YOLO_server_api/auth_test.py index ce76144..e68a8fb 100644 --- a/tests/examples/YOLOv8_server_api/auth_test.py +++ b/tests/examples/YOLO_server_api/auth_test.py @@ -9,8 +9,8 @@ from flask.testing import FlaskClient from flask_jwt_extended import JWTManager -from examples.YOLOv8_server_api.auth import auth_blueprint -from examples.YOLOv8_server_api.models import db +from examples.YOLO_server_api.auth import auth_blueprint +from examples.YOLO_server_api.models import db jwt = JWTManager() @@ -60,8 +60,8 @@ def tearDown(self) -> None: db.drop_all() self.app_context.pop() - @patch('examples.YOLOv8_server_api.auth.user_cache') - @patch('examples.YOLOv8_server_api.auth.User.query') + @patch('examples.YOLO_server_api.auth.user_cache') + @patch('examples.YOLO_server_api.auth.User.query') def test_create_token_success_with_cache( self, mock_user_query: MagicMock, @@ -95,8 +95,8 @@ def test_create_token_success_with_cache( else: self.fail('response.json is None') - @patch('examples.YOLOv8_server_api.auth.user_cache') - @patch('examples.YOLOv8_server_api.auth.User.query') + @patch('examples.YOLO_server_api.auth.user_cache') + @patch('examples.YOLO_server_api.auth.User.query') def test_create_token_success_with_db( self, mock_user_query: MagicMock, @@ -137,8 +137,8 @@ def test_create_token_success_with_db( else: self.fail('response.json is None') - @patch('examples.YOLOv8_server_api.auth.user_cache') - @patch('examples.YOLOv8_server_api.auth.User.query') + @patch('examples.YOLO_server_api.auth.user_cache') + @patch('examples.YOLO_server_api.auth.User.query') def test_create_token_invalid_credentials( self, mock_user_query: MagicMock, @@ -178,8 +178,8 @@ def test_create_token_invalid_credentials( else: self.fail('response.json is None') - @patch('examples.YOLOv8_server_api.auth.User.query') - @patch('examples.YOLOv8_server_api.auth.user_cache') + @patch('examples.YOLO_server_api.auth.User.query') + @patch('examples.YOLO_server_api.auth.user_cache') def test_create_token_user_not_in_db_or_cache( self, mock_user_cache: MagicMock, diff --git a/tests/examples/YOLOv8_server_api/cache_test.py b/tests/examples/YOLO_server_api/cache_test.py similarity index 96% rename from tests/examples/YOLOv8_server_api/cache_test.py rename to tests/examples/YOLO_server_api/cache_test.py index 4d1a576..82467d4 100644 --- a/tests/examples/YOLOv8_server_api/cache_test.py +++ b/tests/examples/YOLO_server_api/cache_test.py @@ -2,7 +2,7 @@ import unittest -from examples.YOLOv8_server_api.cache import user_cache +from examples.YOLO_server_api.cache import user_cache class CacheTestCase(unittest.TestCase): diff --git a/tests/examples/YOLOv8_server_api/config_test.py b/tests/examples/YOLO_server_api/config_test.py similarity index 98% rename from tests/examples/YOLOv8_server_api/config_test.py rename to tests/examples/YOLO_server_api/config_test.py index 50151a7..ec8e575 100644 --- a/tests/examples/YOLOv8_server_api/config_test.py +++ b/tests/examples/YOLO_server_api/config_test.py @@ -5,7 +5,7 @@ from importlib import reload from unittest.mock import patch -import examples.YOLOv8_server_api.config as config_module +import examples.YOLO_server_api.config as config_module class TestConfig(unittest.TestCase): diff --git a/tests/examples/YOLOv8_server_api/detection_test.py b/tests/examples/YOLO_server_api/detection_test.py similarity index 90% rename from tests/examples/YOLOv8_server_api/detection_test.py rename to tests/examples/YOLO_server_api/detection_test.py index c4098b7..35529e4 100644 --- a/tests/examples/YOLOv8_server_api/detection_test.py +++ b/tests/examples/YOLO_server_api/detection_test.py @@ -12,16 +12,16 @@ from flask_limiter import Limiter from flask_limiter.util import get_remote_address -from examples.YOLOv8_server_api.detection import calculate_overlap -from examples.YOLOv8_server_api.detection import check_containment -from examples.YOLOv8_server_api.detection import compile_detection_data -from examples.YOLOv8_server_api.detection import detection_blueprint -from examples.YOLOv8_server_api.detection import DetectionModelManager -from examples.YOLOv8_server_api.detection import is_contained -from examples.YOLOv8_server_api.detection import ( +from examples.YOLO_server_api.detection import calculate_overlap +from examples.YOLO_server_api.detection import check_containment +from examples.YOLO_server_api.detection import compile_detection_data +from examples.YOLO_server_api.detection import detection_blueprint +from examples.YOLO_server_api.detection import DetectionModelManager +from examples.YOLO_server_api.detection import is_contained +from examples.YOLO_server_api.detection import ( remove_completely_contained_labels, ) -from examples.YOLOv8_server_api.detection import remove_overlapping_labels +from examples.YOLO_server_api.detection import remove_overlapping_labels class TestDetectionAPI(unittest.TestCase): diff --git a/tests/examples/YOLOv8_server_api/model_downloader_test.py b/tests/examples/YOLO_server_api/model_downloader_test.py similarity index 82% rename from tests/examples/YOLOv8_server_api/model_downloader_test.py rename to tests/examples/YOLO_server_api/model_downloader_test.py index 28ac114..e3c125d 100644 --- a/tests/examples/YOLOv8_server_api/model_downloader_test.py +++ b/tests/examples/YOLO_server_api/model_downloader_test.py @@ -7,7 +7,7 @@ import requests from flask import Flask -from examples.YOLOv8_server_api.model_downloader import models_blueprint +from examples.YOLO_server_api.model_downloader import models_blueprint class ModelDownloaderTestCase(unittest.TestCase): @@ -27,8 +27,8 @@ def tearDown(self): del self.client del self.app - @patch('examples.YOLOv8_server_api.model_downloader.requests.head') - @patch('examples.YOLOv8_server_api.model_downloader.send_from_directory') + @patch('examples.YOLO_server_api.model_downloader.requests.head') + @patch('examples.YOLO_server_api.model_downloader.send_from_directory') def test_download_model_up_to_date( self, mock_send_from_directory, @@ -50,22 +50,22 @@ def test_download_model_up_to_date( # Mock the stat method to simulate an up-to-date file with patch( - 'examples.YOLOv8_server_api.model_downloader.Path.stat', + 'examples.YOLO_server_api.model_downloader.Path.stat', ) as mock_stat: # Corresponding to 'Wed, 22 Sep 2023 10:00:00 GMT' mock_stat.return_value.st_mtime = 1695386400.0 # Ensure the path exists and is correct with patch( - 'examples.YOLOv8_server_api.model_downloader.Path.exists', + 'examples.YOLO_server_api.model_downloader.Path.exists', return_value=True, ): response = self.client.get('/models/best_yolov8l.pt') self.assertEqual(response.status_code, 304) - @patch('examples.YOLOv8_server_api.model_downloader.requests.head') - @patch('examples.YOLOv8_server_api.model_downloader.send_from_directory') + @patch('examples.YOLO_server_api.model_downloader.requests.head') + @patch('examples.YOLO_server_api.model_downloader.send_from_directory') def test_download_model_not_found( self, mock_send_from_directory, @@ -79,8 +79,8 @@ def test_download_model_not_found( self.assertEqual(response.status_code, 404) self.assertIn(b'Model not found.', response.data) - @patch('examples.YOLOv8_server_api.model_downloader.requests.head') - @patch('examples.YOLOv8_server_api.model_downloader.send_from_directory') + @patch('examples.YOLO_server_api.model_downloader.requests.head') + @patch('examples.YOLO_server_api.model_downloader.send_from_directory') def test_download_model_success( self, mock_send_from_directory, @@ -100,7 +100,7 @@ def test_download_model_success( mock_send_from_directory.return_value = MagicMock() with patch( - 'examples.YOLOv8_server_api.model_downloader.Path.stat', + 'examples.YOLO_server_api.model_downloader.Path.stat', ) as mock_stat: # Set the timestamp to match the date in the Last-Modified header # Corresponding to 'Sat, 01 Jan 2000 00:00:00 GMT' @@ -108,7 +108,7 @@ def test_download_model_success( # Ensure the path exists and is correct with patch( - 'examples.YOLOv8_server_api.model_downloader.Path.exists', + 'examples.YOLO_server_api.model_downloader.Path.exists', return_value=True, ): # Update the mock to simulate the file being downloaded @@ -117,7 +117,7 @@ def test_download_model_success( self.assertEqual(response.status_code, 200) mock_send_from_directory.assert_called_once() - @patch('examples.YOLOv8_server_api.model_downloader.requests.head') + @patch('examples.YOLO_server_api.model_downloader.requests.head') def test_download_model_request_exception(self, mock_requests_head): """ Test the download_model endpoint when there is a request exception. diff --git a/tests/examples/YOLOv8_server_api/models_test.py b/tests/examples/YOLO_server_api/models_test.py similarity index 93% rename from tests/examples/YOLOv8_server_api/models_test.py rename to tests/examples/YOLO_server_api/models_test.py index e67d046..3cf6c15 100644 --- a/tests/examples/YOLOv8_server_api/models_test.py +++ b/tests/examples/YOLO_server_api/models_test.py @@ -6,8 +6,8 @@ from unittest.mock import mock_open from unittest.mock import patch -from examples.YOLOv8_server_api.models import DetectionModelManager -from examples.YOLOv8_server_api.models import User +from examples.YOLO_server_api.models import DetectionModelManager +from examples.YOLO_server_api.models import User class TestUserModel(unittest.TestCase): @@ -41,7 +41,7 @@ class TestDetectionModelManager(unittest.TestCase): model_manager: DetectionModelManager @patch( - 'examples.YOLOv8_server_api.models.' + 'examples.YOLO_server_api.models.' 'AutoDetectionModel.from_pretrained', ) @patch('builtins.open', new_callable=mock_open, read_data='dummy data') @@ -74,7 +74,7 @@ def setUp( self.assertIn(name, self.model_manager.models) @patch( - 'examples.YOLOv8_server_api.models.' + 'examples.YOLO_server_api.models.' 'AutoDetectionModel.from_pretrained', ) def test_load_single_model( @@ -100,7 +100,7 @@ def test_load_single_model( ) self.assertEqual(model, mock_model) - @patch('examples.YOLOv8_server_api.models.Path.stat') + @patch('examples.YOLO_server_api.models.Path.stat') def test_get_last_modified_time( self, mock_stat: MagicMock, @@ -124,11 +124,11 @@ def test_get_last_modified_time( mock_stat.assert_called_once_with() @patch( - 'examples.YOLOv8_server_api.models.DetectionModelManager.' + 'examples.YOLO_server_api.models.DetectionModelManager.' 'get_last_modified_times', ) @patch( - 'examples.YOLOv8_server_api.models.DetectionModelManager.' + 'examples.YOLO_server_api.models.DetectionModelManager.' 'load_single_model', ) @patch('time.sleep', return_value=None) @@ -193,7 +193,7 @@ def reload_models_once() -> None: ) @patch( - 'examples.YOLOv8_server_api.models.DetectionModelManager.' + 'examples.YOLO_server_api.models.DetectionModelManager.' 'get_last_modified_time', ) def test_get_last_modified_times( diff --git a/tests/examples/YOLOv8_server_api/security_test.py b/tests/examples/YOLO_server_api/security_test.py similarity index 89% rename from tests/examples/YOLOv8_server_api/security_test.py rename to tests/examples/YOLO_server_api/security_test.py index 2d7eb3c..a121c7c 100644 --- a/tests/examples/YOLOv8_server_api/security_test.py +++ b/tests/examples/YOLO_server_api/security_test.py @@ -5,7 +5,7 @@ from flask import Flask -from examples.YOLOv8_server_api.security import update_secret_key +from examples.YOLO_server_api.security import update_secret_key class TestUpdateSecretKey(unittest.TestCase): @@ -22,7 +22,7 @@ def tearDown(self) -> None: # Delete the Flask app instance del self.app - @patch('examples.YOLOv8_server_api.security.secrets.token_urlsafe') + @patch('examples.YOLO_server_api.security.secrets.token_urlsafe') def test_update_secret_key(self, mock_token_urlsafe): """ Test that the JWT secret key is updated in the Flask app config. diff --git a/tests/examples/YOLOv8_train/__init__.py b/tests/examples/YOLO_train/__init__.py similarity index 100% rename from tests/examples/YOLOv8_train/__init__.py rename to tests/examples/YOLO_train/__init__.py diff --git a/tests/examples/YOLOv8_train/train_test.py b/tests/examples/YOLO_train/train_test.py similarity index 92% rename from tests/examples/YOLOv8_train/train_test.py rename to tests/examples/YOLO_train/train_test.py index 73b0145..c13ddaf 100644 --- a/tests/examples/YOLOv8_train/train_test.py +++ b/tests/examples/YOLO_train/train_test.py @@ -5,8 +5,8 @@ from unittest.mock import MagicMock from unittest.mock import patch -from examples.YOLOv8_train.train import main -from examples.YOLOv8_train.train import YOLOModelHandler +from examples.YOLO_train.train import main +from examples.YOLO_train.train import YOLOModelHandler class TestYOLOModelHandler(unittest.TestCase): @@ -25,7 +25,7 @@ def tearDown(self) -> None: if hasattr(self, 'handler'): del self.handler - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_load_model_with_yaml( self, mock_yolo: unittest.mock.MagicMock, @@ -38,7 +38,7 @@ def test_load_model_with_yaml( mock_yolo.assert_called_with('models/config.yaml') self.assertIsNotNone(handler.model) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') @patch('torch.cuda.is_available') @patch('torch.backends.mps.is_available') def test_load_model_with_pt_and_device_selection( @@ -73,7 +73,7 @@ def test_load_model_with_pt_and_device_selection( mock_yolo.assert_called_with('models/pt/best_yolov8x.pt') self.assertEqual(handler.device.type, 'cpu') - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_load_model(self, mock_yolo: unittest.mock.MagicMock) -> None: """ Test loading a model. @@ -94,7 +94,7 @@ def test_load_model_with_unsupported_format(self) -> None: "Unsupported model format. Use '.yaml' or '.pt'", ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_train_model(self, mock_yolo: unittest.mock.MagicMock) -> None: """ Test training the model. @@ -114,7 +114,7 @@ def test_train_model(self, mock_yolo: unittest.mock.MagicMock) -> None: optimizer='auto', ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_train_model_without_loading( self, mock_yolo: unittest.mock.MagicMock, @@ -131,7 +131,7 @@ def test_train_model_without_loading( 'The model is not loaded properly.', ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_validate_model_without_loading( self, mock_yolo: unittest.mock.MagicMock, @@ -148,7 +148,7 @@ def test_validate_model_without_loading( 'The model is not loaded properly.', ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_predict_image_without_loading( self, mock_yolo: unittest.mock.MagicMock, @@ -165,7 +165,7 @@ def test_predict_image_without_loading( 'The model is not loaded properly.', ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_export_model_without_loading( self, mock_yolo: unittest.mock.MagicMock, @@ -182,7 +182,7 @@ def test_export_model_without_loading( 'The model is not loaded properly.', ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_save_model_without_loading( self, mock_yolo: unittest.mock.MagicMock, @@ -199,7 +199,7 @@ def test_save_model_without_loading( 'The model is not loaded properly.', ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_cross_validate_model_without_loading( self, mock_yolo: unittest.mock.MagicMock, ) -> None: @@ -215,7 +215,7 @@ def test_cross_validate_model_without_loading( 'The model is not loaded properly.', ) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_validate_model(self, mock_yolo: unittest.mock.MagicMock) -> None: """ Test validating the model. @@ -226,7 +226,7 @@ def test_validate_model(self, mock_yolo: unittest.mock.MagicMock) -> None: handler.validate_model() mock_model.val.assert_called_with(batch=handler.batch_size) - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_predict_image(self, mock_yolo: unittest.mock.MagicMock) -> None: """ Test predicting an image. @@ -237,7 +237,7 @@ def test_predict_image(self, mock_yolo: unittest.mock.MagicMock) -> None: handler.predict_image('path/to/image.jpg') mock_model.assert_called_with('path/to/image.jpg') - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.YOLO') def test_export_model(self, mock_yolo: unittest.mock.MagicMock) -> None: """ Test exporting the model. @@ -248,8 +248,8 @@ def test_export_model(self, mock_yolo: unittest.mock.MagicMock) -> None: handler.export_model('onnx') mock_model.export.assert_called_with(format='onnx') - @patch('examples.YOLOv8_train.train.torch.save') - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.torch.save') + @patch('examples.YOLO_train.train.YOLO') def test_save_model( self, mock_yolo: unittest.mock.MagicMock, @@ -266,8 +266,8 @@ def test_save_model( mock_model.state_dict(), 'path/to/save/model.pt', ) - @patch('examples.YOLOv8_train.train.KFold.split') - @patch('examples.YOLOv8_train.train.YOLO') + @patch('examples.YOLO_train.train.KFold.split') + @patch('examples.YOLO_train.train.YOLO') def test_cross_validate_model( self, mock_yolo: unittest.mock.MagicMock, @@ -289,8 +289,8 @@ def test_cross_validate_model( self.assertEqual(mock_model.train.call_count, 2) self.assertEqual(mock_model.val.call_count, 2) - @patch('examples.YOLOv8_train.train.AutoDetectionModel.from_pretrained') - @patch('examples.YOLOv8_train.train.get_sliced_prediction') + @patch('examples.YOLO_train.train.AutoDetectionModel.from_pretrained') + @patch('examples.YOLO_train.train.get_sliced_prediction') def test_predict_image_sahi( self, mock_sahi_predict: unittest.mock.MagicMock, @@ -330,7 +330,7 @@ def test_predict_image_sahi_without_model_path(self) -> None: ) @patch('argparse.ArgumentParser.parse_args') - @patch('examples.YOLOv8_train.train.YOLOModelHandler') + @patch('examples.YOLO_train.train.YOLOModelHandler') def test_main( self, mock_handler_class: unittest.mock.MagicMock, @@ -363,7 +363,7 @@ def test_main( mock_handler.save_model.assert_called_with('model.pt') @patch('argparse.ArgumentParser.parse_args') - @patch('examples.YOLOv8_train.train.YOLOModelHandler') + @patch('examples.YOLO_train.train.YOLOModelHandler') def test_main_with_cross_validate( self, mock_handler_class: unittest.mock.MagicMock, @@ -407,7 +407,7 @@ def test_main_with_cross_validate( mock_handler.export_model.assert_called_with(export_format='onnx') mock_handler.save_model.assert_called_with('model.pt') - @patch('examples.YOLOv8_train.train.YOLOModelHandler.train_model') + @patch('examples.YOLO_train.train.YOLOModelHandler.train_model') @patch('argparse.ArgumentParser.parse_args') def test_main_exception_handling( self,