首页 > 其他分享 >基于yolov8进行目标识别的文件部署步骤

基于yolov8进行目标识别的文件部署步骤

时间:2024-08-10 17:52:22浏览次数:16  
标签:txt name img 步骤 yolov8 path 识别 os dir

1  yolov8模型简介

YOLOv8(You Only Look Once version 8)是YOLO(You Only Look Once)系列模型的最新版本,延续了YOLO系列的实时目标检测方法。YOLOv8在架构、训练过程和性能方面做了多项改进,旨在提升检测精度和速度。以下是YOLOv8的主要特点和改进:

1. 改进的网络架构:
   - YOLOv8采用了更新的架构设计,相比于之前的版本,它使用了更深层次的卷积神经网络,并结合了新的特征提取模块,如Focus、CSP(Cross Stage Partial Network)等,以提高模型的表达能力和特征提取能力。

2. 自适应锚框生成:
   - YOLOv8引入了自适应锚框生成策略,这使得模型可以根据数据集自动调整锚框的大小和形状,从而提升了检测精度,特别是在处理多尺度目标时。

3. 改进的损失函数:
   - YOLOv8采用了改进的损失函数,结合了分类损失、边界框回归损失和IoU(Intersection over Union)损失,进一步优化了模型的训练过程和收敛速度。

4. 混合数据增强:
   - 为了增强模型的鲁棒性,YOLOv8引入了多种数据增强技术,如Mosaic增强、MixUp增强等,这些技术可以有效增加训练数据的多样性,减少过拟合风险。

5. 多任务学习:
   - YOLOv8支持多任务学习,可以同时进行目标检测、实例分割和姿态估计等任务,这使得模型在多种计算机视觉任务中具有更广泛的应用。

6. 轻量化和高效推理:
   - YOLOv8注重轻量化设计,在保持高精度的同时,减少了模型的参数量和计算量,适用于资源有限的设备,如嵌入式设备和移动设备。

7. 简化的部署:
   - YOLOv8提供了更易于部署的模型格式和工具,支持多种硬件加速器(如GPU、TPU等)以及多种框架(如TensorFlow、PyTorch等),方便在不同平台上快速集成和应用。

YOLOv8的这些改进使其在多个目标检测任务中表现出色,广泛应用于自动驾驶、智能监控、机器人视觉、智慧城市等领域。

2  步骤

2.1  获取照片

方法一:浏览器爬取

我用的是Bing爬取

import os
import requests
from bs4 import BeautifulSoup
from PIL import Image
from io import BytesIO
import time

# 请求头部
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}

# 搜索URL
search_url = "https://www.bing.com/images/async?q={0}&first={1}&count={2}&scenario=ImageBasicHover&datsrc=N_I&layout=ColumnBased&mmasync=1"

def get_image_urls(search_term, num_images):
    '''从Bing中获取图片URL'''
    search_term_encoded = requests.utils.quote(search_term)  # URL编码
    urls = []
    first = 1
    count = 35  # 每页的图片数量

    while len(urls) < num_images:
        url = search_url.format(search_term_encoded, first, count)
        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.text, 'html.parser')

        # 查找图片URL
        img_tags = soup.find_all("img")
        for img_tag in img_tags:
            img_url = img_tag.get('src')
            if img_url and img_url.startswith('http'):
                urls.append(img_url)
                if len(urls) >= num_images:
                    break

        first += count  # 更新为下一页
        time.sleep(1)  # 防止过于频繁的请求

    return urls

def download_images(image_urls, save_dir):
    '''下载图片并保存到指定目录'''
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    for i, url in enumerate(image_urls):
        try:
            response = requests.get(url)
            response.raise_for_status()
            image = Image.open(BytesIO(response.content))
            file_path = os.path.join(save_dir, f"Pi{i+1}.png")
            image.save(file_path, format='PNG')
            print(f"Downloaded {i+1}/{len(image_urls)}: {url}")
        except requests.exceptions.HTTPError as e:
            print(f"HTTP error occurred for {url}: {e}")
        except Exception as e:
            print(f"Could not download {url}: {e}")

# 主程序
if __name__ == '__main__':
    search_term =   # 搜索关键词
    num_images =   # 设置要下载的图片数量
    save_dir =  # 设置保存图片的目录

    # 获取图片URL并下载图片
    image_urls = get_image_urls(search_term, num_images)
    if image_urls:
        download_images(image_urls, save_dir)
    else:
        print("No images found or there was an error retrieving images.")

方法二:自己拍摄照片

这里注意自己拍摄的照片可能过大,需要进行压缩处理,否则后续程序会跑的很慢

压缩图片代码:

import os
import cv2

def resize_images(input_dir, output_dir, target_size):
    # 如果输出目录不存在,则创建它
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # 遍历输入目录中的所有文件
    for img_name in os.listdir(input_dir):
        img_path = os.path.join(input_dir, img_name)
        # 读取图像
        img = cv2.imread(img_path)
        if img is not None:
            # 调整图像大小
            resized_img = cv2.resize(img, target_size)
            # 保存调整后的图像到输出目录
            output_path = os.path.join(output_dir, img_name)
            cv2.imwrite(output_path, resized_img)
            print(f"Resized and saved {img_name} to {output_dir}")

# 定义输入目录、输出目录和目标图像大小
input_dir = r
output_dir = r
target_size = (416, 416)  # 目标分辨率

# 调整图像大小
resize_images(input_dir, output_dir, target_size)

当然,如果原图片是png等其他格式,可以转换成jpg格式 

转换格式代码:

import os
import cv2

def convert_png_to_jpg(input_dir, output_dir):
    # 如果输出目录不存在,则创建它
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # 遍历输入目录中的所有文件
    for img_name in os.listdir(input_dir):
        if img_name.lower().endswith(".png"):  # 检查是否为.png文件
            img_path = os.path.join(input_dir, img_name)
            # 读取图像
            img = cv2.imread(img_path)
            if img is not None:
                # 修改文件扩展名为.jpg
                base_name = os.path.splitext(img_name)[0]
                output_name = base_name + ".jpg"
                output_path = os.path.join(output_dir, output_name)
                # 保存图像为JPEG格式
                cv2.imwrite(output_path, img, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
                print(f"Converted {img_name} to {output_name} and saved to {output_dir}")

# 定义输入目录和输出目录
input_dir = r
output_dir = r

# 转换图像格式
convert_png_to_jpg(input_dir, output_dir)

2.2  圈画图片

这里建议采用labelimg软件进行圈画图片,若遇到打不开图片(无法打开jpg等格式的图片),那么可以考虑在命令行中输入labelimg后面加图片路径的形式

这一步能够生成.xml文件,这便是圈画的结果,这个.xml文件是用来跑Mx-yolov3软件内的yolov2模型的,就是借助这个操作获取分割好的数据集

原图片放置在JPEGImages文件夹内,.xml文件放置在Annotations文件夹内

然后再把.xml文件转为.txt文件,这个.txt文件是下面需要用到的

格式转换代码:

import xml.etree.ElementTree as ET
import os


def convert(size, box):
    """
    Convert bounding box to YOLO format.
    Arguments:
    - size: (width, height) of the image
    - box: (xmin, xmax, ymin, ymax) bounding box coordinates
    Returns:
    - (x_center, y_center, width, height) in YOLO format
    """
    dw = 1.0 / size[0]
    dh = 1.0 / size[1]
    x_center = (box[0] + box[1]) / 2.0
    y_center = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x_center = x_center * dw
    w = w * dw
    y_center = y_center * dh
    h = h * dh
    return (x_center, y_center, w, h)


def convert_annotation(xml_file, save_txt_file, classes):
    """
    Convert VOC XML annotation to YOLO format and save as a .txt file.
    Arguments:
    - xml_file: path to the XML file
    - save_txt_file: path to save the converted .txt file
    - classes: list of class names
    """
    tree = ET.parse(xml_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    with open(save_txt_file, 'w') as out_txt_f:
        for obj in root.iter('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            if cls not in classes or int(difficult) == 1:
                continue
            cls_id = classes.index(cls)
            xmlbox = obj.find('bndbox')
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text),
                 float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
            bb = convert((w, h), b)
            out_txt_f.write(f"{cls_id} " + " ".join([str(a) for a in bb]) + '\n')


def process_annotations(xml_files_path, save_txt_files_path, classes):
    """
    Process all XML files in a directory and convert them to YOLO format.
    Arguments:
    - xml_files_path: directory containing XML files
    - save_txt_files_path: directory to save the converted .txt files
    - classes: list of class names
    """
    if not os.path.exists(save_txt_files_path):
        os.makedirs(save_txt_files_path)

    xml_files = [f for f in os.listdir(xml_files_path) if f.endswith('.xml')]

    for xml_name in xml_files:
        xml_file = os.path.join(xml_files_path, xml_name)
        save_txt_file = os.path.join(save_txt_files_path, xml_name.replace('.xml', '.txt'))
        convert_annotation(xml_file, save_txt_file, classes)
        print(f"Converted {xml_file} to {save_txt_file}")


if __name__ == "__main__":
    # List of classes to be considered for conversion
    classes1 = []#填写标签名称,按顺序
    # Path to the directory containing XML files
    xml_files1 = r#输入路径
    # Path to the directory where YOLO format .txt files will be saved
    save_txt_files1 = r#输出路径

    process_annotations(xml_files1, save_txt_files1, classes1)

2.3  配置数据集

我采用的是Mx-yolov3软件(3.0版本不用配置环境,建议下这个),然后能够自动并且较为科学地分割出训练集和测试集,当然在这个之前建议把文件按顺序编号(两个格式,原图片和.txt),便于查找

分配编号代码:

import os


def rename_files_with_sequence(folder_path):
    """
    Renames all files in the given folder with a sequence number.
    Arguments:
    - folder_path: the path to the folder containing the files to be renamed.
    """
    # 获取文件夹中的所有文件(不包括文件夹)
    files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f))]

    # 对文件名进行自然排序
    files.sort()

    # 按顺序重命名文件
    for index, filename in enumerate(files, start=1):
        # 提取文件的扩展名
        file_extension = os.path.splitext(filename)[1]
        # 生成新的文件名(没有前缀)
        new_name = f"{index}{file_extension}"
        # 获取旧文件的完整路径
        old_file = os.path.join(folder_path, filename)
        # 获取新文件的完整路径
        new_file = os.path.join(folder_path, new_name)

        # 重命名文件
        os.rename(old_file, new_file)
        print(f"Renamed: {filename} -> {new_name}")


if __name__ == "__main__":
    # 文件夹路径
    folder_path = r  # 请替换为你要处理的文件夹路径

    # 调用重命名函数
    rename_files_with_sequence(folder_path)

然后按照Mx-yolov3帮我们分割好的数据集代码,就可以挑选出.txt文件和原图片的数据集了

2.4  修改yolov8模型源代码的参数

这一部分可以参考他人的教程,最后跑完的结果就在runs文件里了

标签:txt,name,img,步骤,yolov8,path,识别,os,dir
From: https://blog.csdn.net/m0_71934846/article/details/141093558

相关文章