def scanline_error(tensor, shape): """ """ height, width, channels = shape value_shape = [height, width, 1] error_line = tf.maximum( basic([int(height * .75), 1], value_shape, distrib=ValueDistribution.exp) - .5, 0) error_swerve = tf.maximum( basic([int(height * .01), 1], value_shape, distrib=ValueDistribution.exp) - .5, 0) error_line *= error_swerve error_swerve *= 2 white_noise = basic([int(height * .75), 1], value_shape) white_noise = effects.blend(0, white_noise, error_swerve) error = error_line + white_noise y_index = effects.column_index(shape) x_index = (effects.row_index(shape) - tf.cast( effects.value_map(error, value_shape) * width * .025, tf.int32)) % width return tf.minimum( tf.gather_nd(tensor, tf.stack([y_index, x_index], 2)) + error_line * white_noise * 4, 1)
def glitch(tensor, shape, time=0.0, speed=1.0): """ Apply a glitch effect. :param Tensor tensor: :param list[int] shape: :return: Tensor """ height, width, channels = shape tensor = effects.normalize(tensor) base = multires(2, shape, time=time, speed=speed, distrib=ValueDistribution.simplex, octaves=random.randint(2, 5), spline_order=0, refract_range=random.random()) stylized = effects.normalize( effects.color_map(base, tensor, shape, horizontal=True, displacement=2.5)) jpegged = effects.color_map(base, stylized, shape, horizontal=True, displacement=2.5) if channels in (1, 3): jpegged = effects.jpeg_decimate(jpegged, shape) # Offset a single color channel separated = [stylized[:, :, i] for i in range(channels)] x_index = (effects.row_index(shape) + random.randint(1, width)) % width index = tf.cast(tf.stack([effects.column_index(shape), x_index], 2), tf.int32) channel = random.randint(0, channels - 1) separated[channel] = effects.normalize( tf.gather_nd(separated[channel], index) % random.random()) stylized = tf.stack(separated, 2) combined = effects.blend(tf.multiply(stylized, 1.0), jpegged, base) combined = effects.blend(tensor, combined, tf.maximum(base * 2 - 1, 0)) combined = effects.blend(combined, effects.pixel_sort(combined, shape), 1.0 - base) combined = tf.image.adjust_contrast(combined, 1.75) return combined
def glitch(tensor, shape): """ Apply a glitch effect. :param Tensor tensor: :param list[int] shape: :return: Tensor """ height, width, channels = shape tensor = effects.normalize(tensor) base = multires(2, shape, octaves=random.randint(2, 5), spline_order=0, refract_range=random.random()) stylized = effects.normalize( effects.color_map(base, tensor, shape, horizontal=True, displacement=2.5)) jpegged = effects.jpeg_decimate( effects.color_map(base, stylized, shape, horizontal=True, displacement=2.5), shape) # Offset a single color channel separated = [stylized[:, :, i] for i in range(channels)] x_index = (effects.row_index(shape) + random.randint(1, width)) % width index = tf.cast(tf.stack([effects.column_index(shape), x_index], 2), tf.int32) channel = random.randint(0, channels - 1) separated[channel] = effects.normalize( tf.gather_nd(separated[channel], index) % random.random()) channel = random.randint(0, channels - 1) top, _ = tf.nn.top_k(effects.value_map(tensor, shape), k=width) separated[channel] += top stylized = tf.stack(separated, 2) combined = effects.blend(tf.multiply(stylized, 1.0), jpegged, base) combined = effects.blend(tensor, combined, tf.maximum(base * 2 - 1, 0)) return combined
def vhs(tensor, shape, time=0.0, speed=1.0): """ Apply a bad VHS tracking effect. :param Tensor tensor: :param list[int] shape: :return: Tensor """ height, width, channels = shape # Generate scan noise scan_noise = basic( [int(height * .5) + 1, int(width * .05) + 1], [height, width, 1], time=time, speed=speed, spline_order=1, distrib=ValueDistribution.simplex) # Create horizontal offsets grad = basic([int(random.random() * 10) + 5, 1], [height, width, 1], time=time, speed=speed, distrib=ValueDistribution.simplex) grad = tf.maximum(grad - .5, 0) grad = tf.minimum(grad * 2, 1) x_index = effects.row_index(shape) x_index -= tf.squeeze( tf.cast(scan_noise * width * tf.square(grad), tf.int32)) x_index = x_index % width tensor = effects.blend(tensor, scan_noise, grad) identity = tf.stack([effects.column_index(shape), x_index], 2) tensor = tf.gather_nd(tensor, identity) return tensor
def vhs(tensor, shape): """ Apply a bad VHS tracking effect. :param Tensor tensor: :param list[int] shape: :return: Tensor """ height, width, channels = shape scan_noise = tf.reshape( basic( [int(height * .5) + 1, int(width * .01) + 1], [height, width, 1]), [height, width]) white_noise = basic( [int(height * .5) + 1, int(width * .1) + 1], [height, width, 1], spline_order=0) # Create horizontal offsets grad = tf.maximum( basic([int(random.random() * 10) + 5, 1], [height, width, 1]) - .5, 0) grad *= grad grad = tf.image.convert_image_dtype(grad, tf.float32, saturate=True) grad = effects.normalize(grad) grad = tf.reshape(grad, [height, width]) tensor = effects.blend_cosine(tensor, white_noise, tf.reshape(grad, [height, width, 1]) * .75) x_index = effects.row_index(shape) - tf.cast( grad * width * .125 + (scan_noise * width * .25 * grad * grad), tf.int32) identity = tf.stack([effects.column_index(shape), x_index], 2) % width tensor = tf.gather_nd(tensor, identity) tensor = tf.image.convert_image_dtype(tensor, tf.float32, saturate=True) return tensor
def values(freq, shape, distrib=ValueDistribution.normal, corners=False, mask=None, mask_inverse=False, spline_order=3, wavelet=False, time=0.0, speed=1.0): """ """ initial_shape = freq + [shape[-1]] if isinstance(distrib, int): distrib = ValueDistribution(distrib) elif isinstance(distrib, str): distrib = ValueDistribution[distrib] if isinstance(mask, int): mask = ValueMask(mask) elif isinstance(mask, str): mask = ValueMask[mask] if distrib == ValueDistribution.ones: tensor = tf.ones(initial_shape) elif distrib == ValueDistribution.mids: tensor = tf.ones(initial_shape) * .5 elif distrib == ValueDistribution.normal: tensor = tf.random_normal(initial_shape) elif distrib == ValueDistribution.uniform: tensor = tf.random_uniform(initial_shape) elif distrib == ValueDistribution.exp: tensor = tf.cast(tf.stack(np.random.exponential(size=initial_shape)), tf.float32) elif distrib == ValueDistribution.laplace: tensor = tf.cast(tf.stack(np.random.laplace(size=initial_shape)), tf.float32) elif distrib == ValueDistribution.lognormal: tensor = tf.cast(tf.stack(np.random.lognormal(size=initial_shape)), tf.float32) elif distrib == ValueDistribution.column_index: tensor = tf.expand_dims( tf.cast(effects.normalize(effects.column_index(initial_shape)), tf.float32), -1) * tf.ones(initial_shape, tf.float32) elif distrib == ValueDistribution.row_index: tensor = tf.expand_dims( tf.cast(effects.normalize(effects.row_index(initial_shape)), tf.float32), -1) * tf.ones(initial_shape, tf.float32) elif distrib == ValueDistribution.simplex: tensor = simplex.simplex(initial_shape, time=time, speed=speed) elif distrib == ValueDistribution.simplex_exp: tensor = tf.pow(simplex.simplex(initial_shape, time=time, speed=speed), 4) else: raise ValueError("%s (%s) is not a ValueDistribution" % (distrib, type(distrib))) if mask: atlas = None if mask == ValueMask.truetype: from noisemaker.glyphs import load_glyphs atlas = load_glyphs([15, 15, 1]) if not atlas: mask = ValueMask.numeric # Fall back to canned values channel_shape = freq + [1] mask_values, _ = masks.mask_values(mask, channel_shape, atlas=atlas, inverse=mask_inverse, time=time, speed=speed) tensor *= mask_values if wavelet: tensor = effects.wavelet(tensor, initial_shape) tensor = effects.resample(tensor, shape, spline_order=spline_order) if (not corners and (freq[0] % 2) == 0) or (corners and (freq[0] % 2) == 1): tensor = effects.offset(tensor, shape, x=int((shape[1] / freq[1]) * .5), y=int((shape[0] / freq[0]) * .5)) return tensor