转载+记录数据增广的八种常用方式

在图像的深度学习中,为了丰富图像训练集,提高模型的泛化能力,一般会对图像进行数据增强。常用的方式有:旋转、剪切、改变图像色差、扭曲图像特征、改变图像尺寸、增加图像噪声(高斯噪声、盐胶噪声)。

思考:对于人脸的数据增广来说,其是对称的,所以镜像旋转pass,然后剪切后的部分人脸应用价值不高,大多数人脸识别都会将人脸对齐,所以多种形式的剪切没有意义,但将人脸从背景中剪切出来再进行识别对于facenet来说很有用。(ps:个人愚见,欢迎讨论)

 
  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. from PIL import Image, ImageEnhance, ImageOps, ImageFile

  15. import numpy as np

  16. import random

  17. import threading, os, time

  18. import logging

  19. logger = logging.getLogger(__name__)

  20. ImageFile.LOAD_TRUNCATED_IMAGES = True

  21. class DataAugmentation:

  22. """

  23. 包含数据增强的八种方式

  24. """

  25. def __init__(self):

  26. pass

  27. @staticmethod

  28. def openImage(image):

  29. return Image.open(image, mode="r")

  30. @staticmethod

  31. def randomRotation(image, mode=Image.BICUBIC):

  32. """

  33. 对图像进行随机任意角度(0~360度)旋转

  34. :param mode 邻近插值,双线性插值,双三次B样条插值(default)

  35. :param image PIL的图像image

  36. :return: 旋转转之后的图像

  37. """

  38. random_angle = np.random.randint(1, 360)

  39. return image.rotate(random_angle, mode)

  40. @staticmethod

  41. def randomCrop(image):

  42. """

  43. 对图像随意剪切,考虑到图像大小范围(68,68),使用一个一个大于(36*36)的窗口进行截图

  44. :param image: PIL的图像image

  45. :return: 剪切之后的图像

  46. """

  47. image_width = image.size[0]

  48. image_height = image.size[1]

  49. crop_win_size = np.random.randint(40, 68)

  50. random_region = (

  51. (image_width - crop_win_size) >> 1, (image_height - crop_win_size) >> 1, (image_width + crop_win_size) >> 1,

  52. (image_height + crop_win_size) >> 1)

  53. return image.crop(random_region)

  54. @staticmethod

  55. def randomColor(image):

  56. """

  57. 对图像进行颜色抖动

  58. :param image: PIL的图像image

  59. :return: 有颜色色差的图像image

  60. """

  61. random_factor = np.random.randint(0, 31) / 10. # 随机因子

  62. color_image = ImageEnhance.Color(image).enhance(random_factor) # 调整图像的饱和度

  63. random_factor = np.random.randint(10, 21) / 10. # 随机因子

  64. brightness_image = ImageEnhance.Brightness(color_image).enhance(random_factor) # 调整图像的亮度

  65. random_factor = np.random.randint(10, 21) / 10. # 随机因1子

  66. contrast_image = ImageEnhance.Contrast(brightness_image).enhance(random_factor) # 调整图像对比度

  67. random_factor = np.random.randint(0, 31) / 10. # 随机因子

  68. return ImageEnhance.Sharpness(contrast_image).enhance(random_factor) # 调整图像锐度

  69. @staticmethod

  70. def randomGaussian(image, mean=0.2, sigma=0.3):

  71. """

  72. 对图像进行高斯噪声处理

  73. :param image:

  74. :return:

  75. """

  76. def gaussianNoisy(im, mean=0.2, sigma=0.3):

  77. """

  78. 对图像做高斯噪音处理

  79. :param im: 单通道图像

  80. :param mean: 偏移量

  81. :param sigma: 标准差

  82. :return:

  83. """

  84. for _i in range(len(im)):

  85. im[_i] += random.gauss(mean, sigma)

  86. return im

  87. # 将图像转化成数组

  88. img = np.asarray(image)

  89. img.flags.writeable = True # 将数组改为读写模式

  90. width, height = img.shape[:2]

  91. img_r = gaussianNoisy(img[:, :, 0].flatten(), mean, sigma)

  92. img_g = gaussianNoisy(img[:, :, 1].flatten(), mean, sigma)

  93. img_b = gaussianNoisy(img[:, :, 2].flatten(), mean, sigma)

  94. img[:, :, 0] = img_r.reshape([width, height])

  95. img[:, :, 1] = img_g.reshape([width, height])

  96. img[:, :, 2] = img_b.reshape([width, height])

  97. return Image.fromarray(np.uint8(img))

  98. @staticmethod

  99. def saveImage(image, path):

  100. image.save(path)

  101. def makeDir(path):

  102. try:

  103. if not os.path.exists(path):

  104. if not os.path.isfile(path):

  105. # os.mkdir(path)

  106. os.makedirs(path)

  107. return 0

  108. else:

  109. return 1

  110. except Exception, e:

  111. print str(e)

  112. return -2

  113. def imageOps(func_name, image, des_path, file_name, times=5):

  114. funcMap = {"randomRotation": DataAugmentation.randomRotation,

  115. "randomCrop": DataAugmentation.randomCrop,

  116. "randomColor": DataAugmentation.randomColor,

  117. "randomGaussian": DataAugmentation.randomGaussian

  118. }

  119. if funcMap.get(func_name) is None:

  120. logger.error("%s is not exist", func_name)

  121. return -1

  122. for _i in range(0, times, 1):

  123. new_image = funcMap[func_name](image)

  124. DataAugmentation.saveImage(new_image, os.path.join(des_path, func_name + str(_i) + file_name))

  125. opsList = {"randomRotation", "randomCrop", "randomColor", "randomGaussian"}

  126. def threadOPS(path, new_path):

  127. """

  128. 多线程处理事务

  129. :param src_path: 资源文件

  130. :param des_path: 目的地文件

  131. :return:

  132. """

  133. if os.path.isdir(path):

  134. img_names = os.listdir(path)

  135. else:

  136. img_names = [path]

  137. for img_name in img_names:

  138. print img_name

  139. tmp_img_name = os.path.join(path, img_name)

  140. if os.path.isdir(tmp_img_name):

  141. if makeDir(os.path.join(new_path, img_name)) != -1:

  142. threadOPS(tmp_img_name, os.path.join(new_path, img_name))

  143. else:

  144. print 'create new dir failure'

  145. return -1

  146. # os.removedirs(tmp_img_name)

  147. elif tmp_img_name.split('.')[1] != "DS_Store":

  148. # 读取文件并进行操作

  149. image = DataAugmentation.openImage(tmp_img_name)

  150. threadImage = [0] * 5

  151. _index = 0

  152. for ops_name in opsList:

  153. threadImage[_index] = threading.Thread(target=imageOps,

  154. args=(ops_name, image, new_path, img_name,))

  155. threadImage[_index].start()

  156. _index += 1

  157. time.sleep(0.2)

  158. if __name__ == '__main__':

  159. threadOPS("/home/pic-image/train/12306train",

  160. "/home/pic-image/train/12306train3")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值