记录第一次跑YOLOV8做目标检测

news2025/3/2 22:07:57

今天是24年的最后一天,终于要向新世界开始破门了,开始深度学习,YOLO来敲门~
最近做了一些皮肤检测的功能,在传统的处理中经历了反复挣扎,终于要上YOLO了。听过、看过,不如上手体会过~
1、YOLO是什么?
看了GPT的回答,首次上手的人还是不太懂,只知道从2016年出第一版到现在已经过多轮迭代更新了,是很成熟的框架,可以放心大胆用。在做目标检测方面,杠杠的。特别是对于特征一致性相对较好的不大不小需求,绝了。安全帽、头盔、口罩检测已经是典型应用了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2、开启YOLOv8框架
为什么是v8,这个还是源于大佬的经验,小白都是先模仿。也因为我的皮肤检测属于小型检测目标。
(1)准备数据文件夹dataset(数据用来建立模型)
images:图片文件夹里面有两个文件夹,分别放了训练图片原图(80%)和用作测试的图片(20%)
labels:标注文件夹,里面放置了训练和测试图片文件夹对应的标注文件,格式是txt。

标注文件:就是采用标注软件对图片中需要识别的目标进行标签化的结果文件。

标注很重要,需要尽量圈出自己的目标前景,且保持多帧间的一致性和稳定性。
常用又好用的标注软件是Labelme 和LabelImg。我挺喜欢Labelme 的,有很多个版本,还有windows可以直接运行的Labelme.exe。总之不用编码直接使用,方便,好get。需要注意的是,Labelme的输出是jason文档,为了顺利转成满足YOLO输入的格式,需要将jason转成txt(后面有给出可运行的代码)。
Labelme.exe我已经上传资源文档了:windows可以直接使用的labelme.exe

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:标注是需要提前做好的,且images 和labels 两个文件夹中的训练和测试的数据应保持匹配和对应关系。

(2)在python编辑器中用代码建立模型并推理计算
先安装好YOLO包(默认已安装好python及常用依赖库,如CV)
在这里插入图片描述

训练代码 train.py

from ultralytics import YOLO

# 初始化 YOLO 模型
model = YOLO("yolov8n.pt")  # 使用预训练的 YOLOv8 nano 模型

# 训练模型
model.train(
    data="E:/skin_data/spot_dataset/dataset.yaml",  # 数据配置文件路径
    epochs=60,                   # 训练轮数
    imgsz=640,                  # 输入图片尺寸
    batch=16,                     # 批次大小,根据显存大小调整
    name="spot_detection60"        # 保存运行结果的名称
)

推测代码

from ultralytics import YOLO

#加载已经训练好的模型
trained_model = YOLO("E:/skin_yolo/runs/detect/spot_detection60/weights/best.pt")  # 加载最优权重

#进行推理测试
results = trained_model.predict(
source="E:/skin_data/spot_dataset/images/val",  # 推理图片的路径(支持文件夹、单个图片、视频等)
    conf=0.5,                     # 置信度阈值
    save=True,                    # 保存结果到运行目录
    save_txt=True,                # 保存结果到文本文件
     imgsz=640                    # 推理图片尺寸
 )
#输出推理结果
print(results)

觉着标注框和注释太粗大了,那么修改一下推测:

from ultralytics import YOLO
import cv2
import os

# Load the trained YOLO model
trained_model = YOLO("E:/skin_yolo/runs/detect/spot_detection60/weights/best.pt")

# Define directories
input_dir = "E:/skin_data/spot_dataset/images/val/"  # Directory containing images to infer
output_dir = "E:/skin_yolo/runs/detect/result2/"  # Directory to save inference results
os.makedirs(output_dir, exist_ok=True)  # Create output directory if it doesn't exist

# Custom settings for bounding boxes
box_color = (0, 255, 0)  # Green color for the bounding box
line_thickness = 1       # Thickness of the bounding box lines

# Iterate through all images in the input directory
for filename in os.listdir(input_dir):
    # Process only image files
    if filename.endswith(('.jpg', '.jpeg', '.png', '.bmp')):
        image_path = os.path.join(input_dir, filename)

        # Run inference
        results = trained_model.predict(source=image_path, conf=0.3, save=False)

        # Get the first (and usually only) result
        result = results[0]  # Access the first result in the list

        # Get the original image from the result
        img = result.orig_img

        # Accessing the detection boxes and labels
        boxes = result.boxes  # This contains the detection boxes
        class_ids = boxes.cls  # Class indices for each box
        confidences = boxes.conf  # Confidence scores for each detection

        # Draw bounding boxes on the image
        for i in range(len(boxes)):
            # Get the coordinates of the box (x1, y1, x2, y2) from xyxy format
            x1, y1, x2, y2 = boxes.xyxy[i].int().tolist()  # Convert tensor to list of integers

            # Draw the bounding box
            cv2.rectangle(img, (x1, y1), (x2, y2), box_color, line_thickness)

            # Get the label (class name) and confidence
            label = f"{trained_model.names[int(class_ids[i])]} {confidences[i]:.2f}"

            # Put the label on the image
            #cv2.putText(img, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, box_color, 2)

        # Save the result image
        result_image_path = os.path.join(output_dir, f"result_{filename}")
        cv2.imwrite(result_image_path, img)  # Save image with bounding boxes
        print(f"Saved result for {filename} at {result_image_path}")

print("Inference for all images in the folder is complete.")

show一张处理结果:我的“目标橙”都检测到了~
在这里插入图片描述
(3)涉及的代码附件
jason2txt

import os
import json

# 类别名称与ID的映射
classes = ["ix"]  # 根据你的类别修改

def convert_labelme_to_yolo(json_dir, output_dir):
    os.makedirs(output_dir, exist_ok=True)

    for file in os.listdir(json_dir):
        if not file.endswith('.json'):
            continue

        # 读取 JSON 文件
        json_path = os.path.join(json_dir, file)
        with open(json_path, 'r', encoding='utf-8') as f:
            data = json.load(f)

        # 调试输出,检查 JSON 数据结构
        print(f"正在处理文件: {file}")
        print(f"JSON 数据: {data}")

        image_width = data.get('imageWidth', 0)
        image_height = data.get('imageHeight', 0)

        # 检查图像尺寸
        print(f"图像宽度: {image_width}, 图像高度: {image_height}")
        if image_width == 0 or image_height == 0:
            print(f"错误:图像尺寸信息丢失: {file}")
            continue

        yolo_labels = []
        for shape in data['shapes']:
            label = shape['label']
            if label not in classes:
                print(f"未识别的类别: {label}, 请在 classes 中添加该类别。")
                continue

            # 获取类别 ID
            class_id = classes.index(label)

            # 解析边界框的点
            points = shape['points']
            print(f"标注类型: {label}, 标注坐标: {points}")

            if len(points) < 2:  # 如果不是矩形框,可能需要其他处理
                print(f"警告:{file} 中的标注无效,跳过。")
                continue

            x_min, y_min = points[0]
            x_max, y_max = points[1]

            # 计算 YOLO 格式的中心点和宽高(归一化)
            x_center = (x_min + x_max) / 2 / image_width
            y_center = (y_min + y_max) / 2 / image_height
            width = (x_max - x_min) / image_width
            height = (y_max - y_min) / image_height

            yolo_labels.append(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}")

        # 检查是否有标注数据
        if not yolo_labels:
            print(f"警告:文件 {file} 没有有效的标注数据。")
            continue

        # 保存到 YOLO 格式的 .txt 文件
        output_file = os.path.join(output_dir, file.replace('.json', '.txt'))
        with open(output_file, 'w') as f:
            f.write("\n".join(yolo_labels))
        print(f"已生成: {output_file}")


# 使用示例
json_dir = "E:/skin_data/json/"  # Labelme JSON 文件路径
output_dir = "E:/skin_data/yolo_labels/"  # YOLO 格式标注文件保存路径
convert_labelme_to_yolo(json_dir, output_dir)

输入图像具有多样性,而标注输出则具有一定的相似性。一般标注的图像输出文件数是小于参与标注输入图像数目的(输入图像中有混入无目标的图像),所以可能需要基于标注完的jason文件数目来反选出适合接入训练的数据。
copypic2dest.py

import os
import shutil

def copy_images_from_json(json_folder, image_folder, target_folder, image_extension=".jpg"):
    # 创建目标文件夹,如果不存在的话
    os.makedirs(target_folder, exist_ok=True)

    # 遍历 JSON 文件夹中的所有 .json 文件
    for json_file in os.listdir(json_folder):
        if json_file.endswith(".json"):
            # 获取不带扩展名的文件名
            file_name_without_extension = os.path.splitext(json_file)[0]

            # 查找对应的图片文件(假设图片扩展名为 .jpg 或其他格式)
            image_file = file_name_without_extension + image_extension
            image_path = os.path.join(image_folder, image_file)

            # 检查图片文件是否存在
            if os.path.exists(image_path):
                # 复制图片到目标文件夹
                target_image_path = os.path.join(target_folder, image_file)
                shutil.copy(image_path, target_image_path)
                print(f"已复制图片: {image_file} 到目标路径")
            else:
                print(f"未找到对应的图片: {image_file}")


# 使用示例
json_folder = "E:/skin_data/json/"  # JSON 文件所在的文件夹
image_folder = "E:/skin_data/pic/"  # 所有原图片所在的文件夹
target_folder = "E:/skin_data/yolo_img/"  # 符合需求的目标文件夹

# 调用函数进行拷贝
copy_images_from_json(json_folder, image_folder, target_folder, image_extension=".jpg")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何配置Java应用程序的远程调试

配置Java应用程序的远程调试涉及几个步骤&#xff0c;包括在启动Java应用程序时设置特定的JVM参数&#xff0c;以及在IDE&#xff08;如Eclipse、IntelliJ IDEA等&#xff09;中配置远程调试连接。以下是详细的步骤&#xff1a; 启动Java应用程序时启用远程调试 为了能够远程…

2025考研江南大学复试科目控制综合(初试807自动控制原理)

​ 2025年全国硕士研究生招生考试江南大学考点 一年年的考研如期而至&#xff0c;我也变成了研二了&#xff0c;作为2次考研经历的学长&#xff0c;总是情不自禁地回想起自己的考研经历&#xff0c;我也会经常从那段经历中汲取力量。我能理解大多数考生考完后的的迷茫无助&…

时间序列预测算法---LSTM

文章目录 一、前言1.1、深度学习时间序列一般是几维数据&#xff1f;每个维度的名字是什么&#xff1f;通常代表什么含义&#xff1f;1.2、为什么机器学习/深度学习算法无法处理时间序列数据?1.3、RNN(循环神经网络)处理时间序列数据的思路&#xff1f;1.4、RNN存在哪些问题?…

[羊城杯 2024]不一样的数据库_2

题目描述&#xff1a; 压缩包6 (1).zip需要解压密码&#xff1a; 尝试用ARCHPR工具爆破一下&#xff1a; &#xff08;字典可自行在github上查找&#xff09; 解压密码为&#xff1a;753951 解压得到13.png和Kee.kdbx文件&#xff1a; 二维码图片看上去只缺了正常的三个角&…

图像处理-Ch7-小波函数

个人博客&#xff01;无广告观看&#xff0c;因为这节内容太多了&#xff0c;有点放不下&#xff0c;分了三节 文章目录 多分辨率展开(Multi-resolution Expansions)序列展开(Series Expansions)尺度函数(Scaling Function)例&#xff1a;哈尔尺度函数(Haar scaling func)多分…

CPT203 Software Engineering 软件工程 Pt.2 敏捷方法和需求工程(中英双语)

文章目录 3. Aglie methods&#xff08;敏捷方法&#xff09;3.1 Aglie methods&#xff08;敏捷方法&#xff09;3.1.1 特点3.1.2 优点3.1.3 缺点3.1.4 原则3.1.5 计划驱动与敏捷方法的对比 3.2 Scrum3.2.1 Scrum roles3.2.2 Scrum Activities and Artifacts3.2.2.1 Product B…

【人工智能机器学习基础篇】——深入详解深度学习之神经网络基础:理解前馈神经网络与反向传播算法

深入详解深度学习之神经网络基础&#xff1a;理解前馈神经网络与反向传播算法 深度学习作为人工智能&#xff08;AI&#xff09;的核心技术&#xff0c;已经在语音识别、图像处理、自然语言处理等诸多领域取得了显著的成果。而在深度学习的众多模型中&#xff0c;**前馈神经网络…

【循环神经网络】RNN介绍

在人工神经网络中&#xff0c;”浅层网络”是指具有一个输入层、一个输出层和最多一个没有循环连接的隐藏层的网络。随着层数的增加&#xff0c;网络的复杂性也在增加。更多的层或循环连接通常会增加网络的深度&#xff0c;并使其能够提供不同级别的数据表示和特征提取&#xf…

【论文投稿】Python 网络爬虫:探秘网页数据抓取的奇妙世界

【IEEE出版|广东工业大学主办】第五届神经网络、信息与通信工程国际学术会议&#xff08;NNICE 2025&#xff09;_艾思科蓝_学术一站式服务平台 目录 前言 一、Python—— 网络爬虫的绝佳拍档 二、网络爬虫基础&#xff1a;揭开神秘面纱 &#xff08;一&#xff09;工作原…

基于深度学习的视觉检测小项目(二) 环境和框架搭建

一、环境和框架要求 SAM的环境要求&#xff1a; Python>3.7 PyTorch>1.7 torchvision>0.8 YOLO V8的环境要求&#xff1a;YOLO集成在ultralytics库中&#xff0c;ultralytics库的环境要求&#xff1a; Python>3.7 PyTorch>1.10.0 1、确定pytorch版本…

SQLiteDataBase数据库

XML界面设计 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:layout_width"match_paren…

cesium小知识: 处理动画的5种方式

在 Cesium 中处理动画可以通过多种方式实现,具体取决于你想要创建的动画类型。Cesium 提供了丰富的API来支持不同种类的动画,包括但不限于物体的移动、旋转、缩放、属性变化等。以下是几种常见的动画处理方法: 1. 使用 Entity 和 SampledProperty 对于动态数据或随时间变化…

【鸿蒙NEXT】鸿蒙里面类似iOS的Keychain——关键资产(@ohos.security.asset)实现设备唯一标识

前言 在iOS开发中Keychain 是一个非常安全的存储系统&#xff0c;用于保存敏感信息&#xff0c;如密码、证书、密钥等。与 NSUserDefaults 或文件系统不同&#xff0c;Keychain 提供了更高的安全性&#xff0c;因为它对数据进行了加密&#xff0c;并且只有经过授权的应用程序才…

visual studio连接sql server数据库

目录 1、为什么要建立连接2、在sql server中建立数据库3、visual studio连接sql server数据库4、学生信息管理系统页面布局5、添加事件逻辑 5.1 页面跳转5.2 读取学生信息5.3 查询学生信息5.4 修改学生信息5.5 删除学生信息5.6 添加学生信息 bilibili演示视频 github源码 1、…

STM32-笔记23-超声波传感器HC-SR04

一、简介 HC-SR04 工作参数&#xff1a; • 探测距离&#xff1a;2~600cm • 探测精度&#xff1a;0.1cm1% • 感应角度&#xff1a;<15 • 输出方式&#xff1a;GPIO • 工作电压&#xff1a;DC 3~5.5V • 工作电流&#xff1a;5.3mA • 工作温度&#xff1a;-40~85℃ 怎么…

vuex - 第一天

思维逻辑 解决问题 代码能力2 vue2的项目 北京前端鸿蒙6期 语雀 vuex 在组件中使用 插件支持v2和v3 宏任务 和 微任务 多问问自己为什么 new的四步 查找数组里是否包含某个元素 同步任务、异步任务、微任务、宏任务

三大行业案例:AI大模型+Agent实践全景

本文将从AI Agent和大模型的发展背景切入&#xff0c;结合51Talk、哈啰出行以及B站三个各具特色的行业案例&#xff0c;带你一窥事件驱动架构、RAG技术、人机协作流程&#xff0c;以及一整套行之有效的实操方法。具体包含内容有&#xff1a;51Talk如何让智能客服“主动进攻”&a…

STM32G0B1 can Error_Handler 解决方法

问题现象 MCU上电&#xff0c;发送0x13帧数据固定进入 Error_Handler 硬件介绍 MCU :STM32G0B1 can:NSI1042 tx 接TX RX 接RX 折腾了一下午&#xff0c;无解&#xff0c;问题依旧&#xff1b; 对比测试 STM32G431 手头有块G431 官方评估版CAN 模块&#xff1b; 同样的…

【服务器】上传文件到服务器并训练深度学习模型下载服务器文件到本地

前言&#xff1a;本文教程为&#xff0c;上传文件到服务器并训练深度学习模型&#xff0c;与下载服务器文件到本地。演示指令输入&#xff0c;完整的上传文件到服务器&#xff0c;并训练模型过程&#xff1b;并演示完整的下载服务器文件到本地的过程。 本文使用的服务器为云服…

基于微博热搜评论的情感分析与热点主题挖掘研究

目录 1、绪论 1.1 研究背景与研究意义 1.2 数据来源 1.3 技术路线 2、数据预处理 2.1 数据清洗与准备 2.2 导入必要库与加载数据 2.3 加载停用词表与分词处理 2.4 统计词频与高频词分析 3、情感分析与主题建模 3.1 情感分析 3.2 主题建模 3.3 热点主题识别 4、数据可视…