深度学习之图像数据集增强(Data Augmentation)

一、 数据增强概述

数据增强(Data Augmentation)是一种技术,通过对现有数据进行各种变换和处理来生成新的训练样本,从而增加数据集的多样性和数量。这些变换可以是几何变换、颜色变换、噪声添加等,使模型在训练过程中能够见到更多种类的数据,从而提升模型的泛化能力和鲁棒性。
在机器学习和深度学习中,数据的数量和质量对模型的性能至关重要。然而,获取大量标注数据通常既耗时又昂贵。数据增强通过对现有数据进行多种处理,模拟出更多样化 的训练样本,有效解决了数据稀缺的问题。这样不仅能防止模型过拟合(即模型在训练数据上表现很好,但在测试数据上表现不佳),还能够提升模型在不同情况下的表现,使其具有更强的泛化能力。
数据增强的方法多种多样,如下图所示:
在这里插入图片描述

这些方法各有优劣,可以根据具体任务和数据特点灵活选择和组合使用,以达到最佳的数据增强效果。通过数据增强,模型能够在有限的数据基础上获得更多的训练样本,提高训练效率和效果,最终在实际应用中表现得更加稳健和可靠。其中,传统数据增强方法比较常用且实现简单,因此本文主要实现传统数据增强的方法,其他数据增强方法后续有空再进行尝试。

二、python实现传统数据增强

import os
import random
from PIL import Image, ImageEnhance, ImageOps, ImageFilter

# 翻转图像
def flip_image(image, mode='horizontal'):
    if mode == 'horizontal':
        return image.transpose(Image.FLIP_LEFT_RIGHT)
    elif mode == 'vertical':
        return image.transpose(Image.FLIP_TOP_BOTTOM)
    else:
        raise ValueError("Mode should be 'horizontal' or 'vertical'")

# 旋转图像
def rotate_image(image, angle):
    return image.rotate(angle)

# 缩放图像
def scale_image(image, scale_factor):
    width, height = image.size
    return image.resize((int(width * scale_factor), int(height * scale_factor)))

# 图像平移
def move(img): #平移,平移尺度为off
    offset = ImageChops.offset(img, np.random.randint(1, 20), np.random.randint(1, 40))
    return offset
    
# 裁剪图像
def crop_image(image, crop_box):
    return image.crop(crop_box)

# 调整亮度、对比度、饱和度、色调
def adjust_color(image, brightness=1, contrast=1, saturation=1, hue=1):
    enhancer = ImageEnhance.Brightness(image)
    image = enhancer.enhance(brightness)
    enhancer = ImageEnhance.Contrast(image)
    image = enhancer.enhance(contrast)
    enhancer = ImageEnhance.Color(image)
    image = enhancer.enhance(saturation)
    # hue adjustment not directly available in PIL, skipped
    return image

# 添加噪声
def add_noise(image, noise_type='gaussian', mean=0, std=1):
    # This function is a placeholder; PIL doesn't support direct noise addition
    return image

# 模糊图像
def blur_image(image, blur_type='gaussian', radius=2):
    if blur_type == 'gaussian':
        return image.filter(ImageFilter.GaussianBlur(radius))
    elif blur_type == 'motion':
        return image.filter(ImageFilter.MotionBlur(radius))  # Pillow doesn't have MotionBlur, custom implementation needed
    else:
        raise ValueError("Blur type should be 'gaussian' or 'motion'")

# 仿射变换
def affine_transform(image, matrix):
    return image.transform(image.size, Image.AFFINE, matrix)

def test():
    input_image_path = 'skadi.jpg'  # 输入图像路径
    output_folder = 'output_path'  # 输出文件夹
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    image = Image.open(input_image_path)

    # 设置增强方法及其参数
    methods = [
        ('flip', {'mode': 'horizontal'}),
        ('rotate', {'angle': 45}),
        ('scale', {'scale_factor': 1.5}),
        ('translate', {'x': 10, 'y': 20}),
        ('crop', {'crop_box': (10, 10, 200, 200)}),
        ('adjust_color', {'brightness': 1.2, 'contrast': 1.5, 'saturation': 1.3}),
        ('add_noise', {'noise_type': 'gaussian', 'mean': 0, 'std': 1}),
        ('blur', {'blur_type': 'gaussian', 'radius': 2}),
        ('affine', {'matrix': (1, 0.2, 0, 0.2, 1, 0)})
    ]

    # 应用选择的增强方法
    for method_name, params in methods:
        if method_name == 'flip':
            result_image = flip_image(image, **params)
        elif method_name == 'rotate':
            result_image = rotate_image(image, **params)
        elif method_name == 'scale':
            result_image = scale_image(image, **params)
        elif method_name == 'translate':
            result_image = translate_image(image, **params)
        elif method_name == 'crop':
            result_image = crop_image(image, **params)
        elif method_name == 'adjust_color':
            result_image = adjust_color(image, **params)
        elif method_name == 'add_noise':
            result_image = add_noise(image, **params)
        elif method_name == 'blur':
            result_image = blur_image(image, **params)
        elif method_name == 'affine':
            result_image = affine_transform(image, **params)
        else:
            continue

        output_image_path = os.path.join(output_folder, f"{method_name}_output.jpg")
        result_image.save(output_image_path)

if __name__ == '__main__':
    test()

例子:对图像进行随机翻转

def pair_flip_image(img, label):
    p = 0.5
    if np.random.random() < p:
        return flip_image(img), flip_image(label)
    return img, label
    
def data_expand():
    image_dir = r"D:\test"
    image_list = os.listdir(os.path.join(image_dir, 'image'))
    expand_time = 10
    for idx in range(len(image_list)):
        if image_list[idx].endswith(('.png', '.jpg', '.tif')):
            print(image_list[idx])
            image = Image.open(os.path.join(image_dir, 'image', image_list[idx]))
            label = Image.open(os.path.join(image_dir, 'label', image_list[idx]))
            for k in range(expand_time):
                image, label = pair_flip_image(image, label)
                image.save("image.png")
                label.save("label.png")    
 
 if __name__ == '__main__':
    data_expand()

参考文献

[1] 数据增强基本介绍和常用的数据增强方法
[2] 使用python及PIL库对图像分类数据图片进行数据增强扩充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值