[目标检测] 训练之前要做什么

news2025/3/15 23:05:11

背景:训练一个Yolo8模型,在训练之前,数据集的处理是影响效果的关键因素。

Step1 定义规则

什么是人/车,比如人的话可能是站着的人,如果是骑电动车/自行车就不算是人。

Step2 收集数据集

1. 自己标注。如果是自己标注,那么根据上述的规则进行清洗。

2. 采集他人的数据集,标注好的。那么最好是能可视化一下标签。下面是可视化代码。

import os
import cv2

def visualize_yolo_boxes(image_folder, label_folder, output_folder):
    # 确保输出文件夹存在
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    # 遍历图片文件夹
    for image_name in os.listdir(image_folder):
        # 获取图片路径
        image_path = os.path.join(image_folder, image_name)
        # 获取对应的标签路径
        label_path = os.path.join(label_folder, os.path.splitext(image_name)[0] + '.txt')

        # 如果标签文件不存在,跳过
        if not os.path.exists(label_path):
            print(f"标签文件不存在: {label_path}")
            continue

        # 读取图片
        image = cv2.imread(image_path)
        if image is None:
            print(f"无法读取图片: {image_path}")
            continue

        # 获取图片的宽度和高度
        img_height, img_width = image.shape[:2]

        # 读取标签文件
        with open(label_path, 'r') as f:
            lines = f.readlines()

        # 遍历每个标签
        for line in lines:
            parts = line.strip().split()
            if len(parts) != 5:
                continue

            # 解析YOLO格式的标签
            class_id = int(parts[0])
            x_center = float(parts[1]) * img_width
            y_center = float(parts[2]) * img_height
            width = float(parts[3]) * img_width
            height = float(parts[4]) * img_height

            # 计算边界框的左上角和右下角坐标
            x1 = int(x_center - width / 2)
            y1 = int(y_center - height / 2)
            x2 = int(x_center + width / 2)
            y2 = int(y_center + height / 2)

            # 在图片上绘制边界框
            cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
            cv2.putText(image, f'Class {class_id}', (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

        # 保存可视化结果
        output_path = os.path.join(output_folder, image_name)
        cv2.imwrite(output_path, image)
        print(f"已保存可视化结果: {output_path}")

# 示例用法
image_folder = r'.\train\images'
label_folder = r'.\train\labels'
output_folder = r'.\train\visualize'

visualize_yolo_boxes(image_folder, label_folder, output_folder)

Step3 修改标签

修改标签是指,比如要合并一些标签。已经标注好的数据集,比如把车子分为了truck,car,bus之类的,但是,我们都统称为car。所以要进行一些合并。下面是合并代码。

import os
import glob

def process_line(line):
    """Process a single line of text according to the mapping rules."""
    parts = line.strip().split()
    if not parts:  # Skip empty lines
        return None
        
    try:
        id_num = int(parts[0])
        # Keep only specified IDs
        if id_num not in [0, 1, 2, 6]:
            return None
            
        # Apply mapping: 0,1 -> 0 and 3,4,5,8 -> 1
        if id_num in [0, 1, 6]:
            new_id = 1
        else:  # id in [3,4,5,8]
            new_id = 0
            
        # Replace first number and keep rest of the line the same
        return f"{new_id} {' '.join(parts[1:])}\n"
        
    except ValueError:
        return None

def process_file(input_path, output_path):
    """Process a single text file and save to output directory."""
    try:
        with open(input_path, 'r') as infile:
            lines = infile.readlines()
            
        # Process lines and filter out None results
        processed_lines = [
            processed for line in lines
            if (processed := process_line(line)) is not None
        ]
        
        # Create output directory if it doesn't exist
        os.makedirs(os.path.dirname(output_path), exist_ok=True)
        
        # Write processed lines to output file
        with open(output_path, 'w') as outfile:
            outfile.writelines(processed_lines)
            
        print(f"Processed {input_path} -> {output_path}")
        
    except Exception as e:
        print(f"Error processing {input_path}: {str(e)}")

def process_directory(input_dir, output_dir):
    """Process all .txt files in the input directory."""
    # Create output directory if it doesn't exist
    os.makedirs(output_dir, exist_ok=True)
    
    # Find all .txt files in input directory
    txt_files = glob.glob(os.path.join(input_dir, "*.txt"))
    
    for input_path in txt_files:
        # Create corresponding output path
        relative_path = os.path.relpath(input_path, input_dir)
        output_path = os.path.join(output_dir, relative_path)
        
        # Process the file
        process_file(input_path, output_path)

# Example usage
if __name__ == "__main__":
    input_directory = r"F:\1-dataset\raw\add_vehicle_person\combine\vehicle_class\valid\labels"  # Replace with your input directory
    output_directory = r"F:\1-dataset\raw\add_vehicle_person\combine\vehicle_class\valid\labels_person_car"  # Replace with your output directory
    
    process_directory(input_directory, output_directory)

 

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

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

相关文章

【工具】C#游戏防沉迷小工具

背景介绍 嘿,各位小伙伴!今天想跟大家唠唠我为啥要搞这么个防沉迷小工具。 咱都清楚,现在这游戏啊,玩起来那叫一个带劲,但时间一长,不仅眼睛累,心也跟着累。有些游戏,规则定得挺有意…

深圳南柯电子|净水器EMC测试整改:水质安全与电磁兼容性的双赢

在当今注重健康生活的时代,净水器作为家庭用水安全的第一道防线,其性能与安全性备受关注。其中,电磁兼容性(EMC)测试是净水器产品上市前不可或缺的一环,它直接关系到产品在复杂电磁环境中的稳定运行及不对其…

SpeechCraf论文学习

Abstract 核心问题 挑战 语音风格包含细微的多样化信息(如情感、语调、节奏),传统基于标签/模板的标注方法难以充分捕捉,制约了语音-语言多模态模型的性能。 数据瓶颈: 大规模数据收集与高质量标注之间存在矛盾&…

Work【2】:PGP-SAM —— 无需额外提示的自动化 SAM!

文章目录 前言AbstractIntroductionMethodsContextual Feature ModulationProgressive Prototype RefinementPrototype-based Prompt Generator ExperimentDatasetsImplementation DetailsResults and AnalysisAblation Study 总结 前言 和大家分享一下我们发表在 ISBI 2025 上…

数据安全之策:备份文件的重要性与自动化实践

在信息化高速发展的今天,数据已成为企业运营和个人生活中不可或缺的重要资源。无论是企业的财务报表、客户资料,还是个人的家庭照片、学习笔记,数据的丢失或损坏都可能带来无法挽回的损失。因此,备份文件的重要性日益凸显&#xf…

uniapp+Vue3 组件之间的传值方法

一、父子传值&#xff08;props / $emit 、ref / $refs&#xff09; 1、props / $emit 父组件通过 props 向子组件传递数据&#xff0c;子组件通过 $emit 触发事件向父组件传递数据。 父组件&#xff1a; // 父组件中<template><view class"container">…

blender使用初体验(甜甜圈教程)

使用blender 建模了甜甜圈&#xff0c;时间空闲了&#xff0c;但愿能创建点好玩的吸引人的东西

大模型学习笔记------Llama 3模型架构之旋转编码(RoPE)

大模型学习笔记------Llama 3模型架构之旋转编码&#xff08;RoPE&#xff09; 1、位置编码简介1.1 绝对位置编码1.2 相对位置编码 2、旋转编码&#xff08;RoPE&#xff09;2.1 基本概念---旋转矩阵2.2 RoPE计算原理2.2.1 绝对位置编码2.2.2 相对位置编码 3、旋转编码&#xf…

04 1个路由器配置一个子网的dhcp服务

前言 这是最近一个朋友的 ensp 相关的问题, 这里来大致了解一下 ensp, 计算机网络拓扑 相关基础知识 这里一系列文章, 主要是参照了这位博主的 ensp 专栏 这里 我只是做了一个记录, 自己实际操作了一遍, 增强了一些 自己的理解 当然 这里仅仅是一个 简单的示例, 实际场景…

安装open-webui

open-webui是一个开源的大语言模型交互界面 前提&#xff1a;Ollama已安装&#xff0c;并下载了deepseek-r1:1.5b模型 拉取镜像 docker pull ghcr.io/open-webui/open-webui:main 配置docker-compose.yml services:open-webui:image: ghcr.io/open-webui/open-webui:mainv…

HCIA-11.以太网链路聚合与交换机堆叠、集群

链路聚合背景 拓扑组网时为了高可用&#xff0c;需要网络的冗余备份。但增加冗余容易后会出现环路&#xff0c;所以我们部署了STP协议来破除环路。 但是&#xff0c;根据实际业务的需要&#xff0c;为网络不停的增加冗余是现实需要的一部分。 那么&#xff0c;为了让网络冗余…

Amazon RDS ProxySQL 探索(一)

:::info &#x1f4a1; 在日常开发中&#xff0c;开发者们会涉及到数据库的连接&#xff0c;在使用Amazon RDS数据库时&#xff0c;若使用集群模式或者多数据库时&#xff0c;会出现一写多读多个Endpoint&#xff0c;在实际开发中&#xff0c; 开发者们配置数据库连接通常希望走…

200多种算法应用于二维和三维无线传感器网络(WSN)覆盖场景

2.1 二元感知模型 在当前无线传感器网络&#xff08;WSN&#xff09;覆盖场景中&#xff0c;最常见且理想的感知模型是二元感知模型[27]。如图2所示&#xff0c; Q 1 Q_1 Q1​和 Q 2 Q_2 Q2​代表平面区域内的两个随机点。 Q 1 Q_1 Q1​位于传感器的检测区域内&#xff0c;其感…

模拟类似 DeepSeek 的对话

以下是一个完整的 JavaScript 数据流式获取实现方案&#xff0c;模拟类似 DeepSeek 的对话式逐段返回效果。包含前端实现、后端模拟和详细注释&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><titl…

Flutter PopScope对于iOS设置canPop为false无效问题

这个问题应该出现很久了&#xff0c;之前的组件WillPopScope用的好好的&#xff0c;flutter做优化打算“软性”处理禁用返回手势&#xff0c;出了PopScope&#xff0c;这个组件也能处理在安卓设备上的左滑返回事件。但是iOS上面左滑返回手势禁用&#xff0c;一直无效。 当然之…

SpringBoot + ResponseBodyEmitter 实时异步流式推送,优雅!

ChatGPT 的火爆&#xff0c;让流式输出技术迅速走进大众视野。在那段时间里&#xff0c;许多热爱钻研技术的小伙伴纷纷开始学习和实践 SSE 异步处理。 我当时也写过相关文章&#xff0c;今天&#xff0c;咱们换一种更为简便的方式来实现流式输出&#xff0c;那就是 ​​Respon…

网络运维学习笔记(DeepSeek优化版) 016 HCIA-Datacom综合实验01

文章目录 综合实验1实验需求总部特性 分支8分支9 配置一、 基本配置&#xff08;IP二层VLAN链路聚合&#xff09;ACC_SWSW-S1SW-S2SW-Ser1SW-CoreSW8SW9DHCPISPGW 二、 单臂路由GW 三、 vlanifSW8SW9 四、 OSPFSW8SW9GW 五、 DHCPDHCPGW 六、 NAT缺省路由GW 七、 HTTPGW 综合实…

02 windows qt配置ffmpeg开发环境搭建

版本说明 首先我使用ffmpeg版本是4.2.1 QT使用版本5.14.2 我选择是c编译 在02Day.pro⾥⾯添加ffmpeg头⽂件和库⽂件路径 win32 { INCLUDEPATH $$PWD/ffmpeg-4.2.1-win32-dev/include LIBS $$PWD/ffmpeg-4.2.1-win32-dev/lib/avformat.lib \$$PWD/ffmpeg-4.2.1-win32-dev/l…

vue-treeselect 【单选/多选】的时候只选择最后一层(绑定的值只绑定最后一层)

欢迎访问我的个人博客 &#xff5c;snows_ls BLOGhttp://snows-l.site 一、单选 1、问题&#xff1a; vue-treeselect 单选的时候只选择最后一层&#xff08;绑定的值只绑定最后一层&#xff09; 2、方法 1、只需要加上 :disable-branch-nodes"true" 就行&#xff0…

微信小程序实现根据不同的用户角色显示不同的tabbar并且可以完整的切换tabbar

直接上图上代码吧 // login/login.js const app getApp() Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad(options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady() {},/*** 生命周期函数--监听页面显示*/onShow() {},/*** 生命周期函…