制备图片数据问题(长话短说)图片数据处理(数据增广,数据格式处理,自动标注)

目录

1.labelme打开图片闪退问题

2.数据格式问题

jpg格式转化

3.数据量少问题

kears数据增广

4.数据转化问题

json to txt:

xml to txt:

 5.数据划分问题

6.数据自动标注问题

yolo辅助标注

7.labelme和labelimg



本片梳理博主在制备数据集所遇问题

1.labelme打开图片闪退问题

原因:数据位深不正确,所有位深为32,打开之后labelme直接闪退

解决:修改为24位深


from PIL import Image
import os

path = "D:\Desktop\实验\图片"              # 原始位像素图像文件路径
save_path = "D:\Desktop\实验\图片24"       # 转后保存的路径

files = os.listdir(path)

for pic in files:
    img = Image.open(os.path.join(path, pic)).convert('RGB')
    print(img.getbands())  # ('P',) 这种是有彩色的,而L是没有彩色的

    pic_new = os.path.join(save_path, pic)

    img.save(pic_new)


2.数据格式问题

jpg格式转化

创建txt文件,并将添加内容,并将后缀名改为.bat

@Echo Off&SetLocal ENABLEDELAYEDEXPANSION

FOR %%a in (*) do (

set "name=%%a"

set "name=!name: (=!"

set "name=!name:)=!"

ren "%%a" "!name!"

)

exit

3.数据量少问题

kears数据增广

首先是kears环境问题:【快速解决】vscode安装Keras,tensorflow;解决from tensorflow.keras.models import Sequential环境配置不上怎么办?_无法解析导入“keras.models”-CSDN博客

import os
from numpy import expand_dims
from keras.preprocessing.image import load_img, img_to_array
from keras.preprocessing.image import ImageDataGenerator
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image
import shutil

# 设置源文件夹路径
source_folder = r''

# 遍历源文件夹中的所有图片
for filename in os.listdir(source_folder):
    if filename.endswith('.jpg') or filename.endswith('.png'):  # 根据需要添加其他图片格式
        # 构建完整的文件路径
        filepath = os.path.join(source_folder, filename)

        # 加载图片
        img = load_img(filepath)

        # 转换为numpy数组
        data = img_to_array(img)

        # 扩展维度以适应模型输入
        samples = expand_dims(data, 0)

        # 创建图像数据增强生成器
        data_gen = ImageDataGenerator(
            width_shift_range=0.2,  # TODO:随机水平方向平移图像(fraction of total width)
            height_shift_range=0.2,  # TODO:随机纵向平移图像(fraction of total height)
            horizontal_flip=True,
            rotation_range=180,
            zoom_range=[0.9, 1.0],
            #参数有很多
        )
        # 准备迭代器
        it = data_gen.flow(samples, batch_size=1)

        # 为增强后的图像创建一个新文件夹(如果需要)
        augmented_folder = os.path.join(source_folder, 'augmented')
        if not os.path.exists(augmented_folder):
            os.makedirs(augmented_folder)

        # 生成增强后的样本并保存
        for i in range(9):  # 假设我们想要为每个原始图像生成5个增强版本
            # 生成一批图像
            batch = it.next()

            # 转换为无符号整数以便查看和保存
            augmented_image = batch[0].astype('uint8')

            # 创建保存路径
            augmented_filepath = os.path.join(augmented_folder, f'{i}_{filename}')

            # 将增强后的图像保存为文件
            Image.fromarray(augmented_image).save(augmented_filepath)

# 注意:在实际应用中,您可能想要删除上面的可选显示部分,以避免在处理大量图像时产生不必要的延迟。

4.数据转化问题

json to txt

import json
import os

name2id = {'blood': 0}  # 标签名称


def convert(img_size, box):
    dw = 1. / (img_size[0])
    dh = 1. / (img_size[1])
    x = (box[0] + box[2]) / 2.0 - 1
    y = (box[1] + box[3]) / 2.0 - 1
    w = box[2] - box[0]
    h = box[3] - box[1]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def decode_json(json_floder_path, json_name):
    txt_name = r'D:\TestMain\yolov10\datasets\bfish\lables/' + json_name[0:-5] + '.txt'
    # 存放txt的绝对路径
    txt_file = open(txt_name, 'w')

    json_path = os.path.join(json_floder_path, json_name)
    data = json.load(open(json_path, 'r', encoding='gb2312', errors='ignore'))

    img_w = data['imageWidth']
    img_h = data['imageHeight']

    for i in data['shapes']:

        label_name = i['label']
        if (i['shape_type'] == 'rectangle'):
            x1 = int(i['points'][0][0])
            y1 = int(i['points'][0][1])
            x2 = int(i['points'][1][0])
            y2 = int(i['points'][1][1])

            bb = (x1, y1, x2, y2)
            bbox = convert((img_w, img_h), bb)
            txt_file.write(str(name2id[label_name]) + " " + " ".join([str(a) for a in bbox]) + '\n')


if __name__ == "__main__":

    json_floder_path = r'D:\TestMain\yolov10\datasets\bfish\json'
    # 存放json的文件夹的绝对路径
    json_names = os.listdir(json_floder_path)
    for json_name in json_names:
        decode_json(json_floder_path, json_name)

xml to txt

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join


def convert(size, box):
    # size=(width, height)  b=(xmin, xmax, ymin, ymax)
    # x_center = (xmax+xmin)/2        y_center = (ymax+ymin)/2
    # x = x_center / width            y = y_center / height
    # w = (xmax-xmin) / width         h = (ymax-ymin) / height

    x_center = (box[0] + box[1]) / 2.0
    y_center = (box[2] + box[3]) / 2.0
    x = x_center / size[0]
    y = y_center / size[1]

    w = (box[1] - box[0]) / size[0]
    h = (box[3] - box[2]) / size[1]

    # print(x, y, w, h)
    return (x, y, w, h)


def convert_annotation(xml_files_path, save_txt_files_path, classes):
    xml_files = os.listdir(xml_files_path)
    # print(xml_files)
    for xml_name in xml_files:
        # print(xml_name)
        xml_file = os.path.join(xml_files_path, xml_name)
        out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')
        out_txt_f = open(out_txt_path, 'w')
        tree = ET.parse(xml_file)
        root = tree.getroot()
        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)

        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))
            # b=(xmin, xmax, ymin, ymax)
            # print(w, h, b)
            bb = convert((w, h), b)
            out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


if __name__ == "__main__":
    # 把forklift_pallet的voc的xml标签文件转化为yolo的txt标签文件
    # 1、需要转化的类别
    classes = ['fish']
    # 2、voc格式的xml标签文件路径
    xml_files1 = r'D:\TestMain\yolov9-main\datasets\fish1\Annotations'
    # 3、转化为yolo格式的txt标签文件存储路径
    save_txt_files1 = r'D:\TestMain\yolov9-main\datasets\fish1\lables'

    convert_annotation(xml_files1, save_txt_files1, classes)

 5.数据划分问题

import os, shutil, random
from tqdm import tqdm

"""
标注文件是yolo格式(txt文件)
训练集:验证集:测试集 (7:2:1) 
"""
def split_img(img_path, label_path, split_list):
    try:
        Data = 'D:/TestMain/yolov9-main/datasets/fish1/ImageSets'
        # Data是你要将要创建的文件夹路径(路径一定是相对于你当前的这个脚本而言的)
        # os.mkdir(Data)

        train_img_dir = Data + '/images/train'
        val_img_dir = Data + '/images/val'
        test_img_dir = Data + '/images/test'

        train_label_dir = Data + '/labels/train'
        val_label_dir = Data + '/labels/val'
        test_label_dir = Data + '/labels/test'

        # 创建文件夹
        os.makedirs(train_img_dir)
        os.makedirs(train_label_dir)
        os.makedirs(val_img_dir)
        os.makedirs(val_label_dir)
        os.makedirs(test_img_dir)
        os.makedirs(test_label_dir)

    except:
        print('文件目录已存在')

    train, val, test = split_list
    all_img = os.listdir(img_path)
    all_img_path = [os.path.join(img_path, img) for img in all_img]
    # all_label = os.listdir(label_path)
    # all_label_path = [os.path.join(label_path, label) for label in all_label]
    train_img = random.sample(all_img_path, int(train * len(all_img_path)))
    train_img_copy = [os.path.join(train_img_dir, img.split('\\')[-1]) for img in train_img]
    train_label = [toLabelPath(img, label_path) for img in train_img]
    train_label_copy = [os.path.join(train_label_dir, label.split('\\')[-1]) for label in train_label]
    for i in tqdm(range(len(train_img)), desc='train ', ncols=80, unit='img'):
        _copy(train_img[i], train_img_dir)
        _copy(train_label[i], train_label_dir)
        all_img_path.remove(train_img[i])
    val_img = random.sample(all_img_path, int(val / (val + test) * len(all_img_path)))
    val_label = [toLabelPath(img, label_path) for img in val_img]
    for i in tqdm(range(len(val_img)), desc='val ', ncols=80, unit='img'):
        _copy(val_img[i], val_img_dir)
        _copy(val_label[i], val_label_dir)
        all_img_path.remove(val_img[i])
    test_img = all_img_path
    test_label = [toLabelPath(img, label_path) for img in test_img]
    for i in tqdm(range(len(test_img)), desc='test ', ncols=80, unit='img'):
        _copy(test_img[i], test_img_dir)
        _copy(test_label[i], test_label_dir)


def _copy(from_path, to_path):
    shutil.copy(from_path, to_path)


def toLabelPath(img_path, label_path):
    img = img_path.split('\\')[-1]
    label = img.split('.jpg')[0] + '.txt'
    return os.path.join(label_path, label)


if __name__ == '__main__':
    img_path = 'D:\TestMain\yolov9-main\datasets\\fish1\images'  # 你的图片存放的路径(路径一定是相对于你当前的这个脚本文件而言的)
    label_path = 'D:\TestMain\yolov9-main\datasets\\fish1\lables'  # 你的txt文件存放的路径(路径一定是相对于你当前的这个脚本文件而言的)
    split_list = [0.7, 0.2, 0.1]  # 数据集划分比例[train:val:test]
    split_img(img_path, label_path, split_list)

6.数据自动标注问题

yolo辅助标注

设置save_txtFalse表示不会将结果保存为.txt文件。这是一个布尔值。

 存放位置在runs/detect/predict文件夹中

7.labelme和labelimg

 labelimg结果为txt文件,且打开步骤为先打开输出文件,再打开图片

labelme结果为json文件,要进一步转为txt文件

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值