效果预览:
随机图片遮挡
def random_block(x: tf.Tensor, y: tf.Tensor) -> (tf.Tensor, tf.Tensor):
# 遮挡块和图片的比例
block_ratio = 0.1
# 遮挡块颜色
block_color = np.random.randint(64, 192)
# channel last
width, height = np.shape(x)[:2]
block_width, block_height = int(width * block_ratio), int(height * block_ratio)
block = np.full(shape=(block_width, block_height, 3), fill_value=block_color)
start_width_idx = np.random.randint(0, width - block_width)
start_height_idx = np.random.randint(0, height - block_height)
x[start_width_idx: start_width_idx + block_width, start_height_idx:start_height_idx + block_height,
:] = block
return x, y
# 这样使用该方法
dataset = dataset.map(lambda x, y: tf.cond(tf.random_uniform([], 0, 1) > 0.4,
lambda: tuple(tf.py_func(random_block, [x, y], [tf.uint8, y.dtype])),
lambda: (x, y)))
随机hsv
def color(x: tf.Tensor, label: tf.Tensor) -> (tf.Tensor, tf.Tensor):
x = tf.image.random_hue(x, 0.05)
x = tf.image.random_saturation(x, 0.6, 1.6)
x = tf.image.random_brightness(x, 0.2)
x = tf.image.random_contrast(x, 0.7, 1.3)
return x, label
高斯模糊(最蛋疼的方法)
def blur(x: tf.Tensor, label: tf.Tensor) -> (tf.Tensor, tf.Tensor):
def gaussian_kernel(size, sigma):
x_points = np.arange(-(size - 1) // 2, (size - 1) // 2 + 1, 1)
y_points = x_points[::-1]
xs, ys = np.meshgrid(x_points, y_points)
kernel = np.exp(-(xs ** 2 + ys ** 2) / (2 * sigma ** 2)) / (2 * np.pi * sigma ** 2)
return kernel / kernel.sum()
kernel = gaussian_kernel(size=5, sigma=2.5)
kernel = kernel[:, :, np.newaxis, np.newaxis]
x = tf.cast(x, tf.float32)
xr, xg, xb = tf.expand_dims(tf.expand_dims(x[:, :, 0], -1), 0), tf.expand_dims(
tf.expand_dims(x[:, :, 1], -1), 0), tf.expand_dims(tf.expand_dims(x[:, :, 2],
-1), 0)
xr_blur = tf.nn.conv2d(xr, kernel, strides=[1, 1, 1, 1], padding='SAME')
xg_blur = tf.nn.conv2d(xg, kernel, strides=[1, 1, 1, 1], padding='SAME')
xb_blur = tf.nn.conv2d(xb, kernel, strides=[1, 1, 1, 1], padding='SAME')
xrgb_blur = tf.concat([xr_blur, xg_blur, xb_blur], axis=3)
xrgb_blur = tf.clip_by_value(xrgb_blur, 0, 255)
xrgb_blur = tf.cast(tf.squeeze(xrgb_blur), tf.uint8)
return xrgb_blur, label
高斯模糊(使用tf.py_func
调用普通python方法)
def blur(x: tf.Tensor, label: tf.Tensor) -> (tf.Tensor, tf.Tensor):
sigmaX = (1.4 - 1.1) + np.random.random() * 1.1
sigmaY = (1.4 - 1.1) + np.random.random() * 1.1
blurred = cv2.GaussianBlur(x, ksize=(0, 0), sigmaX=sigmaX, sigmaY=sigmaY, borderType=cv2.BORDER_DEFAULT)
return blurred, label
# 然后在map时,这样随机高斯模糊处理:
dataset = dataset.map(lambda x, y: tf.cond(tf.random_uniform([], 0, 1) > 0.7,
lambda: tuple(tf.py_func(blur, [x, y], [tf.uint8, y.dtype])),
lambda: (x, y)))
高斯噪音
def noise(image: tf.Tensor, label: tf.Tensor) -> (tf.Tensor, tf.Tensor):
noise = tf.random_normal(dtype=tf.float32, shape=(img_size, img_size, 3), stddev=8.0, mean=0.0)
noise_img = tf.cast(image, tf.float32) + noise
noise_img = tf.clip_by_value(noise_img, 0, 255)
return tf.cast(noise_img, tf.uint8), label
图片旋转(使用tf.py_func
调用普通函数)
def random_rotate(x: tf.Tensor, y: tf.Tensor) -> (tf.Tensor, tf.Tensor):
from scipy import misc
angle = np.random.uniform(low=-10.0, high=10.0)
return misc.imrotate(x, angle, 'bicubic'), y
# map时,这样处理
dataset = dataset.map(lambda x, y: tf.cond(tf.random_uniform([], 0, 1) > 0.7,
lambda: tuple(tf.py_func(random_rotate, [x, y], [tf.uint8, y.dtype])),
lambda: (x, y)))
按概率随机增广图片
augmentations = [noise, color]
for f in augmentations:
dataset = dataset.map(
lambda x, y: tf.cond(tf.random_uniform([], 0, 1) > 0.7, lambda: f(x, y), lambda: (x, y)),
num_parallel_calls=4)