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 _control(): shape = [SMALL_Y, SMALL_X, 1] control = generators.multires(shape=shape, freq=FREQ, octaves=OCTAVES, refract_range=.5) erode_kwargs = { "alpha": .025, "density": 40, "iterations": 20, "inverse": True, } iterations = 5 for i in range(iterations): control = effects.erode(control, shape, **erode_kwargs) control = effects.convolve(constants.ValueMask.conv2d_blur, control, shape) post_shape = [LARGE_Y, LARGE_X, 1] control = effects.resample(control, post_shape) iterations = 2 for i in range(iterations): control = effects.erode(control, post_shape, **erode_kwargs) control = effects.convolve(constants.ValueMask.conv2d_blur, control, post_shape) control = effects.convolve(constants.ValueMask.conv2d_sharpen, control, post_shape) control = effects.normalize(control) with tf.Session().as_default(): save(control, CONTROL_FILENAME)
def grime(tensor, shape): """ """ value_shape = [shape[0], shape[1], 1] mask = multires(5, value_shape, distrib="exp", octaves=8, refract_range=1.0, deriv=3, deriv_alpha=.5) dusty = effects.blend(tensor, .25, tf.square(mask) * .125) specks = basic( [int(shape[0] * .25), int(shape[1] * .25)], value_shape, distrib="exp", refract_range=.1) specks = 1.0 - tf.sqrt(effects.normalize(tf.maximum(specks - .5, 0.0))) dusty = effects.blend(dusty, basic([shape[0], shape[1]], value_shape), .125) * specks return effects.blend(tensor, dusty, mask)
def frame(tensor, shape, time=0.0, speed=1.0): """ """ half_shape = [int(shape[0] * .5), int(shape[1] * .5), shape[2]] half_value_shape = [half_shape[0], half_shape[1], 1] noise = multires(64, half_value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex, octaves=8) black = tf.zeros(half_value_shape) white = tf.ones(half_value_shape) mask = effects.singularity(None, half_value_shape, 1, dist_func=3, inverse=True) mask = effects.normalize(mask + noise * .005) mask = effects.blend_layers(tf.sqrt(mask), half_value_shape, 0.0125, white, black, black, black) faded = effects._downsample(tensor, shape, half_shape) faded = tf.image.adjust_brightness(faded, .1) faded = tf.image.adjust_contrast(faded, .75) faded = effects.light_leak(faded, half_shape, .125) faded = effects.vignette(faded, half_shape, 0.05, .75) edge_texture = white * .9 + effects.shadow(noise, half_value_shape, 1.0) * .1 out = effects.blend(faded, edge_texture, mask) out = effects.aberration(out, half_shape, .00666) out = grime(out, half_shape) out = tf.image.adjust_saturation(out, .5) out = tf.image.random_hue(out, .05) out = effects.resample(out, shape) out = scratches(out, shape) out = stray_hair(out, shape) return out
def false_color(tensor, shape, horizontal=False, displacement=.5, **basic_kwargs): """ """ clut = basic(2, shape, **basic_kwargs) return effects.normalize( effects.color_map(tensor, clut, shape, horizontal=horizontal, displacement=displacement))
def crt(tensor, shape, time=0.0, speed=1.0): """ Apply vintage CRT snow and scanlines. :param Tensor tensor: :param list[int] shape: """ height, width, channels = shape value_shape = [height, width, 1] # Horizontal scanlines scan_noise = tf.tile( basic([2, 1], [2, 1, 1], time=time, speed=speed, distrib=ValueDistribution.simplex, spline_order=0), [int(height * .125) or 1, width, 1]) scan_noise = effects.resample(scan_noise, value_shape) scan_noise = lens_warp(scan_noise, value_shape, time=time, speed=speed) tensor = effects.normalize( effects.blend(tensor, (tensor + scan_noise) * scan_noise, 0.05)) if channels == 3: tensor = effects.aberration(tensor, shape, .0075 + random.random() * .0075) tensor = tf.image.random_hue(tensor, .125) tensor = tf.image.adjust_saturation(tensor, 1.25) tensor = tf.image.adjust_contrast(tensor, 1.25) tensor = effects.vignette(tensor, shape, brightness=0, alpha=random.random() * .175) 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 false_color(tensor, shape, horizontal=False, displacement=.5, time=0.0, speed=1.0, **basic_kwargs): """ """ clut = basic(2, shape, time=time, speed=speed, distrib=ValueDistribution.simplex, **basic_kwargs) return effects.normalize( effects.color_map(tensor, clut, shape, horizontal=horizontal, displacement=displacement))
def grime(tensor, shape, time=0.0, speed=1.0): """ """ value_shape = [shape[0], shape[1], 1] mask = multires(5, value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex_exp, octaves=8, refract_range=1.0, refract_y_from_offset=True, deriv=3, deriv_alpha=.5) dusty = effects.blend(tensor, .25, tf.square(mask) * .125) specks = basic( [int(shape[0] * .25), int(shape[1] * .25)], value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex_exp, refract_range=.1) specks = 1.0 - tf.sqrt(effects.normalize(tf.maximum(specks - .5, 0.0))) dusty = effects.blend( dusty, basic([shape[0], shape[1]], value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex), .125) * specks return effects.blend(tensor, dusty, mask)
def spatter(tensor, shape, time=0.0, speed=1.0): """ """ value_shape = [shape[0], shape[1], 1] # Generate a smear smear = multires(random.randint(2, 4), value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex_exp, ridges=True, octaves=6, spline_order=3) smear = effects.warp( smear, value_shape, [random.randint(2, 3), random.randint(1, 3)], octaves=random.randint(1, 2), displacement=1.0 + random.random(), spline_order=3, time=time, speed=speed) # Add spatter dots smear = tf.maximum( smear, multires(random.randint(25, 50), value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex_exp, post_brightness=-.25, post_contrast=4, octaves=4, spline_order=1)) smear = tf.maximum( smear, multires(random.randint(200, 250), value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex_exp, post_brightness=-.25, post_contrast=4, octaves=4, spline_order=1)) # Remove some of it smear = tf.maximum( 0.0, smear - multires(random.randint(2, 3), value_shape, time=time, speed=speed, distrib=ValueDistribution.simplex_exp, ridges=True, octaves=3, spline_order=2)) # if shape[2] == 3: splash = tf.image.random_hue( tf.ones(shape) * tf.stack([.875, 0.125, 0.125]), .5) else: splash = tf.zeros(shape) return effects.blend_layers(effects.normalize(smear), shape, .005, tensor, splash)
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
def basic(freq, shape, ridges=False, sin=0.0, wavelet=False, spline_order=3, distrib=ValueDistribution.normal, corners=False, mask=None, mask_inverse=False, lattice_drift=0.0, rgb=False, hue_range=.125, hue_rotation=None, saturation=1.0, hue_distrib=None, brightness_distrib=None, brightness_freq=None, saturation_distrib=None, speed=1.0, time=0.0, **post_process_args): """ Generate a single layer of scaled noise. .. image:: images/gaussian.jpg :width: 1024 :height: 256 :alt: Noisemaker example output (CC0) :param int|list[int] freq: Base noise frequency. Int, or list of ints for each spatial dimension :param list[int]: Shape of noise. For 2D noise, this is [height, width, channels] :param bool ridges: "Crease" at midpoint values: (1 - abs(n * 2 - 1)) :param float sin: Apply sin function to noise basis :param bool wavelet: Maybe not wavelets this time? :param int spline_order: Spline point count. 0=Constant, 1=Linear, 2=Cosine, 3=Bicubic :param int|str|ValueDistribution distrib: Type of noise distribution. See :class:`ValueDistribution` enum :param bool corners: If True, pin values to corners instead of image center :param None|ValueMask mask: :param bool mask_inverse: :param float lattice_drift: Push away from underlying lattice :param bool rgb: Disable HSV :param float hue_range: HSV hue range :param float|None hue_rotation: HSV hue bias :param float saturation: HSV saturation :param None|int|str|ValueDistribution hue_distrib: Override ValueDistribution for hue :param None|int|str|ValueDistribution saturation_distrib: Override ValueDistribution for saturation :param None|int|str|ValueDistribution brightness_distrib: Override ValueDistribution for brightness :param None|int|list[int] brightness_freq: Override frequency for brightness :param float speed: Displacement range for Z/W axis (simplex only) :param float time: Time argument for Z/W axis (simplex only) :return: Tensor Additional keyword args will be sent to :py:func:`noisemaker.effects.post_process` """ if isinstance(freq, int): freq = effects.freq_for_shape(freq, shape) tensor = values(freq, shape, distrib=distrib, corners=corners, mask=mask, mask_inverse=mask_inverse, spline_order=spline_order, wavelet=wavelet, speed=speed, time=time) if lattice_drift: displacement = lattice_drift / min(freq[0], freq[1]) tensor = effects.refract(tensor, shape, time=time, speed=speed, displacement=displacement, warp_freq=freq, spline_order=spline_order) tensor = effects.post_process(tensor, shape, freq, time=time, speed=speed, spline_order=spline_order, rgb=rgb, **post_process_args) if shape[-1] == 3 and not rgb: if hue_distrib: h = tf.squeeze( values(freq, [shape[0], shape[1], 1], distrib=hue_distrib, corners=corners, mask=mask, mask_inverse=mask_inverse, spline_order=spline_order, wavelet=wavelet, time=time, speed=speed)) else: if hue_rotation is None: hue_rotation = tf.random_normal([]) h = (tensor[:, :, 0] * hue_range + hue_rotation) % 1.0 if saturation_distrib: s = tf.squeeze( values(freq, [shape[0], shape[1], 1], distrib=saturation_distrib, corners=corners, mask=mask, mask_inverse=mask_inverse, spline_order=spline_order, wavelet=wavelet, time=time, speed=speed)) else: s = tensor[:, :, 1] s *= saturation if brightness_distrib or brightness_freq: if isinstance(brightness_freq, int): brightness_freq = effects.freq_for_shape( brightness_freq, shape) v = tf.squeeze( values(brightness_freq or freq, [shape[0], shape[1], 1], distrib=brightness_distrib or ValueDistribution.normal, corners=corners, mask=mask, mask_inverse=mask_inverse, spline_order=spline_order, wavelet=wavelet, time=time, speed=speed)) else: v = tensor[:, :, 2] if ridges and spline_order: # ridges don't work well when not interpolating values v = effects.crease(v) if sin: v = effects.normalize(tf.sin(sin * v)) tensor = tf.image.hsv_to_rgb([tf.stack([h, s, v], 2)])[0] elif ridges and spline_order: tensor = effects.crease(tensor) if sin and rgb: tensor = tf.sin(sin * tensor) return tensor