From a4e3bf381e222fee92cc232255eee371d4f37172 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:21:51 +0800 Subject: [PATCH 01/25] Create image_object_detection --- src/image_object_detection | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/image_object_detection diff --git a/src/image_object_detection b/src/image_object_detection new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/image_object_detection @@ -0,0 +1 @@ + From 12a6503d4e26ea17678c8f9c0bea6ec4a5e834fc Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:24:47 +0800 Subject: [PATCH 02/25] Delete src/image_object_detection --- src/image_object_detection | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/image_object_detection diff --git a/src/image_object_detection b/src/image_object_detection deleted file mode 100644 index 8b13789179..0000000000 --- a/src/image_object_detection +++ /dev/null @@ -1 +0,0 @@ - From 0a15c3fcba88b16ab70b1adf3aa2636c1e61f772 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:25:29 +0800 Subject: [PATCH 03/25] Create image_object_detection --- src/image_object_detection | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/image_object_detection diff --git a/src/image_object_detection b/src/image_object_detection new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/image_object_detection @@ -0,0 +1 @@ + From 42d02ade9541f864960b9ac2482bcca3c3a09f3b Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:26:24 +0800 Subject: [PATCH 04/25] Delete src/image_object_detection --- src/image_object_detection | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/image_object_detection diff --git a/src/image_object_detection b/src/image_object_detection deleted file mode 100644 index 8b13789179..0000000000 --- a/src/image_object_detection +++ /dev/null @@ -1 +0,0 @@ - From acb8b4de9012476c5ab6f5de962a339c3285868b Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:27:06 +0800 Subject: [PATCH 05/25] Create Image_object_detection --- src/Image_object_detection | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/Image_object_detection @@ -0,0 +1 @@ + From 7e0dcb83b37450272fa7cd51a78dacd7b5a8a9cc Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:27:30 +0800 Subject: [PATCH 06/25] Delete src/Image_object_detection --- src/Image_object_detection | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection deleted file mode 100644 index 8b13789179..0000000000 --- a/src/Image_object_detection +++ /dev/null @@ -1 +0,0 @@ - From 7e26f7d825fdee07fc2f5afa070be48156f0259f Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:28:19 +0800 Subject: [PATCH 07/25] Create Image_object_detection --- src/Image_object_detection | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/Image_object_detection @@ -0,0 +1 @@ + From 17f5843806decb84cc2b2651887d2dc84027cf16 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:28:34 +0800 Subject: [PATCH 08/25] Delete src/Image_object_detection --- src/Image_object_detection | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection deleted file mode 100644 index 8b13789179..0000000000 --- a/src/Image_object_detection +++ /dev/null @@ -1 +0,0 @@ - From b7a579aa472f17d6ac477ec5419e33a9f7baa657 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:29:25 +0800 Subject: [PATCH 09/25] Create Image_object_detection --- src/Image_object_detection | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/Image_object_detection @@ -0,0 +1 @@ + From d093821e28c339cf92cbb1d3ab0f262ccbaf643c Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:30:10 +0800 Subject: [PATCH 10/25] Delete src/Image_object_detection --- src/Image_object_detection | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection deleted file mode 100644 index 8b13789179..0000000000 --- a/src/Image_object_detection +++ /dev/null @@ -1 +0,0 @@ - From e96466ea7e95238027fb804dd5f9c366299e60c6 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:31:18 +0800 Subject: [PATCH 11/25] Create Image_object_detection --- src/Image_object_detection | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/Image_object_detection @@ -0,0 +1 @@ + From 044ac8f205d8d5c6ddc2f1051a7d80205abebaf4 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 09:35:33 +0800 Subject: [PATCH 12/25] Delete src/Image_object_detection --- src/Image_object_detection | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/Image_object_detection diff --git a/src/Image_object_detection b/src/Image_object_detection deleted file mode 100644 index 8b13789179..0000000000 --- a/src/Image_object_detection +++ /dev/null @@ -1 +0,0 @@ - From 456f8b1faaa80dbff133e3dda18a3e6120a0e60e Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 8 Dec 2025 11:03:17 +0800 Subject: [PATCH 13/25] Add files via upload --- src/image_object_detection/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/image_object_detection/README.md diff --git a/src/image_object_detection/README.md b/src/image_object_detection/README.md new file mode 100644 index 0000000000..e0c4b707ee --- /dev/null +++ b/src/image_object_detection/README.md @@ -0,0 +1 @@ +这是一个使用 YOLO 训练模型来进行图像对象检测的系统 \ No newline at end of file From 989791c09d95db8a8dfec48f637c34ea2658befe Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 09:21:50 +0800 Subject: [PATCH 14/25] Add files via upload --- src/image_object_detection/main.py | 110 ++++++++++++++++++++ src/image_object_detection/requirements.txt | 15 +++ 2 files changed, 125 insertions(+) create mode 100644 src/image_object_detection/main.py create mode 100644 src/image_object_detection/requirements.txt diff --git a/src/image_object_detection/main.py b/src/image_object_detection/main.py new file mode 100644 index 0000000000..37419ff35f --- /dev/null +++ b/src/image_object_detection/main.py @@ -0,0 +1,110 @@ +# 导入核心库 +from ultralytics import YOLO +import cv2 +import matplotlib.pyplot as plt +import os # 新增:用于路径验证 + +# -------------------------- 1. 基础配置(重点:替换成你的图片路径!) -------------------------- +# 模型路径:YOLOv8n轻量级预训练模型(自动下载) +MODEL_PATH = "yolov8n.pt" + +# 🔥 关键修改:替换成你图片的绝对路径(右键图片→属性→复制完整路径,加r前缀避免转义) +# 示例:IMAGE_PATH = r"C:\Users\apple\OneDrive\桌面\my_test_image.jpg" +IMAGE_PATH = r"C:\Users\apple\OneDrive\桌面\test.jpg" + +# 检测结果保存路径(建议保存到桌面,方便查找) +SAVE_PATH = r"C:\Users\apple\OneDrive\桌面\detected_image.jpg" + +# -------------------------- 2. 加载YOLO模型 -------------------------- +# 加载预训练YOLOv8模型(首次运行自动下载权重,已下载则直接加载) +model = YOLO(MODEL_PATH) + +# -------------------------- 3. 图像检测核心函数(含路径验证) -------------------------- +def detect_image_with_pretrained_model(image_path, save_path): + """ + 用预训练YOLO模型检测图像,包含路径验证和友好报错 + :param image_path: 待检测图片路径 + :param save_path: 检测结果保存路径 + """ + # 第一步:验证图片路径是否存在(核心解决FileNotFoundError) + if not os.path.exists(image_path): + print(f"\n❌ 错误:找不到图片文件!") + print(f"当前设置的图片路径:{image_path}") + print(f"请检查:1. 图片是否存在 2. 路径是否正确 3. 路径无中文/空格/特殊符号\n") + return # 路径错误则终止函数 + + # 第二步:执行目标检测(conf=0.25:只显示置信度≥25%的目标) + print(f"\n✅ 开始检测图片:{image_path}") + results = model(image_path, conf=0.25) + + # 第三步:可视化检测结果(绘制边界框、类别、置信度) + annotated_image = results[0].plot() # 生成带标注的图片 + + # 转换颜色通道(OpenCV默认BGR,Matplotlib显示需要RGB) + annotated_image_rgb = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB) + + # 第四步:显示检测结果图片 + plt.figure(figsize=(12, 8)) + plt.imshow(annotated_image_rgb) + plt.axis("off") # 隐藏坐标轴 + plt.title("YOLOv8 Object Detection Result", fontsize=16) + plt.show() + + # 第五步:保存检测结果到指定路径 + cv2.imwrite(save_path, annotated_image) + print(f"\n✅ 检测结果已保存:{save_path}") + + # 第六步:打印详细检测信息(类别、置信度、坐标) + print("\n📌 检测到的目标信息:") + for result in results: + boxes = result.boxes # 获取所有检测框 + if len(boxes) == 0: + print(" 未检测到任何目标(可降低conf阈值试试,比如conf=0.1)") + continue + for box in boxes: + cls_index = int(box.cls) # 类别索引 + cls_name = model.names[cls_index] # 类别名称(如person/car/cat) + confidence = box.conf.item() # 置信度 + coordinates = box.xyxy.tolist()[0] # 边界框坐标 [x1, y1, x2, y2] + print(f" 类别:{cls_name} | 置信度:{confidence:.2f} | 坐标:{[round(x, 2) for x in coordinates]}") + +# -------------------------- 4. 自定义数据集训练函数(可选) -------------------------- +def train_custom_yolo_model(data_yaml_path, epochs=10, imgsz=640): + """ + 训练自定义YOLO模型(需先准备数据集和.yaml配置文件) + :param data_yaml_path: 数据集配置文件路径(如dataset/data.yaml) + :param epochs: 训练轮数(入门建议10-30) + :param imgsz: 输入图像尺寸 + """ + if not os.path.exists(data_yaml_path): + print(f"\n❌ 错误:数据集配置文件不存在!路径:{data_yaml_path}") + return + + # 加载模型并开始训练 + train_model = YOLO(MODEL_PATH) + train_results = train_model.train( + data=data_yaml_path, + epochs=epochs, + imgsz=imgsz, + batch=-1, # 自动适配批次大小 + device="cpu", # 无GPU则用cpu,有GPU改0 + patience=50, + save=True, + project="runs/train", + name="custom_yolo", + exist_ok=True + ) + # 验证模型 + val_results = train_model.val() + print("\n✅ 自定义模型训练完成!验证集指标:", val_results.results_dict) + +# -------------------------- 主程序运行入口 -------------------------- +if __name__ == "__main__": + # 运行预训练模型检测(核心功能,必执行) + detect_image_with_pretrained_model(IMAGE_PATH, SAVE_PATH) + + # 如需训练自定义数据集,取消下面注释并配置data_yaml_path + # train_custom_yolo_model(data_yaml_path=r"C:\Users\apple\OneDrive\桌面\dataset\data.yaml", epochs=10) + + + diff --git a/src/image_object_detection/requirements.txt b/src/image_object_detection/requirements.txt new file mode 100644 index 0000000000..f1cc19c3c9 --- /dev/null +++ b/src/image_object_detection/requirements.txt @@ -0,0 +1,15 @@ +# YOLOv8核心库(必须) +ultralytics>=8.0.0 # 推荐8.2.0(稳定版) +# 图像处理(必须) +opencv-python>=4.5.0 # 推荐4.8.1.78 +# 可视化(必须) +matplotlib>=3.0.0 # 推荐3.7.1 +# PyTorch核心(ultralytics依赖,必须) +torch>=2.0.0 # 推荐2.0.1或2.1.0 +torchvision>=0.15.0 # 与torch版本匹配 +# 基础数值计算(间接依赖,建议指定) +numpy>=1.21.0 # 推荐1.24.3 +# 可选(补充依赖,避免隐性报错) +pillow>=8.0.0 # 推荐9.5.0 +psutil>=5.8.0 # ultralytics监控系统资源用 +pyyaml>=6.0 # 自定义训练时解析yaml配置文件 \ No newline at end of file From 09aeed328f3ed68906bbdbc6fe423ebeb741d4ec Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 10:40:27 +0800 Subject: [PATCH 15/25] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 项目源代码及其依赖版本 From 556825aea64df3468ae06e5c1e06727c407f0e70 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 10:47:21 +0800 Subject: [PATCH 16/25] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 项目源代码及依赖版本 From e5faaee653d68f8711293235e61c8f46fbd9041e Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 12:03:21 +0800 Subject: [PATCH 17/25] Delete src/image_object_detection/main.py --- src/image_object_detection/main.py | 110 ----------------------------- 1 file changed, 110 deletions(-) delete mode 100644 src/image_object_detection/main.py diff --git a/src/image_object_detection/main.py b/src/image_object_detection/main.py deleted file mode 100644 index 37419ff35f..0000000000 --- a/src/image_object_detection/main.py +++ /dev/null @@ -1,110 +0,0 @@ -# 导入核心库 -from ultralytics import YOLO -import cv2 -import matplotlib.pyplot as plt -import os # 新增:用于路径验证 - -# -------------------------- 1. 基础配置(重点:替换成你的图片路径!) -------------------------- -# 模型路径:YOLOv8n轻量级预训练模型(自动下载) -MODEL_PATH = "yolov8n.pt" - -# 🔥 关键修改:替换成你图片的绝对路径(右键图片→属性→复制完整路径,加r前缀避免转义) -# 示例:IMAGE_PATH = r"C:\Users\apple\OneDrive\桌面\my_test_image.jpg" -IMAGE_PATH = r"C:\Users\apple\OneDrive\桌面\test.jpg" - -# 检测结果保存路径(建议保存到桌面,方便查找) -SAVE_PATH = r"C:\Users\apple\OneDrive\桌面\detected_image.jpg" - -# -------------------------- 2. 加载YOLO模型 -------------------------- -# 加载预训练YOLOv8模型(首次运行自动下载权重,已下载则直接加载) -model = YOLO(MODEL_PATH) - -# -------------------------- 3. 图像检测核心函数(含路径验证) -------------------------- -def detect_image_with_pretrained_model(image_path, save_path): - """ - 用预训练YOLO模型检测图像,包含路径验证和友好报错 - :param image_path: 待检测图片路径 - :param save_path: 检测结果保存路径 - """ - # 第一步:验证图片路径是否存在(核心解决FileNotFoundError) - if not os.path.exists(image_path): - print(f"\n❌ 错误:找不到图片文件!") - print(f"当前设置的图片路径:{image_path}") - print(f"请检查:1. 图片是否存在 2. 路径是否正确 3. 路径无中文/空格/特殊符号\n") - return # 路径错误则终止函数 - - # 第二步:执行目标检测(conf=0.25:只显示置信度≥25%的目标) - print(f"\n✅ 开始检测图片:{image_path}") - results = model(image_path, conf=0.25) - - # 第三步:可视化检测结果(绘制边界框、类别、置信度) - annotated_image = results[0].plot() # 生成带标注的图片 - - # 转换颜色通道(OpenCV默认BGR,Matplotlib显示需要RGB) - annotated_image_rgb = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB) - - # 第四步:显示检测结果图片 - plt.figure(figsize=(12, 8)) - plt.imshow(annotated_image_rgb) - plt.axis("off") # 隐藏坐标轴 - plt.title("YOLOv8 Object Detection Result", fontsize=16) - plt.show() - - # 第五步:保存检测结果到指定路径 - cv2.imwrite(save_path, annotated_image) - print(f"\n✅ 检测结果已保存:{save_path}") - - # 第六步:打印详细检测信息(类别、置信度、坐标) - print("\n📌 检测到的目标信息:") - for result in results: - boxes = result.boxes # 获取所有检测框 - if len(boxes) == 0: - print(" 未检测到任何目标(可降低conf阈值试试,比如conf=0.1)") - continue - for box in boxes: - cls_index = int(box.cls) # 类别索引 - cls_name = model.names[cls_index] # 类别名称(如person/car/cat) - confidence = box.conf.item() # 置信度 - coordinates = box.xyxy.tolist()[0] # 边界框坐标 [x1, y1, x2, y2] - print(f" 类别:{cls_name} | 置信度:{confidence:.2f} | 坐标:{[round(x, 2) for x in coordinates]}") - -# -------------------------- 4. 自定义数据集训练函数(可选) -------------------------- -def train_custom_yolo_model(data_yaml_path, epochs=10, imgsz=640): - """ - 训练自定义YOLO模型(需先准备数据集和.yaml配置文件) - :param data_yaml_path: 数据集配置文件路径(如dataset/data.yaml) - :param epochs: 训练轮数(入门建议10-30) - :param imgsz: 输入图像尺寸 - """ - if not os.path.exists(data_yaml_path): - print(f"\n❌ 错误:数据集配置文件不存在!路径:{data_yaml_path}") - return - - # 加载模型并开始训练 - train_model = YOLO(MODEL_PATH) - train_results = train_model.train( - data=data_yaml_path, - epochs=epochs, - imgsz=imgsz, - batch=-1, # 自动适配批次大小 - device="cpu", # 无GPU则用cpu,有GPU改0 - patience=50, - save=True, - project="runs/train", - name="custom_yolo", - exist_ok=True - ) - # 验证模型 - val_results = train_model.val() - print("\n✅ 自定义模型训练完成!验证集指标:", val_results.results_dict) - -# -------------------------- 主程序运行入口 -------------------------- -if __name__ == "__main__": - # 运行预训练模型检测(核心功能,必执行) - detect_image_with_pretrained_model(IMAGE_PATH, SAVE_PATH) - - # 如需训练自定义数据集,取消下面注释并配置data_yaml_path - # train_custom_yolo_model(data_yaml_path=r"C:\Users\apple\OneDrive\桌面\dataset\data.yaml", epochs=10) - - - From cbe3f1fa350e2090862e11d770ed7e9bb82a8d4f Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 12:03:33 +0800 Subject: [PATCH 18/25] Delete src/image_object_detection/requirements.txt --- src/image_object_detection/requirements.txt | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/image_object_detection/requirements.txt diff --git a/src/image_object_detection/requirements.txt b/src/image_object_detection/requirements.txt deleted file mode 100644 index f1cc19c3c9..0000000000 --- a/src/image_object_detection/requirements.txt +++ /dev/null @@ -1,15 +0,0 @@ -# YOLOv8核心库(必须) -ultralytics>=8.0.0 # 推荐8.2.0(稳定版) -# 图像处理(必须) -opencv-python>=4.5.0 # 推荐4.8.1.78 -# 可视化(必须) -matplotlib>=3.0.0 # 推荐3.7.1 -# PyTorch核心(ultralytics依赖,必须) -torch>=2.0.0 # 推荐2.0.1或2.1.0 -torchvision>=0.15.0 # 与torch版本匹配 -# 基础数值计算(间接依赖,建议指定) -numpy>=1.21.0 # 推荐1.24.3 -# 可选(补充依赖,避免隐性报错) -pillow>=8.0.0 # 推荐9.5.0 -psutil>=5.8.0 # ultralytics监控系统资源用 -pyyaml>=6.0 # 自定义训练时解析yaml配置文件 \ No newline at end of file From de9a2d26ad9b83ffe76a31c699f545721d57ab39 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 17:55:40 +0800 Subject: [PATCH 19/25] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 项目需要的依赖及其版本 --- src/image_object_detection/requirements.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/image_object_detection/requirements.txt diff --git a/src/image_object_detection/requirements.txt b/src/image_object_detection/requirements.txt new file mode 100644 index 0000000000..f1cc19c3c9 --- /dev/null +++ b/src/image_object_detection/requirements.txt @@ -0,0 +1,15 @@ +# YOLOv8核心库(必须) +ultralytics>=8.0.0 # 推荐8.2.0(稳定版) +# 图像处理(必须) +opencv-python>=4.5.0 # 推荐4.8.1.78 +# 可视化(必须) +matplotlib>=3.0.0 # 推荐3.7.1 +# PyTorch核心(ultralytics依赖,必须) +torch>=2.0.0 # 推荐2.0.1或2.1.0 +torchvision>=0.15.0 # 与torch版本匹配 +# 基础数值计算(间接依赖,建议指定) +numpy>=1.21.0 # 推荐1.24.3 +# 可选(补充依赖,避免隐性报错) +pillow>=8.0.0 # 推荐9.5.0 +psutil>=5.8.0 # ultralytics监控系统资源用 +pyyaml>=6.0 # 自定义训练时解析yaml配置文件 \ No newline at end of file From 0c432cdd6d160f52ea6ed55c823d60177ffc43a3 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 17:56:39 +0800 Subject: [PATCH 20/25] Delete src/image_object_detection/requirements.txt --- src/image_object_detection/requirements.txt | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/image_object_detection/requirements.txt diff --git a/src/image_object_detection/requirements.txt b/src/image_object_detection/requirements.txt deleted file mode 100644 index f1cc19c3c9..0000000000 --- a/src/image_object_detection/requirements.txt +++ /dev/null @@ -1,15 +0,0 @@ -# YOLOv8核心库(必须) -ultralytics>=8.0.0 # 推荐8.2.0(稳定版) -# 图像处理(必须) -opencv-python>=4.5.0 # 推荐4.8.1.78 -# 可视化(必须) -matplotlib>=3.0.0 # 推荐3.7.1 -# PyTorch核心(ultralytics依赖,必须) -torch>=2.0.0 # 推荐2.0.1或2.1.0 -torchvision>=0.15.0 # 与torch版本匹配 -# 基础数值计算(间接依赖,建议指定) -numpy>=1.21.0 # 推荐1.24.3 -# 可选(补充依赖,避免隐性报错) -pillow>=8.0.0 # 推荐9.5.0 -psutil>=5.8.0 # ultralytics监控系统资源用 -pyyaml>=6.0 # 自定义训练时解析yaml配置文件 \ No newline at end of file From d46dbef0c3f9c6f9256a62a5c03cb7ac75ce76a7 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 17:57:36 +0800 Subject: [PATCH 21/25] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 项目需要的依赖及其版本 --- src/image_object_detection/requirements.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/image_object_detection/requirements.txt diff --git a/src/image_object_detection/requirements.txt b/src/image_object_detection/requirements.txt new file mode 100644 index 0000000000..f1cc19c3c9 --- /dev/null +++ b/src/image_object_detection/requirements.txt @@ -0,0 +1,15 @@ +# YOLOv8核心库(必须) +ultralytics>=8.0.0 # 推荐8.2.0(稳定版) +# 图像处理(必须) +opencv-python>=4.5.0 # 推荐4.8.1.78 +# 可视化(必须) +matplotlib>=3.0.0 # 推荐3.7.1 +# PyTorch核心(ultralytics依赖,必须) +torch>=2.0.0 # 推荐2.0.1或2.1.0 +torchvision>=0.15.0 # 与torch版本匹配 +# 基础数值计算(间接依赖,建议指定) +numpy>=1.21.0 # 推荐1.24.3 +# 可选(补充依赖,避免隐性报错) +pillow>=8.0.0 # 推荐9.5.0 +psutil>=5.8.0 # ultralytics监控系统资源用 +pyyaml>=6.0 # 自定义训练时解析yaml配置文件 \ No newline at end of file From 7baa7199aff1ba38ffdf91e1c9b26d2d785ba9f5 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 18:11:58 +0800 Subject: [PATCH 22/25] Add files via upload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加YOLO对象检测系统的主程序(main),UI处理器(ui_handler),配置文件(config),检测引擎(detection_engint),图像检测器(image_detector) --- src/image_object_detection/config.py | 15 ++++ .../detection_engine.py | 57 ++++++++++++++ src/image_object_detection/image_detector.py | 63 ++++++++++++++++ src/image_object_detection/main.py | 11 +++ src/image_object_detection/ui_handler.py | 75 +++++++++++++++++++ 5 files changed, 221 insertions(+) create mode 100644 src/image_object_detection/config.py create mode 100644 src/image_object_detection/detection_engine.py create mode 100644 src/image_object_detection/image_detector.py create mode 100644 src/image_object_detection/main.py create mode 100644 src/image_object_detection/ui_handler.py diff --git a/src/image_object_detection/config.py b/src/image_object_detection/config.py new file mode 100644 index 0000000000..abee289e3d --- /dev/null +++ b/src/image_object_detection/config.py @@ -0,0 +1,15 @@ +# config.py +class Config: + def __init__(self): + # 测试图像路径 + self.test_image_path = r"C:\Users\apple\OneDrive\桌面\test.jpg" + + # YOLO模型配置 + self.model_path = "yolov8n.pt" + self.confidence_threshold = 0.25 + + # 摄像头配置 + self.camera_index = 0 + + # 输出频率控制(秒) + self.output_interval = 1.0 \ No newline at end of file diff --git a/src/image_object_detection/detection_engine.py b/src/image_object_detection/detection_engine.py new file mode 100644 index 0000000000..6f2df4b08b --- /dev/null +++ b/src/image_object_detection/detection_engine.py @@ -0,0 +1,57 @@ +# detection_engine.py +from ultralytics import YOLO +import io +import sys + +class DetectionEngine: + def __init__(self, model_path="yolov8n.pt", conf_threshold=0.25): + self.model_path = model_path + self.conf_threshold = conf_threshold + self.model = self._load_model() + + def _load_model(self): + """加载YOLO模型并抑制输出""" + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() + + try: + model = YOLO(self.model_path) + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + return model + + def detect(self, frame): + """对输入帧进行检测""" + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() + + try: + results = self.model(frame, conf=self.conf_threshold, verbose=False) + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + + annotated_frame = results[0].plot() + return annotated_frame, results + + def find_objects(self, frame): + """检测并分类图像中的对象""" + _, results = self.detect(frame) + objects = [] + for box in results[0].boxes: + cls_index = int(box.cls) + cls_name = self.model.names[cls_index] + coords = box.xyxy.tolist()[0] + confidence = box.conf.item() + objects.append({ + "type": cls_name, + "bbox": coords, + "confidence": confidence + }) + return objects \ No newline at end of file diff --git a/src/image_object_detection/image_detector.py b/src/image_object_detection/image_detector.py new file mode 100644 index 0000000000..ebfbc90bf4 --- /dev/null +++ b/src/image_object_detection/image_detector.py @@ -0,0 +1,63 @@ +# image_detector.py +import cv2 + +class ImageDetector: + def __init__(self, detection_engine): + self.engine = detection_engine + + def detect_static_image(self, image_path): + """检测静态图像""" + print(f"正在加载图像: {image_path}") + + if not self._check_image_exists(image_path): + return + + frame = self._load_image(image_path) + if frame is None: + print("错误: 无法读取图像文件") + return + + print("正在检测图像...") + results = self._perform_detection(frame) + + # 显示检测结果 + self._display_results(results) + + # 显示图像 + self._show_image(results[1][0].plot(), 'YOLO 检测结果 - 静态图像') + + def _check_image_exists(self, image_path): + """检查图像文件是否存在""" + if not cv2.os.path.exists(image_path): + print(f"错误: 图像文件不存在 - {image_path}") + return False + return True + + def _load_image(self, image_path): + """加载图像""" + return cv2.imread(image_path) + + def _perform_detection(self, frame): + """执行检测""" + annotated_frame, results = self.engine.detect(frame) + return results + + def _display_results(self, results): + """显示检测结果""" + detected_count = len(results[0].boxes) + print("检测完成,正在显示结果...") + print(f"检测到 {detected_count} 个对象:") + + for i, box in enumerate(results[0].boxes): + cls_index = int(box.cls) + cls_name = self.engine.model.names[cls_index] + confidence = box.conf.item() + print(f" {i+1}. {cls_name} (置信度: {confidence:.2f})") + + def _show_image(self, annotated_frame, window_name): + """显示图像""" + print("\n图像已显示。按任意键关闭窗口...") + cv2.imshow(window_name, annotated_frame) + cv2.waitKey(0) + cv2.destroyAllWindows() + print("窗口已关闭。") \ No newline at end of file diff --git a/src/image_object_detection/main.py b/src/image_object_detection/main.py new file mode 100644 index 0000000000..6c1bda8efd --- /dev/null +++ b/src/image_object_detection/main.py @@ -0,0 +1,11 @@ +# main.py +from ui_handler import UIHandler +from config import Config + +def main(): + config = Config() + ui_handler = UIHandler(config) + ui_handler.run() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/image_object_detection/ui_handler.py b/src/image_object_detection/ui_handler.py new file mode 100644 index 0000000000..53e4036e0d --- /dev/null +++ b/src/image_object_detection/ui_handler.py @@ -0,0 +1,75 @@ +# ui_handler.py +import cv2 +from detection_engine import DetectionEngine +from image_detector import ImageDetector +from camera_detector import CameraDetector +import sys +import os + +class UIHandler: + def __init__(self, config): + self.config = config + self.detection_engine = DetectionEngine() + self.image_detector = ImageDetector(self.detection_engine) + self.camera_detector = CameraDetector(self.detection_engine) + + def print_debug(self, message): + """调试输出函数""" + print(f"[DEBUG] {message}") + sys.stdout.flush() # 强制刷新输出缓冲区 + + def display_menu(self): + """显示主菜单""" + print("=" * 60) + print(" 欢迎使用 YOLO 对象检测系统") + print("=" * 60) + + print(f"\n测试图像路径: {self.config.test_image_path}") + print(f"图像文件存在: {os.path.exists(self.config.test_image_path)}") + + print("\n请选择检测模式:") + print("1. 检测静态图像") + print("2. 检测摄像头实时画面") + print("3. 退出程序") + + def handle_choice(self, choice): + """处理用户选择""" + if choice == '1': + print("\n您选择了: 检测静态图像") + self.image_detector.detect_static_image(self.config.test_image_path) + return True + elif choice == '2': + print("\n您选择了: 检测摄像头实时画面") + print("注意:要退出摄像头模式,请按 Ctrl+C !") + self.camera_detector.detect_camera() + return True + elif choice == '3': + print("\n程序已退出。") + return False + else: + print("\n无效选择,请输入 1、2 或 3") + return True + + def run(self): + """运行主程序""" + self.print_debug("程序开始执行") + self.display_menu() + + running = True + while running: + try: + choice = input("\n请输入您的选择 (1/2/3): ").strip() + self.print_debug(f"用户输入: {choice}") + running = self.handle_choice(choice) + + except KeyboardInterrupt: + print("\n\n程序被用户中断。") + break + except EOFError: + print("\n输入结束,程序退出。") + break + except Exception as e: + print(f"\n发生错误: {e}") + break + + self.print_debug("程序结束") \ No newline at end of file From e2c38edb5e86cab99bb8d14f57f3ec95cf6fde93 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 18:36:10 +0800 Subject: [PATCH 23/25] Update detection_engine.py --- .../detection_engine.py | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/image_object_detection/detection_engine.py b/src/image_object_detection/detection_engine.py index 6f2df4b08b..7e68491ece 100644 --- a/src/image_object_detection/detection_engine.py +++ b/src/image_object_detection/detection_engine.py @@ -25,7 +25,11 @@ def _load_model(self): return model def detect(self, frame): - """对输入帧进行检测""" + """ + 对输入帧进行检测。 + 返回: (annotated_frame: np.ndarray, results: List[Results]) + 即使无检测框,annotated_frame 也是原始图像(HWC格式)。 + """ old_stdout = sys.stdout old_stderr = sys.stderr sys.stdout = io.StringIO() @@ -37,21 +41,6 @@ def detect(self, frame): sys.stdout = old_stdout sys.stderr = old_stderr - annotated_frame = results[0].plot() + # YOLOv8 always returns at least one result + annotated_frame = results[0].plot() # numpy array (H, W, C) return annotated_frame, results - - def find_objects(self, frame): - """检测并分类图像中的对象""" - _, results = self.detect(frame) - objects = [] - for box in results[0].boxes: - cls_index = int(box.cls) - cls_name = self.model.names[cls_index] - coords = box.xyxy.tolist()[0] - confidence = box.conf.item() - objects.append({ - "type": cls_name, - "bbox": coords, - "confidence": confidence - }) - return objects \ No newline at end of file From 43271ab42e58c8da1b19fd449233c45af8ad45fc Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 18:37:00 +0800 Subject: [PATCH 24/25] Update image_detector.py --- src/image_object_detection/image_detector.py | 101 ++++++++++++++----- 1 file changed, 75 insertions(+), 26 deletions(-) diff --git a/src/image_object_detection/image_detector.py b/src/image_object_detection/image_detector.py index ebfbc90bf4..b161b45597 100644 --- a/src/image_object_detection/image_detector.py +++ b/src/image_object_detection/image_detector.py @@ -1,5 +1,7 @@ # image_detector.py import cv2 +import numpy as np +import traceback class ImageDetector: def __init__(self, detection_engine): @@ -13,51 +15,98 @@ def detect_static_image(self, image_path): return frame = self._load_image(image_path) - if frame is None: - print("错误: 无法读取图像文件") + if frame is None or frame.size == 0: + print("错误: 无法读取图像文件或图像为空") return print("正在检测图像...") - results = self._perform_detection(frame) + results, annotated_frame = self._perform_detection(frame) - # 显示检测结果 + if annotated_frame is None: + print("错误: 检测未返回有效图像") + return + + # 显示检测结果文本 self._display_results(results) - # 显示图像 - self._show_image(results[1][0].plot(), 'YOLO 检测结果 - 静态图像') + # 显示图像窗口(带固定初始大小) + self._show_image(annotated_frame, 'YOLO 检测结果 - 静态图像') def _check_image_exists(self, image_path): - """检查图像文件是否存在""" - if not cv2.os.path.exists(image_path): + import os + if not os.path.exists(image_path): print(f"错误: 图像文件不存在 - {image_path}") return False return True def _load_image(self, image_path): - """加载图像""" - return cv2.imread(image_path) + try: + with open(image_path, "rb") as f: + bytes_data = bytearray(f.read()) + nparr = np.frombuffer(bytes_data, np.uint8) + frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR) + return frame + except Exception as e: + print(f"加载图像时出错: {e}") + return None def _perform_detection(self, frame): - """执行检测""" - annotated_frame, results = self.engine.detect(frame) - return results + try: + annotated_frame, results = self.engine.detect(frame) + return results, annotated_frame + except Exception as e: + print(f"检测过程中发生错误: {e}") + traceback.print_exc() + return [], None def _display_results(self, results): - """显示检测结果""" - detected_count = len(results[0].boxes) + if not results: + print("未检测到任何对象(results 为空)") + return + + result = results[0] + boxes = result.boxes + if len(boxes) == 0: + print("未检测到任何对象") + return + print("检测完成,正在显示结果...") - print(f"检测到 {detected_count} 个对象:") + print(f"检测到 {len(boxes)} 个对象:") + + names_list = self.engine.model.names - for i, box in enumerate(results[0].boxes): - cls_index = int(box.cls) - cls_name = self.engine.model.names[cls_index] - confidence = box.conf.item() - print(f" {i+1}. {cls_name} (置信度: {confidence:.2f})") + for i, box in enumerate(boxes): + try: + cls_index = int(box.cls.item()) + confidence = box.conf.item() + + if 0 <= cls_index < len(names_list): + cls_name = names_list[cls_index] + else: + cls_name = f"unknown_class_{cls_index}" + print(f" ⚠️ 警告:类别索引 {cls_index} 超出范围(共 {len(names_list)} 类)") + + print(f" {i+1}. {cls_name} (置信度: {confidence:.2f})") + except Exception as e: + print(f" ⚠️ 解析第 {i+1} 个检测框时出错: {e}") def _show_image(self, annotated_frame, window_name): - """显示图像""" + """显示图像,并设置窗口为可调整的小尺寸""" + if annotated_frame is None or annotated_frame.size == 0: + print("错误: 标注帧无效,无法显示") + return + print("\n图像已显示。按任意键关闭窗口...") - cv2.imshow(window_name, annotated_frame) - cv2.waitKey(0) - cv2.destroyAllWindows() - print("窗口已关闭。") \ No newline at end of file + try: + # 创建可调整大小的窗口 + cv2.namedWindow(window_name, cv2.WINDOW_NORMAL) + # 设置初始窗口大小为 800x600(你可以按需修改) + cv2.resizeWindow(window_name, 800, 600) + # 显示图像(OpenCV 会自动适应窗口) + cv2.imshow(window_name, annotated_frame) + cv2.waitKey(0) + cv2.destroyAllWindows() + print("窗口已关闭。") + except Exception as e: + print(f"显示图像时发生错误: {e}") + traceback.print_exc() From 13fa00c88373bb1b40f81efe13f3cd94fd54c391 Mon Sep 17 00:00:00 2001 From: is-leplus <3210209742@qq.com> Date: Mon, 15 Dec 2025 20:09:23 +0800 Subject: [PATCH 25/25] Create camera_detector.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加相机识别模块 --- src/image_object_detection/camera_detector.py | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/image_object_detection/camera_detector.py diff --git a/src/image_object_detection/camera_detector.py b/src/image_object_detection/camera_detector.py new file mode 100644 index 0000000000..3964fcc2c6 --- /dev/null +++ b/src/image_object_detection/camera_detector.py @@ -0,0 +1,98 @@ +# camera_detector.py +import cv2 +import time + +class CameraDetector: + def __init__(self, detection_engine): + self.engine = detection_engine + + def detect_camera(self): + """检测摄像头实时画面""" + try: + # 打开摄像头 + print("正在打开摄像头...") + cap = self._open_camera() + + if cap is None: + return + + print("摄像头已打开,开始实时检测。") + print("在显示窗口中按 'q' 键退出,或在终端中按 Ctrl+C 中断程序。\n") + + self._run_camera_loop(cap) + + except KeyboardInterrupt: + print("\n\n用户按下了 Ctrl+C,强制退出摄像头检测...") + print("程序已安全退出。") + except Exception as e: + print(f"摄像头检测过程中发生错误: {e}") + finally: + self._cleanup_resources(cap) + + def _open_camera(self): + """打开摄像头""" + cap = cv2.VideoCapture(0) + + if not cap.isOpened(): + print("错误: 无法打开摄像头") + return None + + return cap + + def _run_camera_loop(self, cap): + """摄像头检测主循环""" + # 记录上次输出时间,控制输出频率 + last_output_time = time.time() + output_interval = 1.0 # 每秒最多输出一次检测信息 + + while True: + ret, frame = cap.read() + if not ret: + print("无法读取摄像头画面,退出...") + break + + results = self._perform_detection(frame) + annotated_frame = results[0].plot() + + # 控制输出频率,避免终端被刷屏 + self._handle_output_frequency(results, last_output_time, output_interval) + last_output_time = time.time() + + cv2.imshow('YOLO 检测结果 - 摄像头', annotated_frame) + + # 按 'q' 键退出 + key = cv2.waitKey(1) & 0xFF + if key == ord('q'): + print("\n用户按下 'q' 键,退出摄像头检测...") + break + + def _perform_detection(self, frame): + """执行检测""" + annotated_frame, results = self.engine.detect(frame) + return results + + def _handle_output_frequency(self, results, last_output_time, output_interval): + """处理输出频率""" + current_time = time.time() + if current_time - last_output_time >= output_interval: + detected_count = len(results[0].boxes) + if detected_count > 0: + # 构建检测对象字符串 + detected_objects = [] + for box in results[0].boxes: + cls_index = int(box.cls) + cls_name = self.engine.model.names[cls_index] + confidence = box.conf.item() + detected_objects.append(f"{cls_name}({confidence:.2f})") + + print(f"检测到 {detected_count} 个对象: {', '.join(detected_objects)}") + + def _cleanup_resources(self, cap): + """清理资源""" + print("释放摄像头资源...") + try: + cap.release() + cv2.destroyAllWindows() + except: + pass + print("摄像头检测已停止。")