Fork me on GitHub

labelImg标注训练数据

labelImg

下载安装

下载labelImg 是一个基于 PyQt5 的图形化图像标注工具,广泛用于 YOLO 等目标检测项目的数据标注。本文记录从安装到解决常见启动错误的完整流程。

一、数据标注 (LabelImg)

image
根据图片生成txt,txt内容为: label类别序号 x y w h
image

二、划分数据集

将标注好的数据分为训练集 (train) 和 验证集 (val)(通常按 8:2 或 9:1 的比例)。
标准目录结构如下:

dataset/
├── images/
│   ├── train/ (训练图片)
│   └── val/ (验证图片)
└── labels/
    ├── train/ (训练标注.txt)
    └── val/ (验证标注.txt)

image

三、 训练模型

1. 安装YOLO环境

安装Python 3.10 或 3.11(兼容性最好):

# 下载 Python 3.11,安装时勾选 "Add Python to PATH"
# 安装完成后验证
python --version
pip --version

安装 PyTorch

# 创建虚拟环境(推荐)
python -m venv yolo_env

# 激活虚拟环境
.\yolo_env\Scripts\Activate.ps1
# 如果报权限错误,先执行:
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# 安装 PyTorch CPU 版 + DirectML 插件
pip install torch torchvision torchaudio

# 安装 DirectML 后端(核心,让 RX580 参与计算)
pip install torch-directml

# 查看安装位置
pip show torch

安装 YOLO 框架

# 安装 ultralytics(YOLOv8/v11 官方库)
pip install ultralytics

# 安装 OpenCV(图像处理)
pip install opencv-python

# 安装其他依赖
pip install matplotlib pandas pillow numpy

2. 编写data.yaml配置文件

创建 data.yaml 文件,指定路径、类别数和类别名称:

path: G:/Yolo/dataset  # 数据集根目录
train: images/train
val: images/val

nc: 16  # 类别数量(与 classes.txt 一致)
names:    # 类别名称列表,这里要和labelimg生成的classes.txt一致
  - dog
  - person
  - cat
  - tv
  - car
  - meatballs
  - marinara sauce
  - tomato soup
  - chicken noodle soup
  - french onion soup
  - chicken breast
  - ribs
  - pulled pork
  - hamburger
  - cavity
  - pole

image

3. 开始训练

运行训练脚本开始训练(AMD3500X CPU训练9张标注数据用时10分钟)

训练脚本train.py

from ultralytics import YOLO

# 加载预训练模型
model = YOLO('yolov8n.pt')
# 开始训练
model.train(data='./dataset/data.yaml', epochs=100, imgsz=640)

训练完成,得到pt模型
image

4. 识别照片test_img.py测试

# -*- coding: utf-8 -*-
"""
YOLO 目标检测推理脚本
功能:加载训练好的 YOLO 模型,对单张图片进行目标检测并显示结果
"""

from ultralytics import YOLO        # YOLO 目标检测模型
from PIL import Image                # 图像打开与显示
from pathlib import Path             # 路径操作


# 加载训练好的 YOLO 模型权重
model = YOLO("./runs/detect/train/weights/best.pt")


# 对图片进行推理预测
results = model.predict(
    source="./test.jpg",   # 输入图片路径
    conf=0.5,              # 置信度阈值,低于此值的检测结果将被过滤
    save=True              # 自动保存带标注框的结果图片
)


# 获取结果图片的保存目录
save_path = Path(results[0].save_dir)

# 拼接结果图片的完整路径(默认文件名与输入图片同名)
img_path = save_path / "test.jpg"

print("结果图片:", img_path)


# 打开并显示带检测框的结果图片
Image.open(img_path).show()

image

5. 批量识别图片batch_test.py

# -*- coding: utf-8 -*-
"""
YOLO 批量目标检测脚本
功能:对指定目录下的所有图片进行批量目标检测,结果保存到指定输出目录
"""

import argparse
from ultralytics import YOLO
from pathlib import Path


def main():
    parser = argparse.ArgumentParser(description="YOLO 批量图片目标检测")
    parser.add_argument("--model", default="./runs/detect/train/weights/best.pt", help="模型权重路径")
    parser.add_argument("--input", default="./images", help="输入图片目录")
    parser.add_argument("--output", default="./batch_predict", help="结果输出目录")
    parser.add_argument("--conf", type=float, default=0.2, help="置信度阈值")
    parser.add_argument("--ext", nargs="+", default=[".jpg", ".jpeg", ".png", ".bmp", ".tif", ".tiff"],
                        help="支持的图片扩展名")
    args = parser.parse_args()

    input_dir = Path(args.input)
    if not input_dir.is_dir():
        print(f"错误:输入目录不存在 -> {input_dir}")
        return

    # 收集所有图片文件
    image_files = []
    for ext in args.ext:
        image_files.extend(input_dir.glob(f"*{ext}"))
        image_files.extend(input_dir.glob(f"*{ext.upper()}"))
    image_files = sorted(set(image_files))

    if not image_files:
        print(f"未找到图片文件(扩展名:{args.ext}),目录:{input_dir}")
        return

    output_path = Path(args.output)

    print(f"模型: {args.model}")
    print(f"输入目录: {input_dir}")
    print(f"输出目录: {output_path}")
    print(f"找到 {len(image_files)} 张图片\n")

    model = YOLO(args.model)

    for i, img_path in enumerate(image_files, 1):
        print(f"[{i}/{len(image_files)}] 正在检测: {img_path.name}")

        results = model.predict(
            source=str(img_path),
            conf=args.conf,
            save=True,
            project=str(output_path.parent),
            name=output_path.name,
            exist_ok=True,
        )

        detections = results[0].boxes
        if detections is not None and len(detections) > 0:
            print(f"  -> 检测到 {len(detections)} 个目标")
        else:
            print(f"  -> 未检测到目标")

    actual_dir = Path(results[0].save_dir).resolve()
    print(f"\n完成!结果已保存至: {actual_dir}")


if __name__ == "__main__":
    main()

运行脚本

  # 基础用法(使用默认参数)
  python batch_test.py

  # 指定输入目录和输出目录
  python batch_test.py --input ./my_images --output ./my_results

  # 自定义模型和置信度阈值
  python batch_test.py --model ./runs/detect/train/weights/best.pt --conf 0.3

  # 只检测 png 和 jpg
  python batch_test.py --ext .jpg .png

image

6. RTSP实时检测

# -*- coding: utf-8 -*-
"""
YOLO RTSP 视频流实时目标检测脚本
功能:拉取 RTSP 视频流,逐帧进行目标检测并实时显示
按 Q 键退出
"""

import argparse
import cv2
from ultralytics import YOLO


def main():
    parser = argparse.ArgumentParser(description="YOLO RTSP 视频流目标检测")
    parser.add_argument("--model", default="./runs/detect/train/weights/best.pt", help="模型权重路径")
    parser.add_argument("--rtsp", required=True, help="RTSP 流地址")
    parser.add_argument("--conf", type=float, default=0.1, help="置信度阈值")
    parser.add_argument("--resize", type=int, nargs=2, default=[1280, 720], help="显示窗口尺寸 (宽 高)")
    parser.add_argument("--output", default=None, help="可选:保存为视频文件路径")
    args = parser.parse_args()

    print(f"模型: {args.model}")
    print(f"RTSP: {args.rtsp}")

    model = YOLO(args.model)

    cap = cv2.VideoCapture(args.rtsp)
    if not cap.isOpened():
        print("错误:无法打开 RTSP 流")
        return

    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    print(f"分辨率: {width}x{height}, FPS: {fps:.1f}")

    writer = None
    if args.output:
        fourcc = cv2.VideoWriter_fourcc(*"mp4v")
        writer = cv2.VideoWriter(args.output, fourcc, fps if fps > 0 else 15, (width, height))
        print(f"保存到: {args.output}")

    print("\n开始检测,按 Q 退出...\n")

    try:
        while True:
            ret, frame = cap.read()
            if not ret:
                print("视频流中断,尝试重连...")
                cap.release()
                cap = cv2.VideoCapture(args.rtsp)
                continue

            results = model(frame, conf=args.conf, verbose=False)
            annotated = results[0].plot()

            cv2.namedWindow("YOLO RTSP", cv2.WINDOW_NORMAL)
            cv2.resizeWindow("YOLO RTSP", *args.resize)
            cv2.imshow("YOLO RTSP", annotated)

            if writer:
                writer.write(annotated)

            if cv2.waitKey(1) & 0xFF == ord("q"):
                break

    except KeyboardInterrupt:
        pass
    finally:
        cap.release()
        if writer:
            writer.release()
        cv2.destroyAllWindows()
        print("已退出")


if __name__ == "__main__":
    main()

使用脚本

  # 基础用法
  python rtsp_test.py --rtsp "rtsp://username:password@192.168.1.100:554/stream"

  # 自定义模型和置信度
  python rtsp_test.py --rtsp "rtsp://..." --conf 0.3

  # 同时保存为视频文件
  python rtsp_test.py --rtsp "rtsp://..." --output ./output.mp4

  # 调整显示窗口大小
  python rtsp_test.py --rtsp "rtsp://..." --resize 1920 1080

image

7. mp4视频文件检测

# drone_detect.py
import torch_directml
from ultralytics import YOLO
import cv2

class DronePoleDetector:
    def __init__(self, model_path="runs/detect/train/weights/best.pt"):
        self.model = YOLO(model_path)
        self.device = torch_directml.device()
        # GPU模式:使用RX580加速
        self.model.model.to(self.device)  # 把底层PyTorch模型迁移到DirectML
        # CPU模式:注销上面两行,改为 self.device = "cpu"

    def detect_frame(self, frame):
        """检测单帧图像"""
        results = self.model(
            frame,
            # device=self.device,  # 可省略,模型已迁移到GPU
            conf=0.1,
            iou=0.5,
            imgsz=640,
            max_det=20,  # 最多检测 20 个目标
        )
        return results

    def draw_results(self, frame, results):
        """绘制检测结果"""
        for result in results:
            boxes = result.boxes
            if boxes is not None:
                for box in boxes:
                    x1, y1, x2, y2 = map(int, box.xyxy[0])
                    conf = float(box.conf[0])

                    # 画框
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                    cv2.putText(
                        frame,
                        f"Pole {conf:.2f}",
                        (x1, y1 - 10),
                        cv2.FONT_HERSHEY_SIMPLEX,
                        0.5,
                        (0, 255, 0),
                        2,
                    )
        return frame

    def process_video(self, video_path, output_path=None):
        """处理视频流"""
        cap = cv2.VideoCapture(video_path)
        
        if output_path:
            fourcc = cv2.VideoWriter_fourcc(*'mp4v')
            fps = int(cap.get(cv2.CAP_PROP_FPS))
            width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
        
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break
            
            results = self.detect_frame(frame)
            frame = self.draw_results(frame, results)
            
            cv2.imshow("Drone Pole Detection", frame)
            if output_path:
                out.write(frame)
            
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        
        cap.release()
        if output_path:
            out.release()
        cv2.destroyAllWindows()

# 使用示例
if __name__ == "__main__":
    detector = DronePoleDetector()
    detector.process_video("drone_footage.mp4", "output_detected.mp4")
posted @ 2026-07-22 21:29  秋夜雨巷  阅读(10)  评论(0)    收藏  举报