记录第一次跑YOLOV8做目标检测
今天是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 filesif filename.endswith(('.jpg', '.jpeg', '.png', '.bmp')):image_path = os.path.join(input_dir, filename)# Run inferenceresults = trained_model.predict(source=image_path, conf=0.3, save=False)# Get the first (and usually only) resultresult = results[0] # Access the first result in the list# Get the original image from the resultimg = result.orig_img# Accessing the detection boxes and labelsboxes = result.boxes # This contains the detection boxesclass_ids = boxes.cls # Class indices for each boxconfidences = boxes.conf # Confidence scores for each detection# Draw bounding boxes on the imagefor i in range(len(boxes)):# Get the coordinates of the box (x1, y1, x2, y2) from xyxy formatx1, y1, x2, y2 = boxes.xyxy[i].int().tolist() # Convert tensor to list of integers# Draw the bounding boxcv2.rectangle(img, (x1, y1), (x2, y2), box_color, line_thickness)# Get the label (class name) and confidencelabel = 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 imageresult_image_path = os.path.join(output_dir, f"result_{filename}")cv2.imwrite(result_image_path, img) # Save image with bounding boxesprint(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}")continueyolo_labels = []for shape in data['shapes']:label = shape['label']if label not in classes:print(f"未识别的类别: {label}, 请在 classes 中添加该类别。")continue# 获取类别 IDclass_id = classes.index(label)# 解析边界框的点points = shape['points']print(f"标注类型: {label}, 标注坐标: {points}")if len(points) < 2: # 如果不是矩形框,可能需要其他处理print(f"警告:{file} 中的标注无效,跳过。")continuex_min, y_min = points[0]x_max, y_max = points[1]# 计算 YOLO 格式的中心点和宽高(归一化)x_center = (x_min + x_max) / 2 / image_widthy_center = (y_min + y_max) / 2 / image_heightwidth = (x_max - x_min) / image_widthheight = (y_max - y_min) / image_heightyolo_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 shutildef 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_extensionimage_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")
相关文章:
记录第一次跑YOLOV8做目标检测
今天是24年的最后一天,终于要向新世界开始破门了,开始深度学习,YOLO来敲门~ 最近做了一些皮肤检测的功能,在传统的处理中经历了反复挣扎,终于要上YOLO了。听过、看过,不如上手体会过~ 1、YOLO是什么&#x…...
使用Python爬取BOSS直聘职位数据并保存到Excel
使用Python爬取BOSS直聘职位数据并保存到Excel 在数据分析和挖掘中,爬取招聘网站数据是一项常见的任务。本文将详细介绍如何使用Python爬取BOSS直聘上与“测试工程师”相关的职位数据,并将其保存到Excel文件中。通过逐步分解代码和添加详细注释…...
node.js之---集群(Cluster)模块
为什么会有集群(Cluster)模块? 集群(Cluster)模块的作用 如何使用集群(Cluster)模块? 为什么会有集群(Cluster)模块 Node.js 是基于 单线程事件驱动 模型的…...
SSM-Spring-IOC/DI对应的配置开发
目录 一、IOC 控制反转 1.什么是控制反转呢 2. Spring和IOC之间的关系是什么呢? 3.IOC容器的作用以及内部存放的是什么? 4.当IOC容器中创建好service和dao对象后,程序能正确执行么? 5.Spring 容器管理什么内容? 6.如何将需要管理的对象交给 …...
一文大白话讲清楚CSS元素的水平居中和垂直居中
文章目录 一文大白话讲清楚CSS元素的水平居中和垂直居中1.已知元素宽高的居中方案1.1 利用定位margin:auto1.2 利用定位margin负值1.3 table布局 2.未知元素宽高的居中方案2.1利用定位transform2.2 flex弹性布局2.3 grid网格布局 3. 内联元素的居中布局 一文大白话讲清楚CSS元素…...
航顺芯片推出HK32A040方案,赋能汽车矩阵大灯安全与智能化升级
汽车安全行驶对整车照明系统的要求正在向智能化方向发展。车灯位于汽车两侧,前期有各种各样的实现包括氙气灯、LED灯等等光源技术。矩阵大灯对汽车照明系统朝着安全性和智能化兼具的方向发展起到了重要推动作用。矩阵大灯可以精细控制到每一个小灯珠,从而…...
智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之12 方案再探:特定于领域的模板 之2 首次尝试和遗留问题解决
本文提要 现在就剩下“体”本身的 约定了--这必然是 自律自省的,或者称为“戒律” --即“体”的自我训导discipline。完整表述为: 严格双相的庄严“相” (<head>侧),完全双性的本质“性”(<boot>侧&…...
redis zset底层实现
1.Redis zset底层实现 转载自:https://marticles.github.io/2019/03/19/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Redis-Zset%E5%8E%9F%E7%90%86/ zset底层是压缩列表 跳表实现的。 跳表里面又由字典hash表 跳表实现。 什么时候用压缩列表?什么时候用…...
go.Bar如何让hovertext显示为legend
在 Plotly 的 go.Bar 图中,如果你想让鼠标悬停时 (hover) 显示的文本 (hovertext) 与图例 (legend) 一致,可以通过 hovertemplate 来控制悬停时的显示内容。 实现方法 hovertemplate 是一种自定义工具,允许你完全控制悬停时的文本显示格式。…...
【Vue】分享一个快速入门的前端框架以及如何搭建
先上效果图: 登录 菜单: 下载地址: 链接:https://pan.baidu.com/s/1m-ZlBARWU6_2n8jZil_RAQ 提取码:ui20 … 主要是可以自定义设置token,更改后端请求地址较为方便。 应用设置: 登录与token设置: 在这里设置不用登录,可以请求的接口: request.js i…...
Flink源码解析之:如何根据JobGraph生成ExecutionGraph
Flink源码解析之:如何根据JobGraph生成ExecutionGraph 在上一篇Flink源码解析中,我们介绍了Flink如何根据StreamGraph生成JobGraph的流程,并着重分析了其算子链的合并过程和JobGraph的构造流程。 对于StreamGraph和JobGraph的生成来说&…...
UE(虚幻)学习(三) UnrealSharp插件中调用非托管DLL
上一篇文章中我使用UnrealSharp成功使用了我的一个C#控制台程序中的网络模块,这个程序是基于KCP网络了,其中调用了Cmake 编译的一个C的DLL,在虚幻中DLL需要放在Binaries目录中才可以。Unity中只要放在任意Plugins目录中就可以。 但是Binaries…...
leetcode 3219. 切蛋糕的最小总开销 II
题目:3219. 切蛋糕的最小总开销 II - 力扣(LeetCode) 排序贪心。 开销越大的越早切。 注意m或n为1的情况。 class Solution { public:long long minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>&…...
vant 地址记录
vant ui 的官网地址记录 vant 4 Vant 4 - A lightweight, customizable Vue UI library for mobile web apps. vant2 https://vant-ui.github.io/vant/v2/ vant3 Vant 3 - Lightweight Mobile UI Components built on Vue...
Lua语言入门 - Lua常量
在Lua中,虽然没有直接的常量关键字(如C中的const),但你可以通过一些编程技巧和约定来实现类似常量的行为。以下是几种常见的方法: 1. 使用全局变量并命名规范 你可以定义一个全局变量,并通过命名约定来表示…...
在Microsoft Windows上安装MySQL
MySQL仅适用于Microsoft Windows 64位操作系统,在Microsoft Windows上安装MySQL有不同的方法:MSI、包含您解压缩的所有必要文件的标准二进制版本(打包为压缩文件)以及自己编译MySQL源文件。 注意:MySQL8.4服务器需要在…...
windows下vscode使用msvc编译器出现中文乱码
文章目录 [toc]1、概述2、修改已创建文件编码3、修改vscode默认编码 更多精彩内容👉内容导航 👈👉C 👈👉开发工具 👈 1、概述 在使用MSVC编译器时,出现中文报错的问题可能与编码格式有关。UTF-…...
Git 解决 everything up-to-date
首先使用git log查看历史提交,找到最新一次提交,比如: PS D:\Unity Projects\CoffeeHouse\CoffeeHouse_BurstDebugInformation_DoNotShip> git log commit a1b54c309ade7c07c3981d3ed748b0ffac2759a3 (HEAD -> master, origin/master)…...
Windows配置cuda,并安装配置Pytorch-GPU版本
文章目录 1. CUDA Toolkit安装2. 安装cuDNN3. 添加环境变量配置Pytorch GPU版本 博主的电脑是Windows11,在安装cuda之前,请先查看pytorch支持的版本,cuda可以向下兼容,但是pytorch不行,请先进入:https://py…...
Neo4j 图数据库安装与操作指南(以mac为例)
目录 一、安装前提条件 1.1 Java环境 1.2 Homebrew(可选) 二、下载并安装Neo4j 2.1 从官方网站下载 2.1.1 访问Neo4j的官方网站 2.1.2 使用Homebrew安装 三、配置Neo4j 3.1 设置环境变量(可选) 3.2 打开配置文件(bash_profile) 3.2.1 打开终端…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...
