【数据集管理】使用 Fiftyone 管理数据集,大型数据集也不在话下!

链接: Fiftyone 官网

1. Fiftyone 安装

# 要求 python 版本 ≥3.7,≤3.10
# 直接使用 pip 指令安装即可

# TODO 网页版安装指令
pip install fiftyone
# TODO 桌面版安装指令
pip install fiftyone-desktop

2. 数据集的加载与导出

Fiftyone 工作流程是打开一个 Python Shell 并加载一个 Datasets,通过 Sessions 进行交互。

2.1 本地数据集操作

2.1.1 创建 session

import fiftyone as fo

# 使用桌面版 APP
# session = fo.launch_app(desktop=True)  
# session.wait()                         # 保持 APP 登录状态,直到手动退出

# 使用网页版
session = fo.launch_app(port=5151)		# 默认端口为 5151  

创建成功的 session 展示
在这里插入图片描述

2.1.2 加载数据集

2.1.2.1 加载 YOLO 格式的数据集

使用 fo.Dataset.from_dir() 加载本地文件夹中的数据集

import fiftyone as fo

name = 'my_test'
dataset_dir = r"D:\fiftyone\test"
dataset_type = fo.types.YOLOv5Dataset   # * 加载YOLO格式的数据集
# dataset_type=fo.types.FiftyOneDataset # * 加载FiftyOne格式的数据集

dataset = fo.Dataset.from_dir(
    dataset_dir = dataset_dir,
    dataset_type = dataset_type,
    name = name,
)

dataset.persistent = True             			# * 持久化保存数据集,防止关闭session后数据集删除  
session = fo.launch_app(dataset, port=5151) 	# * 默认端口为5151
2.1.2.2 加载本地数据库中的数据集

使用 fo.load_dataset(name) 加载本地数据库中数据集(通过 Fiftyone 保存在本地的数据集)

import fiftyone as fo

name = 'SmokeFire_test'
dataset = fo.load_dataset(name)
session.dataset = dataset
2.1.2.3 同时加载数据集 train 和 val

使用dataset = fo.Dataset(name)加载空数据集后使用dataset.add_dir()追加多个子数据集

import fiftyone as fo

name = 'Person_car_hard_ver002'
dataset_dir = r"/media/gll/fiftyone/XingRenHeCheLiangJianCe_detection_hard_samples_20240531_802_ver002"
dataset_type = fo.types.YOLOv5Dataset   # * 加载YOLO格式的数据集

splits = ["train", "val"]

dataset = fo.Dataset(name)
for split in splits:
    dataset.add_dir(
        dataset_dir = dataset_dir , 
        dataset_type = fo.types.YOLOv5Dataset, 
        split = split,
        tags = split
    )

dataset.persistent = True              # * 持久化保存数据集,防止关闭session后数据集删除  
session = fo.launch_app(dataset, remote=True)

数据集加载成功展示
在这里插入图片描述

2.1.3 数据集导出

2.1.3.1 YOLO 格式数据集导出

使用YOLO格式导出指定名称数据集到指定路径下

import fiftyone as fo
dataset = fo.load_dataset("my_test")

export_dir = r"D:\fiftyone\my_test_export_yolo"
export_format = fo.types.YOLOv5Dataset
dataset.export(export_dir=export_dir, dataset_type=export_format)

但上述导出方式不会保存如 Sample tags 等的元数据信息,若需全部保存,则需使用 Fiftyone 格式导出。

2.1.3.2 Fiftyone 格式数据集导出
import fiftyone as fo
dataset = fo.load_dataset("SmokeFire_val_test")

export_dir = r"D:\fiftyone\SmokeFire_val_test_export_fiftyone"
export_format = fo.types.FiftyOneDataset
dataset.export(export_dir=export_dir, dataset_type=export_format)

导出数据集格式如下:
在这里插入图片描述

2.1.4 查看及删除本地数据集

# 查看本地数据库数据集
print(fo.list_datasets())

# 删除指定名称数据集
fo.delete_dataset(dataset_name)

2.2 远程操作数据集

若要在远程服务器上使用 fiftyone 进行数据集管理,则需要远程连接数据集。在登录 session 界面时使用remote=True实现远程控制

import fiftyone as fo

name = 'Person_ver001'
dataset_dir = "/media/gll/fiftyone/ver001"
dataset_type = fo.types.YOLOv5Dataset   # * 加载YOLO格式的数据集

dataset = fo.Dataset.from_dir(
    dataset_dir = dataset_dir,
    dataset_type = dataset_type,
    name = name,
)

dataset.persistent = True              # * 持久化保存数据集,防止关闭session后数据集删除  
session = fo.launch_app(dataset, remote=True)

上述代码执行后,数据集成功加载结果展示如下:
在这里插入图片描述
但此时还不能通过 session 直接访问数据集,还需要在本地终端中运行指令ssh -N -L 5151:127.0.0.1:5151 username@hostname,使用 ssh 实现远程连接
在这里插入图片描述
连接成功后在浏览器打开默认端口localhost:5151,即可以看到已经成功加载的远程数据集。

3. 对数据进行打标签操作

3.1 图像打标签(单个/批量)

3.1.1 session 中单个打标签

  • 选中图像后批量添加标签,在 Samples 下新建或选择已有 tags 并应用即可为选定图像打上标签。
    在这里插入图片描述

3.1.2 使用脚本给已知路径的数据批量打标签

下述示例代码假设图像名称存储在指定 txt 文件中

import fiftyone as fo
import os

# 1. 读取txt文件,获取图像名称列表
def read_image_names_from_txt(txt_file_path):
    with open(txt_file_path, 'r') as file:
        image_names = [line.strip() for line in file.readlines()]
    return image_names

# 2. 加载Fiftyone格式的本地数据库
def load_fiftyone_dataset(dataset_name):
    return fo.load_dataset(dataset_name)

# 3. 匹配图像名称并添加tags
def match_and_tag_images(txt_file_path, dataset_name, tags):
    image_names = read_image_names_from_txt(txt_file_path)
    dataset = load_fiftyone_dataset(dataset_name)
    
    matched_samples = []
    
    for sample in dataset:
        if sample.filepath.split(os.sep)[-1] in image_names:
            sample.tags.extend(tags)
            sample.save()
            matched_samples.append(sample.filepath.split(os.sep)[-1] )
    
    return matched_samples

txt_file_path = r"E:\project\0_Tools\fiftyone\SmokeFire_val.txt"
dataset_name = "fiftyone_test"
tags_to_add = ["test_tags"]

matched_and_tagged_images = match_and_tag_images(txt_file_path, dataset_name, tags_to_add)
# print(f"Matched and tagged images: {[sample for sample in matched_and_tagged_images]}")
print(f"Number of matched and tagged images: {len(matched_and_tagged_images)}")
  • 未打标签前展示 在这里插入图片描述
  • 打标签后展示
    在这里插入图片描述

3.2 图像删除标签(单个/多个)

import fiftyone as fo

# 1. 加载本地数据库
def load_dataset(dataset_name):
    return fo.load_dataset(dataset_name)

# 2. 筛选图像并移除tags
def remove_tags(dataset_name, tags_to_del):
    dataset = load_dataset(dataset_name)
    view = dataset.match_tags(tags_to_del)
    print(f"Number of samples: {len(view)}")
    for sample in view:
        # print(sample.filepath, sample.tags)
        for tag in tags_to_del:
            if tag in sample.tags:
                sample.tags.remove(tag)
                sample.save()
                
    # 打印筛选结果以验证
    view_after = dataset.match_tags(tags_to_del)
    print(f"Filtered samples: {len(view_after)}")
    for sample in view_after:
        print(sample.filepath, sample.tags)
        
dataset_name = "fiftyone_test"        
tags_to_del = ["test_tags", "test_tags1"]
remove_tags(dataset_name, tags_to_del)

3.3 匹配标签数据筛选

在界面中选择多个 tags标签查看时,筛选结果为所选 tags 的并集,故需使用下述代码筛选符合 tags 匹配的交集数据。

# 加载数据库
dataset = fo.load_dataset("SmokeFire_val_test")

# 筛选tag为"场景-开源P图", "季节-春天", "时间-下午"的图像
view = dataset.match_tags(["场景-开源P图", "季节-春天", "时间-下午"], all=True) # all 为选择匹配图像的交集

# 或者获取满足条件的图像的样本
matching_samples = list(view)
matching_samples_paths = [s.filepath for s in matching_samples]

with open("matching_samples_paths.txt", "w") as f:
    for path in matching_samples_paths:
        f.write(path + "\n")
        
print('nums --> ', len(matching_samples_paths))
  • 筛选示例如下
    在这里插入图片描述
    在这里插入图片描述

4. 踩坑记录

4.1 浏览器页面白屏-已解决

  • 问题分析:通过查看浏览器 ‘检查’ 项,发现 MIME 类型不匹配
    在这里插入图片描述
  • 解决方案:https://github.com/voxel51/fiftyone/issues/2010
    在这里插入图片描述
    按上述方法修改后重启,并未解决
  • 修改计算机\HKEY_CLASSES_ROOT.jsContent Typetext/javascript
    在这里插入图片描述
  • HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.js 中添加Content Typetext/javascript
    在这里插入图片描述
    修改后可以在浏览器中正常显示加载 session
    在这里插入图片描述
  • 29
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32是一种微控制器,可以用来控制各种电子设备。使用AT指令可以连接MQTT服务器。 MQTT是一种在物联网应用中非常流行的消息协议。MQTT服务器允许设备通过云端连接、通信和控制。 使用AT指令连接MQTT服务器需要一些步骤。首先需要确定所使用的设备是否支持AT指令,然后需要配置网络连接参数,并且为设备提供连接服务器的认证信息。 连接MQTT服务器需要使用TCP/IP协议。要连接MQTT服务器,需要使用服务器的IP地址和端口号。在发送MQTT消息之前,需要先进行身份验证。这可以通过使用用户名和密码来实现。 一旦设备成功连接到MQTT服务器,就可以使用MQTT协议发送和接收消息。这样就可以建立一个功能强大的物联网系统,通过这个系统,可以控制各种设备,同时监测设备的状态和数据。 总之,STM32使用AT指令连接MQTT服务器需要一些技术,需要一定的经验和知识。但是,如果你能掌握这些技能,就可以在物联网应用的开发和部署中发挥重要的作用。 ### 回答2: STM32是一款功能强大的微控制器,在当前互联网大数据的时代,其可用于连接到MQTT服务器。MQTT(Message Queuing Telemetry Transport)是一种基于发布/订阅(pub/sub)模式的通信协议,被广泛应用于物联网领域。 在使用STM32连接MQTT服务器前,需要先学习AT指令并了解其使用方法。AT指令(AT Commands)是用来控制和配置通信模块的一种指令格式,若能正确使用AT指令,STM32与MQTT服务器的连接就不在话下。 以下为连接MQTT服务器的步骤: 1. 进行网络连接,如Wi-Fi或以太网,确保STM32与网络相连。 2. 在STM32中使用AT指令建立与MQTT服务器的连接,包括连接到服务器、建立通信频道、登录服务器等操作。 3. 使用AT指令订阅MQTT主题,接收或发布消息。如此一来STM32就可以与MQTT服务器直接通讯。 注意: 1. 必须确保网络连接正常,否则MQTT服务器无法连接。 2. 可以通过在程序结构中添加异常处理来诊断连接问题。在连接的过程中,如果程序出现问题,可以在程序编写过程中添加日志记录来快速解决问题。 总而言之,STM32使用AT指令连接MQTT服务器需要提前学习AT指令,并能够正确使用。在连接MQTT服务器的过程中,要确保网络连接、日志记录以及异常处理的准确性,以确保稳定的通信。 ### 回答3: STM32是一种嵌入式系统芯片,通过使用AT指令可以连接MQTT服务器。MQTT是一种轻量级的消息传输协议,可以在低带宽和低计算能力环境下使用。 要使用STM32连接MQTT服务器,需要对设备进行初始化和配置,比如设置网络类型、配置IP地址和端口号、设置用户名和密码等,然后使用AT指令进行连接和通信。下面是一些常用的AT指令: 1. AT+CIPSTART:建立连接,并指定协议类型、服务器IP和端口号。 2. AT+CIPSEND:发送消息,指定消息长度和内容。 3. AT+CIPCLOSE:关闭连接。 4. AT+MQTTUSERDATA:设置用户名和密码。 5. AT+MQTTKEEPALIVE:设置保持连接时间。 使用这些AT指令,我们可以在STM32上实现连接MQTT服务器,并实现双向数据传输。同时,需要注意的是,使用AT指令连接MQTT服务器时,需要考虑网络稳定性和连接安全性,确保数据的准确性和隐私安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值