• 深度学习之图像的数据增强


       在图像的深度学习中,为了丰富图像训练集,更好的提取图像特征,泛化模型(防止模型过拟合),一般都会对数据图像进行数据增强,

    数据增强,常用的方式,就是旋转图像,剪切图像,改变图像色差,扭曲图像特征,改变图像尺寸大小,增强图像噪音(一般使用高斯噪音,盐椒噪音)等.

    但是需要注意,不要加入其他图像轮廓的噪音.

      对于常用的图像的数据增强的实现,如下:

      1 # -*- coding:utf-8 -*-
      2 """数据增强
      3    1. 翻转变换 flip
      4    2. 随机修剪 random crop
      5    3. 色彩抖动 color jittering
      6    4. 平移变换 shift
      7    5. 尺度变换 scale
      8    6. 对比度变换 contrast
      9    7. 噪声扰动 noise
     10    8. 旋转变换/反射变换 Rotation/reflection
     11    author: XiJun.Gong
     12    date:2016-11-29
     13 """
     14 
     15 from PIL import Image, ImageEnhance, ImageOps, ImageFile
     16 import numpy as np
     17 import random
     18 import threading, os, time
     19 import logging
     20 
     21 logger = logging.getLogger(__name__)
     22 ImageFile.LOAD_TRUNCATED_IMAGES = True
     23 
     24 
     25 class DataAugmentation:
     26     """
     27     包含数据增强的八种方式
     28     """
     29 
     30 
     31     def __init__(self):
     32         pass
     33 
     34     @staticmethod
     35     def openImage(image):
     36         return Image.open(image, mode="r")
     37 
     38     @staticmethod
     39     def randomRotation(image, mode=Image.BICUBIC):
     40         """
     41          对图像进行随机任意角度(0~360度)旋转
     42         :param mode 邻近插值,双线性插值,双三次B样条插值(default)
     43         :param image PIL的图像image
     44         :return: 旋转转之后的图像
     45         """
     46         random_angle = np.random.randint(1, 360)
     47         return image.rotate(random_angle, mode)
     48 
     49     @staticmethod
     50     def randomCrop(image):
     51         """
     52         对图像随意剪切,考虑到图像大小范围(68,68),使用一个一个大于(36*36)的窗口进行截图
     53         :param image: PIL的图像image
     54         :return: 剪切之后的图像
     55 
     56         """
     57         image_width = image.size[0]
     58         image_height = image.size[1]
     59         crop_win_size = np.random.randint(40, 68)
     60         random_region = (
     61             (image_width - crop_win_size) >> 1, (image_height - crop_win_size) >> 1, (image_width + crop_win_size) >> 1,
     62             (image_height + crop_win_size) >> 1)
     63         return image.crop(random_region)
     64 
     65     @staticmethod
     66     def randomColor(image):
     67         """
     68         对图像进行颜色抖动
     69         :param image: PIL的图像image
     70         :return: 有颜色色差的图像image
     71         """
     72         random_factor = np.random.randint(0, 31) / 10.  # 随机因子
     73         color_image = ImageEnhance.Color(image).enhance(random_factor)  # 调整图像的饱和度
     74         random_factor = np.random.randint(10, 21) / 10.  # 随机因子
     75         brightness_image = ImageEnhance.Brightness(color_image).enhance(random_factor)  # 调整图像的亮度
     76         random_factor = np.random.randint(10, 21) / 10.  # 随机因1子
     77         contrast_image = ImageEnhance.Contrast(brightness_image).enhance(random_factor)  # 调整图像对比度
     78         random_factor = np.random.randint(0, 31) / 10.  # 随机因子
     79         return ImageEnhance.Sharpness(contrast_image).enhance(random_factor)  # 调整图像锐度
     80 
     81     @staticmethod
     82     def randomGaussian(image, mean=0.2, sigma=0.3):
     83         """
     84          对图像进行高斯噪声处理
     85         :param image:
     86         :return:
     87         """
     88 
     89         def gaussianNoisy(im, mean=0.2, sigma=0.3):
     90             """
     91             对图像做高斯噪音处理
     92             :param im: 单通道图像
     93             :param mean: 偏移量
     94             :param sigma: 标准差
     95             :return:
     96             """
     97             for _i in range(len(im)):
     98                 im[_i] += random.gauss(mean, sigma)
     99             return im
    100 
    101         # 将图像转化成数组
    102         img = np.asarray(image)
    103         img.flags.writeable = True  # 将数组改为读写模式
    104         width, height = img.shape[:2]
    105         img_r = gaussianNoisy(img[:, :, 0].flatten(), mean, sigma)
    106         img_g = gaussianNoisy(img[:, :, 1].flatten(), mean, sigma)
    107         img_b = gaussianNoisy(img[:, :, 2].flatten(), mean, sigma)
    108         img[:, :, 0] = img_r.reshape([width, height])
    109         img[:, :, 1] = img_g.reshape([width, height])
    110         img[:, :, 2] = img_b.reshape([width, height])
    111         return Image.fromarray(np.uint8(img))
    112 
    113     @staticmethod
    114     def saveImage(image, path):
    115         image.save(path)
    116 
    117 
    118 def makeDir(path):
    119     try:
    120         if not os.path.exists(path):
    121             if not os.path.isfile(path):
    122                 # os.mkdir(path)
    123                 os.makedirs(path)
    124             return 0
    125         else:
    126             return 1
    127     except Exception, e:
    128         print str(e)
    129         return -2
    130 
    131 
    132 def imageOps(func_name, image, des_path, file_name, times=5):
    133     funcMap = {"randomRotation": DataAugmentation.randomRotation,
    134                "randomCrop": DataAugmentation.randomCrop,
    135                "randomColor": DataAugmentation.randomColor,
    136                "randomGaussian": DataAugmentation.randomGaussian
    137                }
    138     if funcMap.get(func_name) is None:
    139         logger.error("%s is not exist", func_name)
    140         return -1
    141 
    142     for _i in range(0, times, 1):
    143         new_image = funcMap[func_name](image)
    144         DataAugmentation.saveImage(new_image, os.path.join(des_path, func_name + str(_i) + file_name))
    145 
    146 
    147 opsList = {"randomRotation", "randomCrop", "randomColor", "randomGaussian"}
    148 
    149 
    150 def threadOPS(path, new_path):
    151     """
    152     多线程处理事务
    153     :param src_path: 资源文件
    154     :param des_path: 目的地文件
    155     :return:
    156     """
    157     if os.path.isdir(path):
    158         img_names = os.listdir(path)
    159     else:
    160         img_names = [path]
    161     for img_name in img_names:
    162         print img_name
    163         tmp_img_name = os.path.join(path, img_name)
    164         if os.path.isdir(tmp_img_name):
    165             if makeDir(os.path.join(new_path, img_name)) != -1:
    166                 threadOPS(tmp_img_name, os.path.join(new_path, img_name))
    167             else:
    168                 print 'create new dir failure'
    169                 return -1
    170                 # os.removedirs(tmp_img_name)
    171         elif tmp_img_name.split('.')[1] != "DS_Store":
    172             # 读取文件并进行操作
    173             image = DataAugmentation.openImage(tmp_img_name)
    174             threadImage = [0] * 5
    175             _index = 0
    176             for ops_name in opsList:
    177                 threadImage[_index] = threading.Thread(target=imageOps,
    178                                                        args=(ops_name, image, new_path, img_name,))
    179                 threadImage[_index].start()
    180                 _index += 1
    181                 time.sleep(0.2)
    182 
    183 
    184 if __name__ == '__main__':
    185     threadOPS("/home/pic-image/train/12306train",
    186               "/home/pic-image/train/12306train3")
    View Code
     
  • 相关阅读:
    五)使用 easyui-tabs 遭遇错误 Unexpected Exception caught setting '_' on
    六)iframe 及父子页面之间获取元素、方法调用
    七)如何实现权限控制
    二)手动添加基础数据
    三)EasyUI layout
    四)绘树
    一)6张表
    RollingFileAppender
    GitLabCI VS Jenkins 对比
    Nacos 学习记录
  • 原文地址:https://www.cnblogs.com/gongxijun/p/6117588.html
Copyright © 2020-2023  润新知