修改Egohands公开数据集,用于YOLOv5训练通用手部检测模型

〇、背景:

项目需要,需要利用摄像头对人手进行实时监测,最先考虑到的就是简单易用且高效的YOLOv5,很快找到了公开数据集:Egohands

EgoHands: A Dataset for Hands in Complex Egocentric Interactions | IU Computer Vision Lab

一、Egohands介绍:

EgoHands 数据集包含 48 个 Google Glass 视频,内容涉及两个人之间复杂的第一人称交互。该数据集的主要目的是提供更好的数据驱动方法来理解第一人称计算机视觉中的手。

我下载使用的是[Labeled Data]这个数据集,该存档包含所有带标签的帧,格式为 JPEG 文件 (720x1280px)。 48 个视频中的每个视频都有 100 个标记帧,总共 4,800 个帧。真实标签由每种手型的像素级掩码组成,并以 Matlab 文件形式提供。

由于数据集是用于MATLAB的,所以需要将其转化为YOLOv5可用。

二、数据集转化:

下面的程序主要用于参考,具体使用时需要根据自己情况进行修改。

1,使用程序自动下载、解压并归档数据集

import scipy.io as sio
import numpy as np
import os
import gc
import six.moves.urllib as urllib
import cv2
import time
import xml.etree.cElementTree as ET
import random
import shutil as sh
from shutil import copyfile
import zipfile

import csv


def save_csv(csv_path, csv_content):
    with open(csv_path, 'w') as csvfile:
        wr = csv.writer(csvfile)
        for i in range(len(csv_content)):
            wr.writerow(csv_content[i])


def get_bbox_visualize(base_path, dir):
    image_path_array = []
    for root, dirs, filenames in os.walk(base_path + dir):
        for f in filenames:
            if(f.split(".")[1] == "jpg"):
                img_path = base_path + dir + "/" + f
                image_path_array.append(img_path)

    #sort image_path_array to ensure its in the low to high order expected in polygon.mat
    image_path_array.sort()
    boxes = sio.loadmat(
        base_path + dir + "/polygons.mat")
    # there are 100 of these per folder in the egohands dataset
    polygons = boxes["polygons"][0]
    # first = polygons[0]
    # print(len(first))
    pointindex = 0

    for first in polygons:
        index = 0

        font = cv2.FONT_HERSHEY_SIMPLEX

        img_id = image_path_array[pointindex]
        img = cv2.imread(img_id)

        img_params = {}
        img_params["width"] = np.size(img, 1)
        img_params["height"] = np.size(img, 0)
        head, tail = os.path.split(img_id)
        img_params["filename"] = tail
        img_params["path"] = os.path.abspath(img_id)
        img_params["type"] = "train"
        pointindex += 1

        boxarray = []
        csvholder = []
        for pointlist in first:
            pst = np.empty((0, 2), int)
            max_x = max_y = min_x = min_y = height = width = 0

            findex = 0
            for point in pointlist:
                if(len(point) == 2):
                    x = int(point[0])
                    y = int(point[1])

                    if(findex == 0):
                        min_x = x
                        min_y = y
                    findex += 1
                    max_x = x if (x > max_x) else max_x
                    min_x = x if (x < min_x) else min_x
                    max_y = y if (y > max_y) else max_y
                    min_y = y if (y < min_y) else min_y
                    # print(index, "====", len(point))
                    appeno = np.array([[x, y]])
                    pst = np.append(pst, appeno, axis=0)
                    cv2.putText(img, ".", (x, y), font, 0.7,
                                (255, 255, 255), 2, cv2.LINE_AA)

            hold = {}
            hold['minx'] = min_x
            hold['miny'] = min_y
            hold['maxx'] = max_x
            hold['maxy'] = max_y
            if (min_x > 0 and min_y > 0 and max_x > 0 and max_y > 0):
                boxarray.append(hold)
                labelrow = [tail,
                            np.size(img, 1), np.size(img, 0), "hand", min_x, min_y, max_x, max_y]
                csvholder.append(labelrow)

            cv2.polylines(img, [pst], True, (0, 255, 255), 1)
            cv2.rectangle(img, (min_x, max_y),
                          (max_x, min_y), (0, 255, 0), 1)

        csv_path = img_id.split(".")[0]
        if not os.path.exists(csv_path + ".csv"):
            cv2.putText(img, "DIR : " + dir + " - " + tail, (20, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.75, (77, 255, 9), 2)
            cv2.imshow('Verifying annotation ', img)
            save_csv(csv_path + ".csv", csvholder)
            print("===== saving csv file for ", tail)
        cv2.waitKey(2)  # close window when a key press is detected


def create_directory(dir_path):
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)

# combine all individual csv files for each image into a single csv file per folder.


def generate_label_files(image_dir):
    header = ['filename', 'width', 'height',
              'class', 'xmin', 'ymin', 'xmax', 'ymax']
    for root, dirs, filenames in os.walk(image_dir):
        for dir in dirs:
            csvholder = []
            csvholder.append(header)
            loop_index = 0
            for f in os.listdir(image_dir + dir):
                if(f.split(".")[1] == "csv"):
                    loop_index += 1
                    #print(loop_index, f)
                    csv_file = open(image_dir + dir + "/" + f, 'r')
                    reader = csv.reader(csv_file)
                    for row in reader:
                        csvholder.append(row)
                    csv_file.close()
                    os.remove(image_dir + dir + "/" + f)
            save_csv(image_dir + dir + "/" + dir + "_labels.csv", csvholder)
            print("Saved label csv for ", dir, image_dir +
                  dir + "/" + dir + "_labels.csv")


# Split data, copy to train/test folders
def split_data_test_eval_train(image_dir):
    create_directory("images")
    create_directory("images/train")
    create_directory("images/test")

    data_size = 4000
    loop_index = 0
    data_sampsize = int(0.1 * data_size)
    test_samp_array = random.sample(range(data_size), k=data_sampsize)

    for root, dirs, filenames in os.walk(image_dir):
        for dir in dirs:
            for f in os.listdir(image_dir + dir):
                if(f.split(".")[1] == "jpg"):
                    loop_index += 1
                    print(loop_index, f)

                    if loop_index in test_samp_array:
                        os.rename(image_dir + dir +
                                  "/" + f, "images/test/" + f)
                        os.rename(image_dir + dir +
                                  "/" + f.split(".")[0] + ".csv", "images/test/" + f.split(".")[0] + ".csv")
                    else:
                        os.rename(image_dir + dir +
                                  "/" + f, "images/train/" + f)
                        os.rename(image_dir + dir +
                                  "/" + f.split(".")[0] + ".csv", "images/train/" + f.split(".")[0] + ".csv")
                    print(loop_index, image_dir + f)
            print(">   done scanning director ", dir)
            os.remove(image_dir + dir + "/polygons.mat")
            os.rmdir(image_dir + dir)

        print("Train/test content generation complete!")
        generate_label_files("images/")


def generate_csv_files(image_dir):
    for root, dirs, filenames in os.walk(image_dir):
        for dir in dirs:
            get_bbox_visualize(image_dir, dir)

    print("CSV generation complete!\nGenerating train/test/eval folders")
    split_data_test_eval_train("egohands/_LABELLED_SAMPLES/")


# rename image files so we can have them all in a train/test/eval folder.
def rename_files(image_dir):
    print("Renaming files")
    loop_index = 0
    for root, dirs, filenames in os.walk(image_dir):
        for dir in dirs:
            for f in os.listdir(image_dir + dir):
                if (dir not in f):
                    if(f.split(".")[1] == "jpg"):
                        loop_index += 1
                        os.rename(image_dir + dir +
                                  "/" + f, image_dir + dir +
                                  "/" + dir + "_" + f)
                else:
                    break

    generate_csv_files("egohands/_LABELLED_SAMPLES/")

def extract_folder(dataset_path):
    print("Egohands dataset already downloaded.\nGenerating CSV files")
    if not os.path.exists("egohands"):
        zip_ref = zipfile.ZipFile(dataset_path, 'r')
        print("> Extracting Dataset files")
        zip_ref.extractall("egohands")
        print("> Extraction complete")
        zip_ref.close()
        rename_files("egohands/_LABELLED_SAMPLES/")

def download_egohands_dataset(dataset_url, dataset_path):
    is_downloaded = os.path.exists(dataset_path)
    if not is_downloaded:
        print(
            "> downloading egohands dataset. This may take a while (1.3GB, say 3-5mins). Coffee break?")
        opener = urllib.request.URLopener()
        opener.retrieve(dataset_url, dataset_path)
        print("> download complete")
        extract_folder(dataset_path);

    else:
        extract_folder(dataset_path)


EGOHANDS_DATASET_URL = "http://vision.soic.indiana.edu/egohands_files/egohands_data.zip"
EGO_HANDS_FILE = "egohands_data.zip"


download_egohands_dataset(EGOHANDS_DATASET_URL, EGO_HANDS_FILE)

在data_deal文件夹中,train_labels.csv与test_labels.csv是解压后的标注文件,下面需要针对csv文件进行转化

2,csv文件转为txt文件

#-*- coding:utf-8
import pandas as pd
import  os
 
path_dir = './'
# csvPath = path_dir + 'train_labels.csv'
csvPath = path_dir + 'test_labels.csv'
if not os.path.exists(csvPath):
    print('Not that files:%s'%csvPath)
 
# txtPath = path_dir+'train_labels.txt'
txtPath = path_dir+'test_labels.txt'
data = pd.read_csv(csvPath, encoding='utf-8')
 
with open(txtPath,'a+', encoding='utf-8') as f:
    for line in data.values:
        f.write((str(line[0])+'\t'+str(line[1])+','+str(line[2])+'\t'+str(line[4])+','+str(line[5])+','+str(line[6])+','+str(line[7])+'\t'+str(line[3])+'\n'))

转换完成后形成两个txt文件,下一步需要将txt文件进行拆分

3,拆分txt文件

import os

txt_path='./train_txt/'
with open('./train_labels.txt') as f:
	lines=f.readlines()
	for line in lines:
		line=line.strip()
		words=line.split('\t')
		file_name=words[0]
		img_size=words[1]
		coordinate=words[2]
		label=words[3]
		with open(txt_path+file_name[:-3]+'txt','a') as f1:
			f1.write(coordinate+','+label+'\n')

拆分完成后,在两个文件夹中会生成对应的txt标签文件,但目前的格式还不是YOLOv5需要的格式,还需要进行进一步转换

4,转换txt文件

import os

input_folder = "./labels/train/"  # 替换为包含 txt 文件的文件夹路径
output_folder = "./labels_yolo/train/"  # 替换为输出转换后标签的文件夹路径

image_width = 1280
image_height = 720

if not os.path.exists(output_folder):
    os.makedirs(output_folder)

for filename in os.listdir(input_folder):
    if filename.endswith(".txt"):
        with open(os.path.join(input_folder, filename), "r") as input_file:
            lines = input_file.readlines()

        output_lines = []
        for line in lines:
            xmin, ymin, xmax, ymax, class_name = line.strip().split(",")
            center_x = (int(xmin) + int(xmax)) / (2.0 * image_width)
            center_y = (int(ymin) + int(ymax)) / (2.0 * image_height)
            width = (int(xmax) - int(xmin)) / image_width
            height = (int(ymax) - int(ymin)) / image_height
            
            yolo_line = f"0 {center_x:.6f} {center_y:.6f} {width:.6f} {height:.6f}"
            output_lines.append(yolo_line)

        output_filename = os.path.join(output_folder, filename)
        with open(output_filename, "w") as output_file:
            output_file.write("\n".join(output_lines))

至此,转换步骤结束,我们已经得到了完整的4800个图像和对应的txt标签,然后用于训练即可

三、YOLOv5训练

放着服务器不用,我拿闲置的2060跑了半宿,得到结果如下

 

 

 

 

 

四、直接下载修改好的数据集、标签和训练好的模型文件

我本来,想上传到CSDN资源里的,但我的压缩包1.3GB,CSDN最大只能上传1GB的文件,那这波积分是骗不到了,下面是123盘和百度网盘的链接,需要的朋友自取吧:

123云盘:https://www.123pan.com/s/wTqA-j00ph.html
提取码:oBH3
百度网盘: https://pan.baidu.com/s/1wT8K4xTutfqE3WXLanAxiA?pwd=nmdj 
提取码: nmdj

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习模型的可解释性:增加对人工智能系统的信任和理解

为了以道德和值得信赖的方式使用人工智能&#xff0c;研究人员必须继续创建平衡模型复杂性和易于解释的方法。 机器学习模型在各个领域的使用都取得了重大进展&#xff0c;包括自然语言处理、生成式人工智能和自主系统等。另一方面&#xff0c;随着模型复杂性和规模的增加&…

元年方舟企业数字化PaaS平台入选《全国企业数字化转型十佳案例》|元年科技

7月4日&#xff0c;2023全球数字经济大会第二届全国企业数字化转型高峰论坛在京隆重举行。大会由全球数字经济大会组委会主办&#xff0c;中关村数字经济产业联盟承办&#xff0c;北京市科学技术协会鼎力支持。论坛期间元年科技凭借卓越案例《构建数字化转型引擎&#xff1a;元…

苏州OV泛域名RSA加密算法https

RSA加密算法是一种非对称加密算法&#xff0c;它被广泛应用于信息安全领域。与对称加密算法不同&#xff0c;RSA加密算法使用了两个密钥&#xff0c;一个公钥和一个私钥。公钥可以公开&#xff0c;任何人都可以使用它加密信息&#xff0c;但只有私钥的持有者才能解密信息。RSA加…

竞赛项目 深度学习的水果识别 opencv python

文章目录 0 前言2 开发简介3 识别原理3.1 传统图像识别原理3.2 深度学习水果识别 4 数据集5 部分关键代码5.1 处理训练集的数据结构5.2 模型网络结构5.3 训练模型 6 识别效果7 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习…

Mac unsupported architecture

&#xff08;瓜是长大在营养肥料里的最甜&#xff0c;天才是长在恶性土壤中的最好。——培根&#xff09; unsupported architecture 在mac的m系列芯片中容易出现此类问题&#xff0c;因为m系列是arm64的芯片架构&#xff0c;而有些nodejs版本或npm包的芯片架构是x86的&#x…

代码随想录算法训练营第十四天|对树的初步认识

二叉树种类 在我们解题过程中二叉树有两种主要的形式&#xff1a;满二叉树和完全二叉树。 满二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 这棵二叉树为满二叉树&…

相关C语言易错点

四区 我们想来介绍一下内存四区 栈区 局部变量&#xff0c;局部常量 空间自动开辟和释放&#xff0c;只能作用于局部&#xff0c;函数不能返回局部变量的空间地址 堆区 malloc,realloc,free 手动开辟&#xff0c;手动释放&#xff0c;如果不手动释放&#xff0c;那么会在程…

python3.6 安装pillow失败

问题描述 python3 安装 pillow 失败 错误原因 python3.6 不支持 pillow9.0 以上的版本 解决方法&#xff1a; 指定版本安装 e.g., pillow8.0 pip3 install pillow8.0

【HarmonyOS】Java如何引用外部jar包

【关键字】 Java、引用jar包​ 【写在前面】 使用API6和API7开发HarmonyOS应用时&#xff0c;因为应用中只能引用SDK中开放的功能接口&#xff0c;但是部分jdk自带的接口功能在SDK中并未封装&#xff0c;要想在工程中使用jdk开放的接口功能&#xff0c;需要将jdk中的jar包通过…

一文讲述什么是数字孪生?

当前世界正处于百年未有之大变局&#xff0c;数字经济在各国已成为经济发展的重点。数字经济也是我国社会经济发展的必经之路。 近些年&#xff0c;大数据、人工智能、数字孪生等技术的发展促使技术与国内各产业进一步融合&#xff0c;从而推动了各产业在智能化、数字化等方面…

UEFI+win7+多系统安装

物理主机先安装的Windows10&#xff0c;同时需要安装Windows7的双系统 1.在https://next.itellyou.cn/下载Windows 7 ISO 2.使用Rufus制作U盘安装盘 注意一定要选择FAT32格式&#xff0c;否则安装过程会卡住 3.由于官方纯净的安装镜像默认不支持UEFI安装&#xff0c;有两种解决…

React - useEffect函数的理解和使用

文章目录 一&#xff0c;useEffect描述二&#xff0c;它的执行时机三&#xff0c;useEffect分情况使用1&#xff0c;不写第二个参数 说明监测所有state&#xff0c;其中一个变化就会触发此函数2&#xff0c;第二个参数如果是[]空数组&#xff0c;说明谁也不监测3&#xff0c;第…

RHCE使用RHEL系统角色题报错

题目&#xff1a; 使用 RHEL 系统角色 4. 安装 RHEL 系统角色软件包&#xff0c;并创建符合以下条件的 playbook/home/curtis/ansible/selinux.yml &#xff1a; 在所有受管节点上运行 使用 selinux 角色 配置该角色&#xff0c;以强制状态使用 selinux 报错一&#xff1a; [c…

tomcat优化

目录 tomcat tomcat优点 tomcat核心组件 Web容器 其他 功能组件 connector container tomcat处理请求过程 目录文件内容 内存池 堆区 JVM优化 ajp-nio-8009 启动速度优化 配置文件优化 tomcat tomcat是基于Java代码开发的开放源代码的web应用服务器 tomcat就…

Python Selenium 设置带账号密码的socks5代理,启动浏览器

selenium添加带有账密的socks5代理 我们都知道在使用selenium开发爬虫的时候不可避免的会使用socks5高匿名代理。一般情况下我们使用方法如下(开发语言为python)&#xff1a; from selenium import webdriver chrome_options webdriver.ChromeOptions() chrome_options.add_…

英特尔处理器被曝出“Downfall”漏洞:可窃取加密密钥

今日&#xff0c;谷歌的一位高级研究科学家利用一个漏洞设计了一种新的CPU攻击方法&#xff0c;该漏洞可影响多个英特尔微处理器系列&#xff0c;并允许窃取密码、加密密钥以及共享同一台计算机的用户的电子邮件、消息或银行信息等私人数据。 该漏洞被追踪为CVE-2022-40982&am…

解决 idea maven依赖引入失效,无法正常导入依赖问题

解决 idea maven依赖引入失效&#xff0c;无法正常导入依赖问题_idea无法导入本地maven依赖_普通网友的博客-CSDN博客 解决 idea maven依赖引入失效&#xff0c;无法正常导入依赖问题 idea是真的好用&#xff0c;不过里面的maven依赖问题有时候还真挺让人头疼&#xff0c;不少小…

【计算机视觉】关于图像处理的一些基本操作

目录 图像平滑滤波处理均值滤波计算过程python实现 高斯滤波计算过程python实现 中值滤波计算过程python实现 图像的边缘检测Robert算子计算过程python实现 图像处理腐蚀算子计算过程python实现 Hog&#xff08;梯度方向直方图&#xff09;特征计算流程&#xff1a;Hog的特征维…

brew+nginx配置静态文件服务器

背景 一下子闲下来了&#xff0c;了解的我的人都知道我闲不下来。于是&#xff0c;我在思考COS之后&#xff0c;决定自己整一个本地的OSS&#xff0c;实现静态文件的访问。那么&#xff0c;首屈一指的就是我很熟的nginx。也算是个小复习吧&#xff0c;复习一下nginx代理静态文…

【Java并发】如何进行死锁诊断?

文章目录 1.什么是死锁2.死锁怎么产生的3.如何进行死锁诊断&#xff1f;3.1 通过命令查看3.2 jconsole可视化工具3.2 VisualVM&#xff1a;故障处理工具 1.什么是死锁 死锁&#xff08;Deadlock&#xff09;是指两个或多个进程&#xff08;线程&#xff09;在执行过程中&#…