YoloV8实战:使用YoloV8实现水下目标检测(RUOD)

news2024/11/18 6:17:19

摘要

水下目标检测技术在生态监测、管道检修、沉船捕捞等任务中发挥着重要作用。常用的检测方法包括高清视像、侧扫声呐等。光学图像检测因高分辨率和灵活性,在近距离检测中优势显著。但水下图像受水体吸收、衰减、光源分布等影响,呈现蓝绿色,且存在低对比度、非均匀光照、模糊、亮斑和高噪声等问题。此外,水下环境复杂,数据集相对较少,目标小且分布密集,重叠遮挡现象常见。现有的检测算法在复杂水下环境中精确度有限。URPC2021和DUO等数据集为水下目标检测研究提供了重要资源。DUO为URPC挑战赛多年数据集的整合,对其中重复数据进行删除,训练集并且对有误的标签进行了重新标注。

下载链接:

https://github.com/xiaoDetection/RUOD

或者
https://aistudio.baidu.com/datasetdetail/216919(这个链接下载速度快,飕飕的)
数据集格式:COCO格式

类别:

holothurian,echinus,scallop,starfish,fish,corals,diver,cuttlefish,turtle,jellyfish10个常见类别

数据集转换与可视化

项目结构如下:

在这里插入图片描述

将数据集转成Yolo格式

代码:

import json
import glob
import os
import shutil
from pathlib import Path
import numpy as np
from tqdm import tqdm


def make_folders(path='./coco/'):
    # Create folders

    if os.path.exists(path):
        shutil.rmtree(path)  # delete output folder
    os.makedirs(path)  # make new output folder
    os.makedirs(path + os.sep + 'labels')  # make new labels folder
    os.makedirs(path + os.sep + 'images')  # make new labels folder
    return path


def convert_coco_json(json_dir='./RUOD/RUOD_ANN/'):
    jsons = glob.glob(json_dir + '*.json')

    # Import json
    for json_file in sorted(jsons):
        fn = 'coco/labels/%s/' % Path(json_file).stem.replace('instances_', '')  # folder name
        fn_images = 'coco/images/%s/' % Path(json_file).stem.replace('instances_', '')  # folder name
        os.makedirs(fn, exist_ok=True)
        os.makedirs(fn_images, exist_ok=True)
        with open(json_file) as f:
            data = json.load(f)
        print(fn)
        # Create image dict
        images = {'%g' % x['id']: x for x in data['images']}

        # Write labels file
        for x in tqdm(data['annotations'], desc='Annotations %s' % json_file):
            if x['iscrowd']:
                continue

            img = images['%g' % x['image_id']]
            h, w, f = img['height'], img['width'], img['file_name']
            file_path = './RUOD/RUOD_pic/' + fn.split('/')[-2] + "/" + f
            # The Labelbox bounding box format is [top left x, top left y, width, height]
            box = np.array(x['bbox'], dtype=np.float64)
            box[:2] += box[2:] / 2  # xy top-left corner to center
            box[[0, 2]] /= w  # normalize x
            box[[1, 3]] /= h  # normalize y

            if (box[2] > 0.) and (box[3] > 0.):  # if w > 0 and h > 0
                with open(fn + Path(f).stem + '.txt', 'a') as file:
                    file.write('%g %.6f %.6f %.6f %.6f\n' % (x['category_id'] - 1, *box))
            file_path_t = fn_images + f
            print(file_path, file_path_t)
            shutil.copy(file_path, file_path_t)


convert_coco_json()

可视化

import cv2
import os

def draw_box_in_single_image(image_path, txt_path):
    # 读取图像
    image = cv2.imread(image_path)

    # 读取txt文件信息
    def read_list(txt_path):
        pos = []
        with open(txt_path, 'r') as file_to_read:
            while True:
                lines = file_to_read.readline()  # 整行读取数据
                if not lines:
                    break
                # 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。
                p_tmp = [float(i) for i in lines.split(' ')]
                pos.append(p_tmp)  # 添加新读取的数据
                # Efield.append(E_tmp)
                pass
        return pos


    # txt转换为box
    def convert(size, box):
        xmin = (box[1]-box[3]/2.)*size[1]
        xmax = (box[1]+box[3]/2.)*size[1]
        ymin = (box[2]-box[4]/2.)*size[0]
        ymax = (box[2]+box[4]/2.)*size[0]
        box = (int(xmin), int(ymin), int(xmax), int(ymax))
        return box

    pos = read_list(txt_path)
    print(pos)
    tl = int((image.shape[0]+image.shape[1])/2)
    lf = max(tl-1,1)
    for i in range(len(pos)):
        label = str(int(pos[i][0]))
        print('label is '+label)
        box = convert(image.shape, pos[i])
        image = cv2.rectangle(image,(box[0], box[1]),(box[2],box[3]),(0,0,255),2)
        cv2.putText(image,label,(box[0],box[1]-2), 0, 1, [0,0,255], thickness=2, lineType=cv2.LINE_AA)
        pass

    if pos:
        cv2.imwrite('./VOCData/see_images/{}.png'.format(image_path.split('\\')[-1][:-4]), image)
    else:
        print('None')

    print('./VOCData/see_images/{}.png'.format(image_path.split('\\')[-1][:-4]))
    # cv2.imshow("images", image)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()


img_folder = "./coco/images/train"
img_list = os.listdir(img_folder)
img_list.sort()

label_folder = "./coco/labels/train"
label_list = os.listdir(label_folder)
label_list.sort()
if not os.path.exists('./VOCData/see_images'):
    os.makedirs('./VOCData/see_images')
for i in range(len(img_list)):
    image_path = img_folder + "\\" + img_list[i]
    txt_path = label_folder + "\\" + label_list[i]
    draw_box_in_single_image(image_path, txt_path)

在这里插入图片描述

在这里插入图片描述

训练

完成上面的数据准备工作就可以开启训练了。将得到的数据集放到datasets文件夹下面,在项目的根目录新建coco.yaml,如下图:
在这里插入图片描述

coco.yaml插入内容:

train: ./coco/images/train # train images
val: ./coco/images/test # val images

names: ['holothurian', 'echinus', 'scallop', 'starfish','fish','corals','diver','cuttlefish','turtle','jellyfish']

然后新建train.py,插入内容:

from ultralytics import YOLO
import os

if __name__ == '__main__':
    model = YOLO(model="ultralytics/cfg/models/v8/yolov8s.yaml")  # 从头开始构建新模型
    print(model)

    # Use the model
    results = model.train(data="coco.yaml", patience=0, epochs=50, device='0', batch=16, seed=42)  # 训练模

在这里插入图片描述
然后,运行train.py,就可以开启训练了!如下图:
在这里插入图片描述

测试结果

在这里插入图片描述

验证

代码如下:

from ultralytics import YOLO


if __name__ == '__main__':
    # Load a model
    # model = YOLO('yolov8m.pt')  # load an official model
    model = YOLO('runs/detect/train/weights/best.pt')  # load a custom model


    # Validate the model
    metrics = model.val(split='val',save_json=True)  # no arguments needed, dataset and settings remembered

split参数设置为val,则测试val指向数据集,如果设置为test,则测试test指向的数据集。本次没有test,所以我们只能设置为val。

save_json设置为True,则会保存类似coco格式的json文件。如下图:

在这里插入图片描述

测试

新建test.py,插入代码:

from ultralytics import YOLO

if __name__ == '__main__':
    # Load a model
    # model = YOLO('yolov8m.pt')  # load an official model
    model = YOLO('runs/detect/train/weights/best.pt')  # load a custom model
    results = model.predict(source="ultralytics/assets", device='0', visualize=True, save=True)  # predict on an image
    print(results)

其他的参数就不解释了!说一说YoloV8里没有介绍,或者难以理解的参数。
visualize设置为True,可视化每层的特征。设置后,会生成每层的特征,如下图:
在这里插入图片描述
保存的路径:
在这里插入图片描述
stage后面的数字代表的是YoloV8网络中的层,里面有两种文件,png文件是抽取的特征组成的图片,npy文件则是保存了所有的特征信息。读取方式:

#导入所需的包
import numpy as np

#导入npy文件路径位置
test = np.load('runs/detect/predict/zidane/stage2_C2f_features.npy')

print(test.shape[0])

总结

本次实战讲解了RUOD数据集的使用,以及训练、验证相关的知识。不知道还有没有遗漏的,欢迎大家补充。

完整的代码:


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

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

相关文章

拾光坞N3 ARM 虚拟主机 i茅台项目

拾光坞N3 在Dcoker部署i茅台案例 OS:Ubuntu 22.04.1 LTS aarch64 cpu:RK3566 ram:2G 部署流程——》mysql——》java8——》redis——》nginx mysql # 依赖 apt update apt install -y net-tools apt install -y libaio* # 下载mysql wg…

太阳能自动气象站讲解

TH-QC10随着科技的不断进步和环保意识的日益增强,太阳能自动气象站逐渐成为了气象观测领域的新宠。这种结合了清洁能源与先进技术的装置,不仅为气象数据的获取提供了更为便捷、高效的方式,同时也为环保事业贡献了自己的力量。 一、太阳能自动…

PCI总线学习笔记:读写篇

前言 最近在写E1000网卡的驱动,这其中涉及到了PCI总线的相关内容。但是网上大部分关于PCI的文章都只局限在概念上的描述,并没有给出具体的例子来解释。这其实也是情理之中的,因为PCI总线规范就像是一个抽象的接口,其具体怎么实现…

[LeetCode][LCR133]位 1 的个数——快速从右边消去1

题目 LCR 133. 位 1 的个数 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).)。 提示: 请注意,在某些语言…

CTF之矛盾

这一题就是php的弱比较“” 这里要求输入的不是数字,并且输入要为1才打印flag 那我们就输入一个1后面接随便什么字符,因为php的弱比较将字符与数字进行比较的时候,会把字符转换成数字再比较,当转换到字符时后面便都为空了 flag{…

蓝桥杯 经验技巧篇

1. 注意事项 👨‍🏫 官方通知 👨‍🏫 资料文档 时间:4月13日 9:00~13:00 (时长 4小时)物品 准考证(赛前一周开放下载,自行打印)学生证身份证笔、水、外套&a…

层次式架构设计-体系结构概述

层次式架构是软件体系结构设计中最为常用的一种架构形式,它为软件系统提供了一种在结构、行为和属性方面的高级抽象。其核心思想是将系统组成为一种层次结构,每一层为上层服务,并作为下层的客户。 层次式架构设计技术: 表现层中间…

LeetCode刷题之31.下一个排列

文章目录 1. 题目2.分析3.解答3.1 先排序,后交换3.2 先交换,后排序 1. 题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3…

C——找单身狗2

题目内容: 在一个数组中,室友两个数字出现了一次,其他所有数字都出现了两次。找出只出现一次的数字。 如:1,2,3,4,5,1,2,3,4&#xff…

交互设计师、UI设计师、视觉设计师面试作品集包装模板figma源文件

页面数量:19页 页面尺寸:1920*1080PX 交付格式:figma 赠送文件:24款高质量样机 交付文件:作品集模板源文件、作品集包装psd源文件、作品集所用字体文件 该作品集虽然只有19页,但可根据需求复制作品集里已有…

SpringBoot3整合RabbitMQ之三_工作队列模型案例

SpringBoot3整合RabbitMQ之三_工作队列模型案例 文章目录 SpringBoot3整合RabbitMQ之三_工作队列模型案例2. 工作队列模型1. 消息发布者1. 创建工作队列的配置类2. 发布消费Controller 2. 消息消费者One3. 消息消费者Two4. 消息消费者Three5. 输出结果 2. 工作队列模型 1. 消息…

金融企业区域集中库的设计构想和测试验证

导读 本文探讨了金融企业区域集中库的设计构想和测试验证,包括架构设想、数据库整合场景测试及优势和使用设想。作者提出利用 TiDB 数据库产品集中建设区域集中库,解决 MySQL 存量节点的整合问题,实现部署的标准化、按需扩展和统一运维管理。…

【绩效管理】帮助零售企业建立分层分类绩效考核体系项目纪实

购物中心张经理评价:“员工的绩效管理一直是困扰我公司的难题,我们只懂得怎么经营,至于怎么做人力资源管理,真是一点都不懂。这次华恒智信为我们提供的服务对我们的帮助很大。基于企业实际调研情况,华恒智信专家明确指…

蓝桥杯单片机第十四届省赛模拟考试一

一、基本要求 使用大赛组委会提供的国信长天单片机竞赛实训平台,完成本试题的程序设计与调试。程序编写、调试完成后,选手需通过考试系统提交以准考证号命名的hex文件。不符合以上文件提交要求的作品将被评为零分或者被酌情扣分。 硬件设置: …

SpringBoot3整合RabbitMQ之四_发布订阅模型中的fanout模型

SpringBoot3整合RabbitMQ之四_发布订阅模型中的fanout模型 文章目录 SpringBoot3整合RabbitMQ之四_发布订阅模型中的fanout模型3. 发布/订阅模型之fanout模型1. 说明1. 消息发布者1. 创建工作队列的配置类2. 发布消费Controller 2. 消息消费者One3. 消息消费者Two4. 消息消费者…

windows上使用influx2.7学习

参考 官方文档:https://docs.influxdata.com/influxdb/v2/ 下载 需要下载两样东西:influxd.exe和influx.exe influxd:influx数据库的服务端。下载地址:https://dl.influxdata.com/influxdb/releases/influxdb2-2.7.5-windows.zipinflux:连…

C# 实现子进程跟随主进程关闭

文章目录 前言一、如何实现?1、创建作业对象(1)、创建对象(2)、设置销毁作业时,关闭拥有的进程 2、子进程加入作业对象3、销毁作业对象(1)、手动销毁(2)、所在…

算法设计与分析实验报告c++实现(连续邮资问题、卫兵布置问题、圆排列问题、求解填字游戏问题、分支限界法求解旅行售货员(TSP)问题)

一、 实验目的 1.加深学生对算法设计方法的基本思想、基本步骤、基本方法的理解与掌握; 2.提高学生利用课堂所学知识解决实际问题的能力; 3.提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 1.连续邮资…

最好用的安卓按钮(3)

属性解释 按钮文字 app:text“床前明月光” 按钮文字颜色 app:textColor“color/color_white” 按钮文字大小 app:textSize“22sp” 按钮背景颜色 app:color_normal“color/color_accent” 0x2 单独设置每个圆角 效果 代码 <top.androidman.SuperButton android:layo…

软考 系统架构设计师系列知识点之数据库基本概念(4)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之数据库基本概念&#xff08;3&#xff09; 所属章节&#xff1a; 第6章. 数据库设计基础知识 第1节 数据库基本概念 6.1.3 数据库管理系统 DBMS&#xff08;DataBase Management System&#xff0c;数据库管理系统&am…