当前位置: 首页 > news >正文

YOLO目标检测实战:从数据标注到模型部署全流程指南

🚀 30+款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度

零基础训练自己的YOLO目标检测模型!从数据采集到本地部署,全流程保姆级教程

目标检测作为计算机视觉的核心技术之一,在安防监控、自动驾驶、工业质检等领域有着广泛应用。YOLO(You Only Look Once)作为单阶段目标检测算法的代表,以其速度快、精度高的特点深受开发者喜爱。很多初学者想入门YOLO却苦于不知从何开始,本文将带你完整走一遍YOLO模型训练的全流程,从数据采集到模型部署,每个步骤都提供详细的操作指南。

无论你是计算机视觉新手,还是有一定基础想系统学习YOLO的开发者,这篇教程都能帮你快速上手。我们将使用最流行的Ultralytics YOLOv8版本,结合Label Studio标注工具,打造一个完整的实战项目。

1. YOLO目标检测基础概念

1.1 什么是YOLO目标检测

YOLO(You Only Look Once)是一种基于深度学习的实时目标检测算法,与传统的两阶段检测方法不同,YOLO将目标检测任务视为一个回归问题,直接在单个神经网络中预测边界框和类别概率。

YOLO的核心思想是将输入图像划分为S×S的网格,每个网格负责预测固定数量的边界框。对于每个边界框,网络会预测5个值:边界框的中心坐标(x,y)、宽度w、高度h以及置信度分数。同时,每个网格还会预测C个类别概率。这种设计使得YOLO能够实现端到端的训练和推理,大大提高了检测速度。

1.2 YOLO版本演进与选择

YOLO算法自2015年提出以来,经历了多个版本的迭代:

  • YOLOv1-v3:Joseph Redmon团队开发的经典版本
  • YOLOv4:Alexey Bochkovskiy在YOLOv3基础上的优化
  • YOLOv5:Ultralytics公司开发,采用PyTorch框架
  • YOLOv6:美团视觉智能部研发的工业级目标检测框架
  • YOLOv7:在速度和精度上的进一步优化
  • YOLOv8:Ultralytics最新版本,在易用性和性能上都有显著提升

对于初学者,推荐使用YOLOv8,因为它有完善的文档、活跃的社区支持,且安装使用相对简单。YOLOv8支持目标检测、实例分割、图像分类等多种任务,满足大多数应用场景需求。

1.3 目标检测的核心评价指标

了解目标检测的评价指标有助于我们评估模型性能:

  • mAP(mean Average Precision):综合衡量检测精度的重要指标,计算所有类别的平均精度
  • Precision(精确率):预测为正样本中真正为正样本的比例
  • Recall(召回率):实际正样本中被正确预测为正样本的比例
  • F1 Score:精确率和召回率的调和平均数
  • IoU(Intersection over Union):预测框与真实框的重叠程度

2. 环境准备与工具安装

2.1 硬件与软件要求

在开始之前,确保你的系统满足以下要求:

硬件要求:

  • CPU:至少4核处理器
  • 内存:8GB以上(推荐16GB)
  • 存储:至少20GB可用空间
  • GPU:可选,但推荐NVIDIA GPU(训练速度大幅提升)

软件要求:

  • 操作系统:Windows 10/11, Ubuntu 18.04+, macOS 10.15+
  • Python:3.8-3.10版本
  • CUDA:如果使用GPU,需要安装对应版本的CUDA

2.2 创建Python虚拟环境

为避免包冲突,我们首先创建独立的Python环境:

# 创建名为yolo_env的虚拟环境 conda create -n yolo_env python=3.9 -y # 激活虚拟环境 conda activate yolo_env # 或者使用venv创建虚拟环境(Linux/macOS) python -m venv yolo_env source yolo_env/bin/activate

2.3 安装YOLOv8及相关依赖

YOLOv8可以通过pip直接安装,非常方便:

# 安装YOLOv8 pip install ultralytics # 安装其他必要的依赖 pip install opencv-python pip install pillow pip install matplotlib pip install seaborn pip install pandas

如果计划使用GPU进行训练,还需要安装PyTorch的GPU版本:

# 安装PyTorch GPU版本(根据你的CUDA版本选择) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

2.4 安装Label Studio标注工具

Label Studio是一款开源的数据标注工具,支持多种标注类型:

# 安装Label Studio pip install label-studio # 启动Label Studio(首次启动会引导初始化) label-studio start

安装完成后,在浏览器中访问 http://localhost:8080 即可看到Label Studio的界面。

3. 数据采集与准备

3.1 数据采集策略

高质量的数据集是训练优秀模型的基础。数据采集可以考虑以下途径:

公开数据集:

  • COCO:包含80个类别,33万张图片
  • Pascal VOC:20个类别,1.1万张图片
  • Open Images:600个类别,900万张图片

自定义数据采集:

  • 网络爬虫:使用爬虫工具采集特定类别图片
  • 自行拍摄:针对特定场景拍摄图片
  • 视频抽帧:从视频中按时间间隔抽取帧作为训练数据

3.2 数据采集实战示例

以下是一个简单的图片爬虫示例,用于采集特定类别的图片:

import requests import os from bs4 import BeautifulSoup import time import urllib.parse class ImageCollector: def __init__(self, save_dir="dataset/images"): self.save_dir = save_dir os.makedirs(save_dir, exist_ok=True) def download_images(self, keywords, num_images=100): """下载指定关键词的图片""" for keyword in keywords: print(f"正在下载关键词: {keyword}") self._download_by_keyword(keyword, num_images) def _download_by_keyword(self, keyword, num_images): """根据关键词下载图片""" # 这里使用Bing图片搜索为例(实际使用时请遵守网站规则) search_url = f"https://www.bing.com/images/search?q={urllib.parse.quote(keyword)}" # 注意:实际爬虫需要处理反爬机制,这里仅为示例 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } # 实际项目中应使用合法的API或遵守robots.txt print(f"模拟搜索: {search_url}") # 这里省略具体的爬虫实现,建议使用合法的数据源 # 使用示例 if __name__ == "__main__": collector = ImageCollector() keywords = ["cat", "dog", "car"] # 根据你的需求修改关键词 collector.download_images(keywords, 50)

重要提醒:在实际项目中,请确保数据采集的合法性,遵守网站的使用条款和robots.txt规定。

3.3 数据质量检查

采集到的数据需要进行质量检查:

import os from PIL import Image import cv2 def check_dataset_quality(image_dir): """检查数据集质量""" valid_images = [] corrupted_images = [] for img_file in os.listdir(image_dir): if img_file.lower().endswith(('.png', '.jpg', '.jpeg')): img_path = os.path.join(image_dir, img_file) try: # 尝试用PIL打开图片 with Image.open(img_path) as img: img.verify() # 用OpenCV检查图片是否可读 cv_img = cv2.imread(img_path) if cv_img is not None: valid_images.append(img_path) else: corrupted_images.append(img_path) except Exception as e: corrupted_images.append(img_path) print(f"损坏图片: {img_path}, 错误: {e}") print(f"有效图片: {len(valid_images)}") print(f"损坏图片: {len(corrupted_images)}") # 删除损坏图片 for corrupt_img in corrupted_images: os.remove(corrupt_img) print(f"已删除: {corrupt_img}") return valid_images # 检查图片质量 image_dir = "dataset/images" valid_images = check_dataset_quality(image_dir)

4. 数据标注与预处理

4.1 使用Label Studio进行数据标注

Label Studio提供了友好的Web界面进行数据标注:

创建标注项目:

  1. 启动Label Studio:label-studio start
  2. 访问 http://localhost:8080
  3. 创建新项目,选择"Object Detection with Bounding Boxes"模板
  4. 设置标签名称(如:person, car, dog, cat等)

配置标注界面:

<View> <Image name="image" value="$image"/> <RectangleLabels name="label" toName="image"> <Label value="person" background="green"/> <Label value="car" background="blue"/> <Label value="dog" background="red"/> <Label value="cat" background="yellow"/> </RectangleLabels> </View>

批量导入图片:

import os import json def prepare_label_studio_import(image_dir, output_file="import_list.json"): """准备Label Studio导入文件列表""" image_files = [f for f in os.listdir(image_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))] import_list = [] for img_file in image_files: import_list.append({ "image": f"/data/local-files/?d=images/{img_file}" }) with open(output_file, 'w') as f: json.dump(import_list, f, indent=2) print(f"生成导入文件: {output_file}, 包含 {len(image_files)} 张图片") # 准备导入文件 prepare_label_studio_import("dataset/images")

4.2 半自动化标注技巧

利用预训练模型进行半自动化标注可以大幅提高效率:

from ultralytics import YOLO import cv2 import json import os class SemiAutoLabeling: def __init__(self, model_path='yolov8n.pt'): # 加载预训练模型 self.model = YOLO(model_path) def predict_and_export(self, image_dir, output_dir="auto_labels"): """预测并导出标注结果""" os.makedirs(output_dir, exist_ok=True) image_files = [f for f in os.listdir(image_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))] for img_file in image_files: img_path = os.path.join(image_dir, img_file) results = self.model(img_path) # 导出标注信息 self.export_annotations(results, img_file, output_dir) def export_annotations(self, results, image_name, output_dir): """导出标注信息为JSON格式""" annotations = { "image": image_name, "annotations": [] } for result in results: boxes = result.boxes if boxes is not None: for box in boxes: # 获取边界框坐标 x1, y1, x2, y2 = box.xyxy[0].tolist() confidence = box.conf[0].item() class_id = int(box.cls[0].item()) class_name = result.names[class_id] annotation = { "label": class_name, "x": x1, "y": y1, "width": x2 - x1, "height": y2 - y1, "confidence": confidence } annotations["annotations"].append(annotation) # 保存标注文件 json_file = os.path.splitext(image_name)[0] + ".json" json_path = os.path.join(output_dir, json_file) with open(json_path, 'w') as f: json.dump(annotations, f, indent=2) # 使用半自动化标注 labeler = SemiAutoLabeling() labeler.predict_and_export("dataset/images")

4.3 数据格式转换

将Label Studio的标注结果转换为YOLO格式:

import json import os from PIL import Image def convert_labelstudio_to_yolo(labelstudio_json, image_dir, output_dir): """将Label Studio JSON格式转换为YOLO格式""" os.makedirs(output_dir, exist_ok=True) with open(labelstudio_json, 'r') as f: data = json.load(f) # 创建类别映射 classes = set() for annotation in data: for result in annotation.get('annotations', [])[0].get('result', []): if 'rectanglelabels' in result['value']: classes.update(result['value']['rectanglelabels']) classes = sorted(list(classes)) class_to_id = {cls: idx for idx, cls in enumerate(classes)} # 保存类别文件 with open(os.path.join(output_dir, 'classes.txt'), 'w') as f: for cls in classes: f.write(cls + '\n') # 转换每个标注 for annotation in data: image_file = annotation['data']['image'].split('/')[-1] image_path = os.path.join(image_dir, image_file) # 获取图片尺寸 with Image.open(image_path) as img: img_width, img_height = img.size # 生成YOLO格式标注 yolo_annotations = [] for result in annotation.get('annotations', [])[0].get('result', []): if 'rectanglelabels' in result['value']: x = result['value']['x'] / 100 * img_width y = result['value']['y'] / 100 * img_height width = result['value']['width'] / 100 * img_width height = result['value']['height'] / 100 * img_height # 转换为YOLO格式(归一化坐标) x_center = (x + width / 2) / img_width y_center = (y + height / 2) / img_height norm_width = width / img_width norm_height = height / img_height class_id = class_to_id[result['value']['rectanglelabels'][0]] yolo_annotations.append(f"{class_id} {x_center} {y_center} {norm_width} {norm_height}") # 保存YOLO标注文件 txt_file = os.path.splitext(image_file)[0] + '.txt' txt_path = os.path.join(output_dir, txt_file) with open(txt_path, 'w') as f: f.write('\n'.join(yolo_annotations)) # 转换标注格式 convert_labelstudio_to_yolo("labelstudio_export.json", "dataset/images", "dataset/labels")

5. YOLO模型训练实战

5.1 准备YOLO格式数据集

YOLO需要特定的目录结构:

dataset/ ├── images/ │ ├── train/ │ │ ├── image1.jpg │ │ └── image2.jpg │ └── val/ │ ├── image3.jpg │ └── image4.jpg └── labels/ ├── train/ │ ├── image1.txt │ └── image2.txt └── val/ ├── image3.txt └── image4.txt

创建数据集配置文件dataset.yaml

# dataset.yaml path: /path/to/dataset # 数据集根目录 train: images/train # 训练图片目录 val: images/val # 验证图片目录 # 类别数量 nc: 4 # 类别名称 names: ['person', 'car', 'dog', 'cat']

5.2 模型训练完整代码

使用YOLOv8进行模型训练:

from ultralytics import YOLO import os def train_yolo_model(): """训练YOLO模型""" # 加载预训练模型 model = YOLO('yolov8n.pt') # 可以选择yolov8s.pt, yolov8m.pt等 # 训练参数配置 training_results = model.train( data='dataset.yaml', # 数据集配置文件 epochs=100, # 训练轮数 imgsz=640, # 输入图片尺寸 batch=16, # 批次大小 device='cpu', # 使用CPU训练,如有GPU可改为0或[0,1] workers=4, # 数据加载线程数 patience=10, # 早停耐心值 lr0=0.01, # 初始学习率 lrf=0.01, # 最终学习率 momentum=0.937, # 动量 weight_decay=0.0005, # 权重衰减 warmup_epochs=3.0, # 热身轮数 box=7.5, # 边界框损失权重 cls=0.5, # 分类损失权重 dfl=1.5, # DFL损失权重 save=True, # 保存训练检查点 exist_ok=True, # 覆盖现有输出 pretrained=True, # 使用预训练权重 optimizer='auto', # 优化器自动选择 verbose=True, # 显示训练详情 seed=42 # 随机种子 ) return training_results # 开始训练 if __name__ == "__main__": results = train_yolo_model() print("训练完成!")

5.3 训练过程监控

实时监控训练进度和指标:

import matplotlib.pyplot as plt import pandas as pd def plot_training_results(results_dir): """绘制训练结果图表""" # 读取训练结果CSV文件 results_csv = os.path.join(results_dir, 'results.csv') if not os.path.exists(results_csv): print("未找到训练结果文件") return df = pd.read_csv(results_csv) # 创建图表 fig, axes = plt.subplots(2, 2, figsize=(15, 10)) # 损失函数曲线 axes[0, 0].plot(df['epoch'], df['train/box_loss'], label='Box Loss') axes[0, 0].plot(df['epoch'], df['train/cls_loss'], label='Cls Loss') axes[0, 0].plot(df['epoch'], df['train/dfl_loss'], label='DFL Loss') axes[0, 0].set_title('Training Loss') axes[0, 0].set_xlabel('Epoch') axes[0, 0].set_ylabel('Loss') axes[0, 0].legend() axes[0, 0].grid(True) # 验证损失曲线 axes[0, 1].plot(df['epoch'], df['val/box_loss'], label='Val Box Loss') axes[0, 1].plot(df['epoch'], df['val/cls_loss'], label='Val Cls Loss') axes[0, 1].plot(df['epoch'], df['val/dfl_loss'], label='Val DFL Loss') axes[0, 1].set_title('Validation Loss') axes[0, 1].set_xlabel('Epoch') axes[0, 1].set_ylabel('Loss') axes[0, 1].legend() axes[0, 1].grid(True) # 精确率和召回率 axes[1, 0].plot(df['epoch'], df['metrics/precision(B)'], label='Precision') axes[1, 0].plot(df['epoch'], df['metrics/recall(B)'], label='Recall') axes[1, 0].set_title('Precision & Recall') axes[1, 0].set_xlabel('Epoch') axes[1, 0].set_ylabel('Score') axes[1, 0].legend() axes[1, 0].grid(True) # mAP指标 axes[1, 1].plot(df['epoch'], df['metrics/mAP50(B)'], label='mAP@0.5') axes[1, 1].plot(df['epoch'], df['metrics/mAP50-95(B)'], label='mAP@0.5:0.95') axes[1, 1].set_title('mAP Metrics') axes[1, 1].set_xlabel('Epoch') axes[1, 1].set_ylabel('mAP') axes[1, 1].legend() axes[1, 1].grid(True) plt.tight_layout() plt.savefig('training_results.png', dpi=300, bbox_inches='tight') plt.show() # 绘制训练结果 plot_training_results('runs/detect/train')

6. 模型评估与优化

6.1 模型性能评估

训练完成后,需要对模型进行全面评估:

from ultralytics import YOLO import matplotlib.pyplot as plt def evaluate_model(model_path, data_yaml): """评估模型性能""" # 加载训练好的模型 model = YOLO(model_path) # 在验证集上评估 metrics = model.val(data=data_yaml, split='val') print("模型评估结果:") print(f"mAP@0.5: {metrics.box.map50:.3f}") print(f"mAP@0.5:0.95: {metrics.box.map:.3f}") print(f"精确率: {metrics.box.mp:.3f}") print(f"召回率: {metrics.box.mr:.3f}") return metrics # 评估模型 metrics = evaluate_model('runs/detect/train/weights/best.pt', 'dataset.yaml')

6.2 混淆矩阵分析

def plot_confusion_matrix(model_path, data_yaml): """绘制混淆矩阵""" model = YOLO(model_path) # 生成混淆矩阵 model.val(data=data_yaml, plots=True) # 混淆矩阵图片保存在runs/detect/val目录 print("混淆矩阵已生成") plot_confusion_matrix('runs/detect/train/weights/best.pt', 'dataset.yaml')

6.3 模型优化策略

根据评估结果进行模型优化:

def optimize_model_training(): """模型优化训练配置""" model = YOLO('yolov8n.pt') # 优化后的训练参数 results = model.train( data='dataset.yaml', epochs=150, # 增加训练轮数 imgsz=640, batch=8, # 减小批次大小 lr0=0.001, # 降低学习率 weight_decay=0.0001, # 调整权重衰减 augment=True, # 启用数据增强 degrees=10.0, # 旋转增强 translate=0.1, # 平移增强 scale=0.5, # 缩放增强 shear=2.0, # 剪切增强 perspective=0.0001, # 透视变换 flipud=0.0, # 上下翻转 fliplr=0.5, # 左右翻转 mosaic=1.0, # Mosaic数据增强 mixup=0.0, # MixUp增强 copy_paste=0.0 # 复制粘贴增强 ) return results # 如果需要优化,可以重新训练 # optimized_results = optimize_model_training()

7. 模型导出与本地部署

7.1 模型格式导出

将训练好的模型导出为不同格式,便于部署:

def export_model(model_path, export_formats=['onnx', 'torchscript']): """导出模型为不同格式""" model = YOLO(model_path) for format in export_formats: try: # 导出模型 exported_path = model.export(format=format, imgsz=640, optimize=True) print(f"模型已导出为 {format.upper()} 格式: {exported_path}") except Exception as e: print(f"导出 {format} 格式失败: {e}") # 导出模型 export_model('runs/detect/train/weights/best.pt')

7.2 本地推理部署

创建本地推理应用程序:

from ultralytics import YOLO import cv2 import numpy as np import time class YOLODeployer: def __init__(self, model_path): self.model = YOLO(model_path) self.class_names = self.model.names def predict_image(self, image_path, conf_threshold=0.25, iou_threshold=0.7): """单张图片预测""" results = self.model.predict( source=image_path, conf=conf_threshold, iou=iou_threshold, imgsz=640, save=True ) return results def real_time_detection(self, camera_index=0): """实时摄像头检测""" cap = cv2.VideoCapture(camera_index) if not cap.isOpened(): print("无法打开摄像头") return print("实时检测已启动,按 'q' 键退出") while True: ret, frame = cap.read() if not ret: break # 进行目标检测 results = self.model(frame) # 绘制检测结果 annotated_frame = results[0].plot() # 显示FPS cv2.putText(annotated_frame, f"FPS: {int(1/(time.time() - start_time))}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow('YOLO Real-time Detection', annotated_frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() def batch_predict(self, image_dir, output_dir="predictions"): """批量图片预测""" import os os.makedirs(output_dir, exist_ok=True) results = self.model.predict( source=image_dir, save=True, project=output_dir, name="exp", exist_ok=True ) print(f"批量预测完成,结果保存在: {output_dir}") return results # 使用部署类 deployer = YOLODeployer('runs/detect/train/weights/best.pt') # 单张图片测试 results = deployer.predict_image('test_image.jpg') # 实时检测(取消注释以启用) # deployer.real_time_detection()

7.3 创建Web API服务

使用FastAPI创建模型推理API:

from fastapi import FastAPI, File, UploadFile from fastapi.responses import JSONResponse import cv2 import numpy as np from ultralytics import YOLO import io from PIL import Image app = FastAPI(title="YOLO目标检测API") # 加载模型 model = YOLO('runs/detect/train/weights/best.pt') @app.post("/predict") async def predict_image(file: UploadFile = File(...)): """图片预测API接口""" # 读取上传的图片 image_data = await file.read() image = Image.open(io.BytesIO(image_data)) image_np = np.array(image) # 进行预测 results = model(image_np) # 解析结果 detections = [] for result in results: boxes = result.boxes if boxes is not None: for box in boxes: detection = { "class": model.names[int(box.cls[0])], "confidence": float(box.conf[0]), "bbox": { "x1": float(box.xyxy[0][0]), "y1": float(box.xyxy[0][1]), "x2": float(box.xyxy[0][2]), "y2": float(box.xyxy[0][3]) } } detections.append(detection) return JSONResponse({ "filename": file.filename, "detections": detections, "detection_count": len(detections) }) @app.get("/") async def root(): return {"message": "YOLO目标检测API服务运行中"} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)

启动API服务:

python api_server.py

8. 常见问题与解决方案

8.1 训练过程中的常见问题

问题1:CUDA内存不足

解决方案: - 减小批次大小(batch size) - 减小输入图片尺寸(imgsz) - 使用梯度累积 - 清理GPU缓存

问题2:训练损失不下降

解决方案: - 检查学习率是否合适 - 验证数据标注质量 - 增加数据增强 - 检查模型架构是否适合任务

问题3:过拟合

解决方案: - 增加正则化(权重衰减) - 使用早停(early stopping) - 增加数据量 - 简化模型结构

8.2 部署时的常见问题

问题1:模型推理速度慢

# 优化推理速度的配置 results = model.predict( source=image, imgsz=320, # 减小输入尺寸 half=True, # 使用半精度推理 device='cpu', # 确保使用正确的设备 verbose=False # 关闭详细输出 )

问题2:检测框不准确

# 调整检测参数 results = model.predict( source=image, conf=0.5, # 提高置信度阈值 iou=0.5, # 调整IoU阈值 agnostic_nms=False, # 使用类别感知NMS max_det=100 # 限制最大检测数量 )

8.3 数据相关的常见问题

问题:类别不平衡

# 在训练配置中处理类别不平衡 results = model.train( data='dataset.yaml', cls=1.0, # 调整分类损失权重 fl_gamma=1.5, # 使用Focal Loss # 或者使用过采样/欠采样策略 )

9. 项目实战:构建完整应用

9.1 创建综合检测应用

下面是一个完整的桌面应用示例,集成训练好的YOLO模型:

import tkinter as tk from tkinter import filedialog, messagebox from PIL import Image, ImageTk import cv2 from ultralytics import YOLO import threading class YOLOApp: def __init__(self, root): self.root = root self.root.title("YOLO目标检测应用") self.root.geometry("800x600") # 加载模型 self.model = YOLO('runs/detect/train/weights/best.pt') self.setup_ui() def setup_ui(self): """设置用户界面""" # 顶部按钮框架 button_frame = tk.Frame(self.root) button_frame.pack(pady=10) # 功能按钮 self.load_btn = tk.Button(button_frame, text="加载图片", command=self.load_image) self.load_btn.pack(side=tk.LEFT, padx=5) self.detect_btn = tk.Button(button_frame, text="开始检测", command=self.detect_objects) self.detect_btn.pack(side=tk.LEFT, padx=5) self.camera_btn = tk.Button(button_frame, text="摄像头检测", command=self.camera_detection) self.camera_btn.pack(side=tk.LEFT, padx=5) # 图片显示区域 self.image_label = tk.Label(self.root) self.image_label.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) # 状态栏 self.status_var = tk.StringVar() self.status_var.set("就绪") status_bar = tk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W) status_bar.pack(side=tk.BOTTOM, fill=tk.X) def load_image(self): """加载图片""" file_path = filedialog.askopenfilename( filetypes=[("Image files", "*.jpg *.jpeg *.png *.bmp")] ) if file_path: self.original_image = Image.open(file_path) self.display_image(self.original_image) self.status_var.set(f"已加载: {file_path}") def display_image(self, image): """显示图片""" # 调整图片大小以适应窗口 width, height = image.size max_size = 600 if width > max_size or height > max_size: ratio = min(max_size/width, max_size/height) new_size = (int(width*ratio), int(height*ratio)) image = image.resize(new_size, Image.Resampling.LANCZOS) self.tk_image = ImageTk.PhotoImage(image) self.image_label.config(image=self.tk_image) def detect_objects(self): """目标检测""" if hasattr(self, 'original_image'): # 在新线程中执行检测,避免界面卡顿 threading.Thread(target=self._detect_objects_thread).start() else: messagebox.showwarning("警告", "请先加载图片") def _detect_objects_thread(self): """检测线程""" self.status_var.set("检测中...") self.detect_btn.config(state=tk.DISABLED) # 转换图片格式 image_cv = cv2.cvtColor(np.array(self.original_image), cv2.COLOR_RGB2BGR) # 进行检测 results = self.model(image_cv) # 绘制检测结果 annotated_image = results[0].plot() annotated_image_rgb = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB) result_image = Image.fromarray(annotated_image_rgb) # 更新界面 self.root.after(0, self._update_detection_result, result_image) def _update_detection > 🚀 30+款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉[点击领海量免费额度](https://taotoken.net/models/detail/chat?modelId=deepseek-v4-pro&utm_source=tt_blog_mr)
http://www.jsqmd.com/news/1139601/

相关文章:

  • AI智能体自动化解决VC++运行库缺失:从检测到决策的工程实践
  • LTX2.3+ComfyUI本地图生视频部署指南:12G显存即可运行
  • 5分钟快速上手Foliate:Linux上最优雅的电子书阅读器终极指南
  • YOLOv8蜜蜂识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+环境配置+目标检测)
  • Okbiye AI 写作|分档适配全等级期刊论文,一站式搞定普刊、核心、SCI 文稿创作
  • 支付安全基石:TR31与TR34标准的核心原理、应用与实战避坑指南
  • 3D ResNet-101 PyTorch 复现指南:从 2D 到 3D 卷积的 5 个关键改动点
  • Paperxie 期刊论文写作对话实录|搞定普刊 / 北核 / SCI 投稿文稿全攻略
  • 微信支付APIv3签名错误排查指南:从原理到实战解决发券难题
  • 如何高效配置洛雪音乐音源:开发者的专业指南与最佳实践
  • 伊朗战争影响渐退,德国5月工厂订单有所反弹
  • 低查重的AI教材生成秘诀!3款AI工具实测,快速编写高质量教材!
  • RFID手持终端与固定式读写器在资产盘点场景中的协同组网策略
  • 电脑右下角显示未激活windows
  • 电子小白入门之NE555
  • ScienceDecrypting:永久解锁加密学术文献,告别7天阅读限制
  • CTFshow Web 78-81关:文件包含漏洞原理、PHP伪协议利用与防御实战
  • 2026年AIGC检测新规下如何一次通过?PaperRed+元宝组合实测报告
  • AgenticDiffusion:多视角扩散规划驱动的语义无人机导航
  • Java计算机毕设之基于 SpringBoot 的农产品产业分析报告管理系统的设计与实现 基于前后端分离的农业科研报告资源管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 【AI大模型进阶】手把手教你读懂“模型卡”:就像看食品配料表一样简单
  • Urho3D游戏引擎:轻量级架构与跨平台技术实现的深度剖析
  • 大麦抢票自动化终极指南:从零到一的完整解决方案
  • Maya结合AI渲染:静态3D图转动态视频的技术实践
  • openeuler/os-compat-analyzer安全最佳实践:防止XSS攻击的前端渲染策略
  • 计算机毕业设计Flink+Kafka深圳智慧交通拥堵预测系统 智慧交通可视化大屏 交通实时治理决策系统 交通大数据(源码+LW+PPT+讲解)
  • 选择后端框架的五个关键考量因素
  • StreamCap架构解析:多平台直播流自动录制技术实现深度指南
  • 图像锐度评分算法实战:基于OpenCV与Python实现自动对焦评价函数
  • PyTorch UNet 训练优化:4个技巧将小数据集(<100张)mIoU提升15%