数据扩增
数据扩增是扩充数据的一项重要手段,原理是基于已有的标注数据,进行相应变化,其对应的标签不作改变或者也跟着有相应的变化。
本次只对原始图片进行更改,label保持不变。即只变动原始数据,生成新的图像的label与原始图像一样,只是文件名变了
import skimage
import os
import shutil
import sys
from PIL import Image, ImageEnhance, ImageChops
import random
import numpy as np
def aj_contrast(root_path, img_name, label_path): # 调整对比度 两种方式 gamma/log
image = skimage.io.imread(os.path.join(root_path, img_name))
gam = skimage.exposure.adjust_gamma(image, 0.5)
img_save_path = "/xxxx/image/"
label_save_path = "/xxxx/label/"
skimage.io.imsave(os.path.join(img_save_path, img_name.split('.')[0] + '_gam.jpg'), gam)
label_src = label_path + img_name.split('.')[0] + '.txt'
label_dst = label_save_path + img_name.split('.')[0] + '_gam.txt'
shutil.copy(label_src, label_dst)
log = skimage.exposure.adjust_log(image)
img_save_path = "/xxxx/image/"
label_save_path = "/xxxx/label/"
skimage.io.imsave(os.path.join(img_save_path, img_name.split('.')[0] + '_log.jpg'), log)
label_dst = label_save_path + img_name.split('.')[0] + '_log.txt'
shutil.copy(label_src, label_dst)
return gam, log
def randomGaussian(root_path, img_name, label_path, mean=0, sigma=4): # 高斯噪声
image = Image.open(os.path.join(root_path, img_name))
im = np.array(image)
# 设定高斯函数的偏移
means = 0
# 设定高斯函数的标准差
sigma = 25
# r通道
r = im[:, :, 0].flatten()
# g通道
g = im[:, :, 1].flatten()
# b通道
b = im[:, :, 2].flatten()
# 计算新的像素值
for i in range(im.shape[0]*im.shape[1]):
pr = int(r[i]) + random.gauss(0, sigma)
pg = int(g[i]) + random.gauss(0, sigma)
pb = int(b[i]) + random.gauss(0, sigma)
if(pr < 0):
pr = 0
if(pr > 255):
pr = 255
if(pg < 0):
pg = 0
if(pg > 255):
pg = 255
if(pb < 0):
pb = 0
if(pb > 255):
pb = 255
r[i] = pr
g[i] = pg
b[i] = pb
im[:, :, 0] = r.reshape([im.shape[0], im.shape[1]])
im[:, :, 1] = g.reshape([im.shape[0], im.shape[1]])
im[:, :, 2] = b.reshape([im.shape[0], im.shape[1]])
gaussian_image = Image.fromarray(np.uint8(im))
img_save_path = "/xxxx/image/"
label_save_path = "/xxxx/label/"
gaussian_image.save(os.path.join(img_save_path, img_name.split('.')[0] + '_randomGaussian.jpg'))
label_src = label_path + img_name.split('.')[0] + '.txt'
label_dst = label_save_path + img_name.split('.')[0] + '_randomGaussian.txt'
shutil.copy(label_src, label_dst)
return gaussian_image
def randomColor(root_path, img_name, label_path): # 随机颜色
"""
对图像进行颜色抖动
:param image: PIL的图像image
:return: 有颜色色差的图像image
"""
image = Image.open(os.path.join(root_path, img_name))
random_factor = np.random.randint(0, 31) / 10. # 随机因子
color_image = ImageEnhance.Color(image).enhance(random_factor) # 调整图像的饱和度
random_factor = np.random.randint(10, 21) / 10. # 随机因子
brightness_image = ImageEnhance.Brightness(color_image).enhance(random_factor) # 调整图像的亮度
random_factor = np.random.randint(10, 21) / 10. # 随机因子
contrast_image = ImageEnhance.Contrast(brightness_image).enhance(random_factor) # 调整图像对比度
random_factor = np.random.randint(0, 31) / 10. # 随机因子
redu_image = ImageEnhance.Sharpness(contrast_image).enhance(random_factor) # 调整图像锐度
img_save_path = "/xxxx/image/"
label_save_path = "/xxxx/label/"
redu_image.save(os.path.join(img_save_path, img_name.split('.')[0] + '_redu.jpg'))
label_src = label_path + img_name.split('.')[0] + '.txt'
label_dst = label_save_path + img_name.split('.')[0] + '_redu.txt'
shutil.copy(label_src, label_dst)
return None
def process(root_path, img_name, label_path):
# aj_contrast
aj_contrast(root_path, img_name, label_path)
# randomGaussian
randomGaussian(root_path, img_name, label_path)
# randomColor
randomColor(root_path, img_name, label_path)
if __name__ == '__main__':
image_path = "/xxxx/image/"
label_path = "/xxxx/label/"
imgs_file = sys.argv[1]
with open(imgs_file) as f:
for ln in f:
img_name = ln.rstrip('\n')
process(image_path, img_name, label_path)
上述代码是批量处理的,如果是单张处理,直接更改最后的几行代码即可
总结
本代码没有添加翻转等操作,这是因为该代码适用于目标检测数据集,目标检测数据集旋转时候,其对应的label也需要进行变换,旋转的数据增强见目标检测数据增强—-旋转
感谢阅读!