YOLO数据处理工具函数合集

changeTheLabel.py

# 改标签文件对应数字
#
import os

folder_path = r'C:\Users\User\Desktop\coco\transfer\cell_phone\label'

# 遍历文件夹中的每个txt文件
for filename in os.listdir(folder_path):
    if filename.endswith('.txt'):
        file_path = os.path.join(folder_path, filename)

        # 读取txt文件内容
        with open(file_path, 'r') as file:
            lines = file.readlines()

        # 修改每一行的第一个数字为2
        modified_lines = []
        for line in lines:
            split_line = line.strip().split(' ')
            split_line[0] = '1'
            modified_line = ' '.join(split_line) + '\n'
            modified_lines.append(modified_line)

        # 将修改后的内容写入文件
        with open(file_path, 'w') as file:
            file.writelines(modified_lines)

print("修改完成!")

coco_extract.py

# 提取对应类别数据集
#
from pycocotools.coco import COCO
import os
import shutil
from tqdm import tqdm
import skimage.io as io
import matplotlib.pyplot as plt
import cv2
from PIL import Image, ImageDraw
# 参考链接
# https://blog.csdn.net/Accelerating/article/details/126855883
# https://blog.csdn.net/Dongjiuqing/article/details/127949190
pathset = 'wine glass'

'''
交通 'person', 'bicycle', 'car', 'motorcycle', 'bus', 'train',   'truck'
      '人', '   自行车',  '汽车', '摩托车',    '公共汽车', '火车', '卡车'
      257249     7056     43532    8654        6061     4570     9970
物品  'bottle', 'wine glass', 'cup', 'bowl',   'fork', 'knife', 'spoon', 
      '瓶子',   '酒杯',       '杯子', '碗',    '叉子',  '刀',    '勺子',  
       24070    7839          20574   14323
手机  'cell phone'
'''

# 需要设置的路径
savepath = r"C:/Users/User/Desktop/coco/transfer/"+pathset+'/'
# print(savepath)
img_dir = savepath + 'images/'
anno_dir = savepath + 'annotations/'
datasets_list = ['train2017', 'val2017']
# datasets_list = ['val2017']

# coco有80类,这里写要提取类的名字,以person为例
classes_names = [pathset]
# 包含所有类别的原coco数据集路径
'''
目录格式如下:
$COCO_PATH
----|annotations
----|train2017
----|val2017
----|test2017
'''
dataDir = 'C:/Users/User/Desktop/coco/'

headstr = """\
<annotation>
    <folder>VOC</folder>
    <filename>%s</filename>
    <source>
        <database>My Database</database>
        <annotation>COCO</annotation>
        <image>flickr</image>
        <flickrid>NULL</flickrid>
    </source>
    <owner>
        <flickrid>NULL</flickrid>
        <name>company</name>
    </owner>
    <size>
        <width>%d</width>
        <height>%d</height>
        <depth>%d</depth>
    </size>
    <segmented>0</segmented>
"""
objstr = """\
    <object>
        <name>%s</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>%d</xmin>
            <ymin>%d</ymin>
            <xmax>%d</xmax>
            <ymax>%d</ymax>
        </bndbox>
    </object>
"""

tailstr = '''\
</annotation>
'''


# 检查目录是否存在,如果存在,先删除再创建,否则,直接创建
def mkr(path):
    if not os.path.exists(path):
        os.makedirs(path)  # 可以创建多级目录


def id2name(coco):
    classes = dict()
    for cls in coco.dataset['categories']:
        classes[cls['id']] = cls['name']
    return classes


def write_xml(anno_path, head, objs, tail):
    f = open(anno_path, "w")
    f.write(head)
    for obj in objs:
        f.write(objstr % (obj[0], obj[1], obj[2], obj[3], obj[4]))
    f.write(tail)


def save_annotations_and_imgs(coco, dataset, filename, objs):
    # 将图片转为xml,例:COCO_train2017_000000196610.jpg-->COCO_train2017_000000196610.xml
    dst_anno_dir = os.path.join(anno_dir, dataset)
    mkr(dst_anno_dir)
    anno_path = dst_anno_dir + '/' + filename[:-3] + 'xml'
    img_path = dataDir + dataset + '/' + filename
    # print("img_path: ", img_path)
    dst_img_dir = os.path.join(img_dir, dataset)
    mkr(dst_img_dir)
    dst_imgpath = dst_img_dir + '/' + filename
    # print("dst_imgpath: ", dst_imgpath)
    img = cv2.imread(img_path)
    # if (img.shape[2] == 1):
    #    print(filename + " not a RGB image")
    #   return
    shutil.copy(img_path, dst_imgpath)

    head = headstr % (filename, img.shape[1], img.shape[0], img.shape[2])
    tail = tailstr
    write_xml(anno_path, head, objs, tail)


def showimg(coco, dataset, img, classes, cls_id, show=True):
    global dataDir
    I = Image.open('%s/%s/%s' % (dataDir, dataset, img['file_name']))
    # 通过id,得到注释的信息
    annIds = coco.getAnnIds(imgIds=img['id'], catIds=cls_id, iscrowd=None)
    # print(annIds)
    anns = coco.loadAnns(annIds)
    # print(anns)
    # coco.showAnns(anns)
    objs = []
    for ann in anns:
        class_name = classes[ann['category_id']]
        if class_name in classes_names:
            # print(class_name)
            if 'bbox' in ann:
                bbox = ann['bbox']
                xmin = int(bbox[0])
                ymin = int(bbox[1])
                xmax = int(bbox[2] + bbox[0])
                ymax = int(bbox[3] + bbox[1])
                obj = [class_name, xmin, ymin, xmax, ymax]
                objs.append(obj)
                draw = ImageDraw.Draw(I)
                draw.rectangle([xmin, ymin, xmax, ymax])
    if show:
        plt.figure()
        plt.axis('off')
        plt.imshow(I)
        plt.show()

    return objs


for dataset in datasets_list:
    # ./COCO/annotations/instances_train2017.json
    annFile = '{}/annotations/instances_{}.json'.format(dataDir, dataset)

    # 使用COCO API用来初始化注释数据
    coco = COCO(annFile)

    # 获取COCO数据集中的所有类别
    classes = id2name(coco)
    # print(classes)
    # [1, 2, 3, 4, 6, 8]
    classes_ids = coco.getCatIds(catNms=classes_names)
    # print(classes_ids)
    for cls in classes_names:
        # 获取该类的id
        cls_id = coco.getCatIds(catNms=[cls])
        img_ids = coco.getImgIds(catIds=cls_id)
        # print(cls, len(img_ids))
        # imgIds=img_ids[0:10]
        for imgId in tqdm(img_ids):
            img = coco.loadImgs(imgId)[0]
            filename = img['file_name']
            # print(filename)
            objs = showimg(coco, dataset, img, classes, classes_ids, show=False)
            # print(objs)
            save_annotations_and_imgs(coco, dataset, filename, objs)

count.py

# 文件夹文件计数
#
import os

def count_files_in_folder(folder_path):
    try:
        # 获取文件夹中的所有文件和子文件夹
        items = os.listdir(folder_path)

        # 初始化计数器
        file_count = 0

        # 遍历文件夹中的所有项目
        for item in items:
            item_path = os.path.join(folder_path, item)

            # 判断是否为文件
            if os.path.isfile(item_path):
                file_count += 1
            # 如果是子文件夹,则递归调用count_files_in_folder
            elif os.path.isdir(item_path):
                file_count += count_files_in_folder(item_path)

        return file_count

    except Exception as e:
        print(f"Error counting files: {e}")
        return None

# 测试示例
folder_path = "/home/ws/CoodWorkRun/Database/smoDB_phoDB_glaDB_faceDB/JPEGImages"
result = count_files_in_folder(folder_path)

if result is not None:
    print(f"Number of files in {folder_path}: {result}")

delete.py

# 检测两个文件夹文件是否匹配 不匹配删除
# delete
import os

image_folder = r'C:\Users\User\Desktop\coco\transfer\bottle\JPEGImages'
label_folder = r'C:\Users\User\Desktop\coco\transfer\bottle\annotations'

# 获取图片文件夹和标签文件夹内的所有文件名
# 获取图片文件夹和标签文件夹内的所有文件名(去掉后缀)
image_files = set(os.path.splitext(filename)[0] for filename in os.listdir(image_folder))
label_files = set(os.path.splitext(filename)[0] for filename in os.listdir(label_folder))

print(image_files)
print(len(image_files))
print(label_files)
print(len(label_files))

# 找出需要删除的文件
files_to_delete = image_files.symmetric_difference(label_files)
print('删除文件夹:')
print(files_to_delete)
print('删除数:')
print(len(files_to_delete))

# # 删除不匹配的文件
# for filename in files_to_delete:
#     # print(filename)
#     if filename in image_files:
#         os.remove(os.path.join(image_folder, filename+'.jpg'))
#     if filename in label_files:
#         os.remove(os.path.join(label_folder, filename+'.txt'))

divide.py

# 数据集划分
#
import os
import random
import shutil

# 原始数据存放路径
data_dir = r"D:\Database\Database地铁\smoDB_phoDB_glaDB_faceDB_v2/"
images_dir = os.path.join(data_dir, "JPEGImages")
labels_dir = os.path.join(data_dir, "label")

# 划分后的训练集和验证集路径
train_dir = "D:\Database\Database地铁\smoDB_phoDB_glaDB_faceDB_v2/train"
train_images_dir = os.path.join(train_dir, "images")
train_labels_dir = os.path.join(train_dir, "labels")

val_dir = "D:\Database\Database地铁\smoDB_phoDB_glaDB_faceDB_v2/val"
val_images_dir = os.path.join(val_dir, "images")
val_labels_dir = os.path.join(val_dir, "labels")

# 创建训练集和验证集目录
os.makedirs(train_images_dir, exist_ok=True)
os.makedirs(train_labels_dir, exist_ok=True)
os.makedirs(val_images_dir, exist_ok=True)
os.makedirs(val_labels_dir, exist_ok=True)

# 获取所有图片文件名
image_files = os.listdir(images_dir)

# 随机打乱文件列表
random.shuffle(image_files)

# 计算划分的数量
total_images = len(image_files)
train_ratio = 0.9
num_train = int(total_images * train_ratio)

# 将图片和标签文件划分到训练集和验证集
train_file_list = []
val_file_list = []

for i, image_file in enumerate(image_files):
    label_file = image_file.replace(".jpg", ".txt")

    if i < num_train:
        # 划分到训练集
        shutil.copy(os.path.join(images_dir, image_file), os.path.join(train_images_dir, image_file))
        shutil.copy(os.path.join(labels_dir, label_file), os.path.join(train_labels_dir, label_file))
        train_file_list.append(os.path.join("train", "images", image_file))
    else:
        # 划分到验证集
        shutil.copy(os.path.join(images_dir, image_file), os.path.join(val_images_dir, image_file))
        shutil.copy(os.path.join(labels_dir, label_file), os.path.join(val_labels_dir, label_file))
        val_file_list.append(os.path.join("val", "images", image_file))

# 创建train.txt和val.txt文件
with open(os.path.join(data_dir, "train.txt"), "w") as train_txt_file:
    train_txt_file.write("\n".join(train_file_list))

with open(os.path.join(data_dir, "val.txt"), "w") as val_txt_file:
    val_txt_file.write("\n".join(val_file_list))

print(f"划分完成,训练集包含 {num_train} 个样本,验证集包含 {total_images - num_train} 个样本。")

examine.py

# 检查txt文件夹内文件内容是否为空
import os

folder_path = "/home/ws/CoodWorkRun/Database/smoDB_phoDB_glaDB/label"
empty_files = []

for file_name in os.listdir(folder_path):
    if file_name.endswith(".txt"):
        file_path = os.path.join(folder_path, file_name)
        if os.path.getsize(file_path) == 0:
            empty_files.append(file_name)
            print("Empty file:", file_name)

num_empty_folders = len(empty_files)
print("Number of empty files:", num_empty_folders)

label_make.py

# 人脸数据集标签制作

from PIL import Image,ImageDraw

anno_box_path = r"/home/ws/CoodWorkRun/Database/人脸数据集/CelebA/Anno/list_bbox_celeba.txt"
label_dir = "/home/ws/CoodWorkRun/Database/人脸数据集/CelebA/label"
img_dir = "/home/ws/CoodWorkRun/Database/人脸数据集/CelebA/Img/img_celeba.7z/img_celeba"
count = 0
epoch = 1
box_file = open(anno_box_path,"r")

i = 0


for line in box_file:
    if i < 2:
        i += 1
        continue
    i += 1
    print(line)

    imgname = line[0:6]
    #print(imgname)

    img_strs = line.split()
    x1, y1, w, h = int(img_strs[1]), int(img_strs[2]), int(img_strs[3]), int(img_strs[4])
    x2, y2 = x1+w, y1+h

    img = Image.open(f"{img_dir}/{img_strs[0]}")
    img_w, img_h = img.size

    # ****************************
    dw = 1. / (int(img_w))
    dh = 1. / (int(img_h))
    x = ((x1 + x2) / 2.0 - 1)*dw
    y = ((y1 + y2) / 2.0 - 1)*dh
    w = (x2 - x1)*dw
    h = (y2 - y1)*dh
    # x = x * dw
    # w = w * dw
    # y = y * dh
    # h = h * dh
    # ****************************
    label_txt = open(f"{label_dir}/{imgname}.txt", "w")

    label_txt.write(f"0 {x} {y} {w} {h}\n")
    label_txt.flush()
    label_txt.close()

    if i == 1:
        exit()

rename.py

# 标签文件重命名
import os

def rename_files(folder_path_images, folder_path_labels):
    try:
        # 获取两个文件夹中的文件列表
        image_files = sorted(os.listdir(folder_path_images))
        label_files = sorted(os.listdir(folder_path_labels))

        # 确保两个文件夹中的文件数量相同
        if len(image_files) != len(label_files):
            print("Error: The number of files in the two folders does not match.")
            return

        # 遍历文件列表,对应重命名文件
        for image_file, label_file in zip(image_files, label_files):
            image_old_path = os.path.join(folder_path_images, image_file)
            label_old_path = os.path.join(folder_path_labels, label_file)

            # 获取文件名和扩展名
            image_name, image_ext = os.path.splitext(image_file)

            # 生成新的文件名
            new_name = f"phoneB_{image_name}"

            # 构建新的文件路径
            image_new_path = os.path.join(folder_path_images, f"{new_name}{image_ext}")
            label_new_path = os.path.join(folder_path_labels, f"{new_name}.txt")

            # 重命名文件
            os.rename(image_old_path, image_new_path)
            os.rename(label_old_path, label_new_path)

        print("Files renamed successfully.")

    except Exception as e:
        print(f"Error: {e}")

# 使用示例
folder_path_images = r'C:\Users\User\Desktop\coco\transfer\cell_phone\JPEGImages'
folder_path_labels = r'C:\Users\User\Desktop\coco\transfer\cell_phone\label'

rename_files(folder_path_images, folder_path_labels)

xmlToTxt.py

# xml转txt标签文件
#
import xml.etree.ElementTree as ET
from os import listdir, getcwd
import glob
import cv2

# folder_path_images = r'C:\Users\User\Desktop\coco\transfer\bottle\JPEGImages'
# folder_path_labels = r'C:\Users\User\Desktop\coco\transfer\bottle\annotations'

classes = ["cell phone"]  # <name>person</name>,中是啥填啥,多个用逗号隔开

def convert(size, box):
    # 新增对框框范围的判断,防止0作为被除数
    if size[0] == 0:
        dw = size[0]
    else:
        dw = 1.0 / size[0]

    if size[1] == 0:
        dw = size[1]
    else:
        dh = 1.0 / size[1]

    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    # return (x, y, w, h)
    return ('%.6f' % x, '%.6f' % y, '%.6f' % w, '%.6f' % h)


def convert_annotation(image_name, image_path):
    print(f"Processing {image_name}")
    # print(image_name[0:-3])
    f = open(r'C:\Users\User\Desktop\coco\transfer\cell_phone\annotations/' + image_name[0:-3] + 'xml', encoding="utf8")  # xml文件存放文件夹路径
    out_file = open(r'C:\Users\User\Desktop\coco\transfer\cell_phone/label/' + image_name[0:-3] + 'txt', 'w')  # 存放转换后的txt文件路径,记得先创建label文件夹
    xml_text = f.read()
    root = ET.fromstring(xml_text)
    f.close()
    size = root.find('size')
    # 填补图片高宽缺失
    img = cv2.imread(image_path)
    sz = img.shape

    w = int(sz[1])
    h = int(sz[0])
    # w = int(size.find('width').text)
    # h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls not in classes:
            # print(cls)
            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_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


wd = getcwd()

if __name__ == '__main__':

    for image_path in glob.glob(r"C:\Users\User\Desktop\coco\transfer\cell_phone/JPEGImages/*.jpg"):  # 放图片的文件夹,自己图片什么类型,自行替换
        image_name = image_path.split('\\')[-1]
        # print(image_name)
        convert_annotation(image_name, image_path)
    print('完成!')

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
需要学习Windows系统YOLOv4的同学请前往《Windows版YOLOv4目标检测实战:原理与源码解析》,课程链接 https://edu.csdn.net/course/detail/29865【为什么要学习这门课】 Linux创始人Linus Torvalds有一句名言:Talk is cheap. Show me the code. 冗谈不够,放码过来!  代码阅读是从基础到提高的必由之路。尤其对深度学习,许多框架隐藏了神经网络底层的实现,只能在上层调包使用,对其内部原理很难认识清晰,不利于进一步优化和创新。YOLOv4是最近推出的基于深度学习的端到端实时目标检测方法。YOLOv4的实现darknet是使用C语言开发的轻型开源深度学习框架,依赖少,可移植性好,可以作为很好的代码阅读案例,让我们深入探究其实现原理。【课程内容与收获】 本课程将解析YOLOv4的实现原理和源码,具体内容包括:- YOLOv4目标检测原理- 神经网络及darknet的C语言实现,尤其是反向传播的梯度求解和误差计算- 代码阅读工具及方法- 深度学习计算的利器:BLAS和GEMM- GPU的CUDA编程方法及在darknet的应用- YOLOv4的程序流程- YOLOv4各层及关键技术的源码解析本课程将提供注释后的darknet的源码程序文件。【相关课程】 除本课程《YOLOv4目标检测:原理与源码解析》外,本人推出了有关YOLOv4目标检测的系列课程,包括:《YOLOv4目标检测实战:训练自己的数据集》《YOLOv4-tiny目标检测实战:训练自己的数据集》《YOLOv4目标检测实战:人脸口罩佩戴检测》《YOLOv4目标检测实战:中国交通标志识别》建议先学习一门YOLOv4实战课程,对YOLOv4的使用方法了解以后再学习本课程。【YOLOv4网络模型架构图】 下图由白勇老师绘制  
YOLO(You Only Look Once)是一种用于目标检测的算法,通过单个神经网络模型进行实时目标检测。相比传统的目标检测方法,YOLO算法具有更快的检测速度和更好的检测准确率。 在Matlab中使用YOLO算法,可以通过以下几个步骤实现: 1. 安装Matlab深度学习工具箱,该工具箱提供了YOLO算法的实现功能。 2. 下载预训练的YOLO模型,YOLO算法在训练过程中需要大量的数据和计算资源,因此通常会使用预训练的模型来进行二次开发。可以在YOLO官方网站或者其他开源项目中找到预训练的模型。 3. 加载模型和图片数据,使用Matlab提供的函数加载已经训练好的YOLO模型,并读取要检测的图片数据。 4. 图片预处理,对读取的图片数据进行一系列的预处理操作,比如调整图片大小、归一化、转换为模型可接受的输入格式等。 5. 调用YOLO模型进行目标检测,将处理后的图片数据输入到YOLO模型中进行检测。模型将返回目标的类别、位置和置信度等信息。 6. 可视化检测结果,使用Matlab提供的绘图函数将检测结果可视化展示出来,比如在图片上绘制框和标签。 需要注意的是,YOLO算法是一种计算资源密集型的算法,对于较低配置的计算机可能会有一定的性能压力。此外,YOLO算法的检测结果可能会受到一些限制,比如遮挡、视角变化等因素的影响。因此,在实际应用中可能需要根据具体场景对算法进行优化和改进。 总之,通过在Matlab中使用YOLO算法,可以快速、准确地实现目标检测功能,为图像处理和计算机视觉等领域的应用提供帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1-0-1 C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值