from enum import Enum import os import numpy as np import librosa import math from scipy.interpolate import interp1d import matplotlib.pyplot as plt import random import shutil import subprocess import tempfile import textwrap import click import tensorflow as tf from PIL import Image, ImageEnhance from noisemaker.composer import EFFECT_PRESETS, GENERATOR_PRESETS, reload_presets from noisemaker.constants import ColorSpace, ValueDistribution from noisemaker.presets import PRESETS import noisemaker.ai as ai import noisemaker.dreamer as dreamer import noisemaker.cli as cli import noisemaker.generators as generators import noisemaker.effects as effects import noisemaker.util as util import noisemaker.value as value MAX_SEED_VALUE = 2 ** 32 - 1 os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' reload_presets(PRESETS) @click.group(context_settings=cli.CLICK_CONTEXT_SETTINGS) def main(): pass def anlyzeSound(audio_input_file): # Assuming that into "generated" directoruy U've already create "project_name" subfolder #audio_input_file = '/home/lalo/data/studio_grafica/deforum/stars_clip_r2.wav' #audio_input_file = '/home/lalo/data/studio_suono/ardourprojects/space/export/star_r1_sessione_20240310_msub07.wav' #audio_input_file = '/home/lalo/data/studio_suono/spx/231104_001_m01.wav' #audio_input_file = '/home/lalo/data/studio_grafica/deforum/eucrasy_r1_sample.wav' #audio_input_file = '/home/lalo/data/studio_grafica/deforum/eucrasy_r1.wav' #audio_input_file = '/home/lalo/data/studio_grafica/deforum/eucrasy_short_r1.wav' #audio_input_file = '/home/lalo/data/studio_suono/231014_002_mastered_r2_clip.WAV' #audio_input_file = 'C:/Users/LucaConte/Music/lc_music/wilson_r1_mm.wav' # Store the sampling rate as `sr` fps = 24 flength = 22050//fps #audio frame size is 22050/30=735 wave, sr = librosa.load(audio_input_file) rms = librosa.feature.rms(y=wave, frame_length=flength, hop_length=flength) #rms = librosa.feature.rms(y=wave, frame_length=735, hop_length=735) cent = librosa.feature.spectral_centroid(y=wave, sr=sr,n_fft=flength, hop_length=flength) zcr = librosa.feature.zero_crossing_rate(y=wave, frame_length=flength, hop_length=flength) duration = int(math.ceil(librosa.get_duration(y=wave, sr=sr))) #frames = duration * fps #:w # sr.len /22050 = duration # rms.len * 30 = duration # rms[i] mi da la potenza media del frame iesimo #generateSoundVariations("bubble-machine", 3793866858, rms,5000,7500) #generateSoundVariations("sands-of-time", 2226183906, rms,-1,2500) #generateSoundVariations("sands-of-time", 2226183906, rms,2500,5000) #generateSoundVariations("sands-of-time", 2226183906, rms,5000,7500) #generateSoundVariations("sands-of-time", 2226183906, rms,7500,10000) #generateSoundVariations("sands-of-time", 2226183906, rms,10000,10333) #generateSamples() #postprocessBrightness("/tmp/",cent, 8316,10000) return rms, cent, zcr def width_option(default=1024, **attrs): attrs.setdefault("help", "Output width, in pixels") return int_option("--width", default=default, **attrs) #gli estremi frame start e frame stop sono esclusi # python sampler.py genframes --width 666 --height 666 --preset bubble-machine --framestart 1 --framestop 55 @main.command() @click.option('--width', required=True, type=int, default=1024) @click.option('--height', required=True, type=int, default=1024) @click.option('--seed', required=False, type=int, default=None) @click.option('--out-dir', required=True, type=str, default=tempfile.gettempdir()) @click.option('--framestart', required=False, type=int, default=1) @click.option('--framestop', required=False, type=int, default=-1) @click.option('--audiofile', required=True, type=str, default='./dummy.wav') @click.option('--preset', type=click.Choice(["random"] + sorted(GENERATOR_PRESETS))) @click.pass_context def genframes(ctx,width, height,preset, seed, framestart, framestop, audiofile, out_dir): rms, centroids, zcr = anlyzeSound(audiofile) if not seed: seed = random.randint(1, MAX_SEED_VALUE) print(f"(total frames: {len(rms[0])}) (framestart: {framestart}) (framestop: {framestop})") time_dividend =500 s = interp1d([min(rms[0]), max(rms[0])], [0, 0.9]) trms=rms[0] mean = np.mean(trms) if framestop<0: framestop = len(rms[0]) for frame in range(framestart, framestop): try: speed=abs(mean - float(format(trms[frame], '.3f'))) #speed=float(format(trms[frame], '.3f')) #print(f"(speed: {speed}) (trms: {trms[frame]}) )") time = (float)((frame % time_dividend)/time_dividend) filename = out_dir+ '/' + preset + "_" + str(seed)+ "_" + str(frame).zfill(10) +".png" print(f"(speed: {speed}) (time: {time}) (filename: {filename})") generate(1080,1080,time,speed,seed,filename,False,False,False,False,False,False,"",False,False,preset) #generate(1024,1024,ftime,1,seed,"/tmp/" + str(frame).zfill(10) +".png",False,False,False,False,False,False,"",False,False,preset_name) #generate(1024,1024,0.0,ftime,seed,"/tmp/" + str(frame).zfill(10) +"_" + preset_name + ".png",False,False,False,False,False,False,"",False,False,preset_name) except Exception as e: print(f"Exception {e} on Preset: {preset}") continue @main.command() @click.pass_context def testpillow(ctx): image = Image.open('/tmp/the-inward-spiral_3917354306_0_0.23284526795328386.png') brightness_factor = 3.5 # Increase brightness by 50% enhancer = ImageEnhance.Brightness(image) brightened_image = enhancer.enhance(brightness_factor) contrast_factor = 4.2 # Increase contrast by 20% enhancer = ImageEnhance.Contrast(image) contrasted_image = enhancer.enhance(contrast_factor) brightened_image.save("/tmp/alt/brightened_image.png") contrasted_image.save("/tmp/alt/contrasted_image.png") def postprocessBrightness(srcdir,centroids,framemin=0,framemax=9999999999): c = interp1d([centroids.min(), centroids.max()], [1, 4.5]) items = os.listdir(srcdir) sorted_items = sorted(items) for f in sorted_items: if f.endswith(".png"): frame = int(f.split("_")[-1].split(".")[0])@click.command(context_settings=dict( ignore_unknown_options=True, )) if frame >= framemin and frame < framemax: image = Image.open(srcdir+f) enhancer = ImageEnhance.Brightness(image) brightened_image = enhancer.enhance(c(centroids[0][frame])) print(f'File: {f}') brightened_image.save(srcdir+"b_"+f) def testCombinedVariations(preset_name): seed = random.randint(1, MAX_SEED_VALUE) times = 0 for speed in range(0,999,1): try: if(times == 0): times = random.randint(1, 30) time = round(random.uniform(0, 1), 1) fspeed = (float)(speed/100) filename = "/tmp/"+ preset_name + "_" + str(seed)+ "_" + str(speed).zfill(10) +".png" print(f"(speed: {speed}) (time: {time}) (times: {times}) (filename: {filename})") times -= 1 #generate(600,600,time,fspeed,seed,filename,False,False,False,False,False,False,"",False,False,preset_name) except Exception as e: print(f"Exception on Preset: {preset_name}") continue def generateSpeedVariations(preset_name): seed = random.randint(1, MAX_SEED_VALUE) for speed in range(0,999,1): try: generate(600,600,0.1,speed,seed,"/tmp/"+ preset_name + "_" + str(seed)+ "_" + str(speed).zfill(10) +".png",False,False,False,False,False,False,"",False,False,preset_name) except Exception as e: print(f"Exception on Preset: {preset_name}") continue @main.command() @click.option('--iterations', required=False, type=int, default=100) @click.option('--preset', type=click.Choice(["random"] + sorted(GENERATOR_PRESETS))) @click.pass_context def gentimevariations(ctx,preset,iterations): seed = random.randint(1, MAX_SEED_VALUE) speed = random.random() for time in range(0, iterations, 1): try: ftime = (float)(time/iterations) print(str(ftime)) filename = tempfile.gettempdir() + "/" + preset+ "_" + str(seed) + "_" + str(time) + "_" + str(speed) + ".png" generate(600,600,ftime,speed,seed, filename,False,False,False,False,False,False,"",False,False,preset) except Exception as e: print(f"Exception on Preset: {preset}") continue @main.command() @click.pass_context def gensamples(ctx): for preset_name, preset_data in PRESETS().items(): try: seed = random.randint(1, MAX_SEED_VALUE) time = random.random() speed = random.random() filename = tempfile.gettempdir() + "/" + preset_name + "_" + str(seed) + "_" + str(time)+ "_" + str(speed) + ".png" print(f"Going to generate: {filename}") generate(1024, 1024, time, speed, seed, filename , False, False, False, False, False, False, "", False, False, preset_name) except Exception as e: print(f"Exception on Preset: {preset_name}") continue @main.command() @click.option('--iterations', required=False, type=int, default=10) @click.option('--preset', type=click.Choice(["random"] + sorted(GENERATOR_PRESETS))) @click.pass_context def genseedsvariations(ctx,preset,iterations): for i in range(iterations): try: seed = random.randint(1, MAX_SEED_VALUE) time = random.random() speed = random.random() filename = tempfile.gettempdir() + "/" + preset + "_" + str(seed) + "_" + str(time) + "_" + str( speed) + ".png" print(f"Going to generate: {filename}") generate(1024, 1024, time, speed, seed, filename, False, False, False, False, False, False, "", False, False, preset) except Exception as e: print(f"Exception on Preset: {preset}") continue def generate(width, height, time, speed, seed, filename, with_alpha, with_supersample, with_fxaa, with_ai, with_upscale, with_alt_text, stability_model, debug_print, debug_out, preset_name): if not seed: seed = random.randint(1, MAX_SEED_VALUE) value.set_seed(seed) reload_presets(PRESETS) if preset_name == "random": preset_name = list(GENERATOR_PRESETS)[random.randint(0, len(GENERATOR_PRESETS) - 1)] preset = GENERATOR_PRESETS[preset_name] if debug_print or debug_out: debug_text = _debug_print(seed, preset, with_alpha, with_supersample, with_fxaa, with_ai, with_upscale, stability_model) if debug_print: for line in debug_text: print(line) if debug_out is not None: with open(debug_out, 'w') as fh: for line in debug_text: fh.write(line + "\n") try: preset.render(seed, shape=[height, width, None], time=time, speed=speed, filename=filename, with_alpha=with_alpha, with_supersample=with_supersample, with_fxaa=with_fxaa, with_ai=with_ai, with_upscale=with_upscale, stability_model=stability_model) except Exception as e: util.logger.error(f"preset.render() failed: {e}\nSeed: {seed}\nArgs: {preset.__dict__}") raise if preset.ai_success: print(f"{preset_name} vs. {preset.ai_settings['model']} (seed: {seed})") else: print(f"{preset_name} (seed: {seed})") if with_alt_text: print(ai.describe(preset.name.replace('-', ' '), preset.ai_settings.get("prompt"), filename)) def _debug_print(seed, preset, with_alpha, with_supersample, with_fxaa, with_ai, with_upscale, stability_model): first_column = ["Layers:"] if preset.flattened_layers: first_column.append(" - Lineage (by newest):") if not preset.flattened_layers: first_column.append(" - None") for parent in reversed(preset.flattened_layers): first_column.append(f" - {parent}") first_column.append("") first_column.append(" - Effects (by newest):") if not preset.final_effects and not with_ai and not preset.post_effects: first_column.append(" - None") first_column.append("") if preset.final_effects: first_column.append(" - Final Pass:") for effect in reversed(preset.final_effects): if callable(effect): first_column.append(f" - {effect.func.__name__.replace('_', ' ')}") else: first_column.append(f" - {effect.name.replace('_', ' ').replace('-', ' ')}") first_column.append("") if with_ai: first_column.append(f" - AI Settings:") for (k, v) in sorted(preset.ai_settings.items()): if stability_model and k == 'model': v = stability_model for i, line in enumerate(textwrap.wrap(f"{k.replace('_', ' ')}: {v}", 42)): if i == 0: first_column.append(f" - {line}") else: first_column.append(f" {line}") first_column.append("") if preset.post_effects or with_ai: first_column.append(" - Post Pass:") if with_ai: first_column.append(" - stable diffusion") for effect in reversed(preset.post_effects): if callable(effect): first_column.append(f" - {effect.func.__name__.replace('_', ' ')}") else: first_column.append(f" - {effect.name.replace('_', ' ').replace('-', ' ')}") first_column.append("") if preset.octave_effects: first_column.append(" - Per-Octave Pass:") for effect in reversed(preset.octave_effects): if callable(effect): first_column.append(f" - {effect.func.__name__.replace('_', ' ')}") else: first_column.append(f" - {effect.name.replace('_', ' ').replace('-', ' ')}") first_column.append("") first_column.append("Canvas:") first_column.append(f" - seed: {seed}") first_column.append(f" - with alpha: {with_alpha}") first_column.append(f" - with supersample: {with_supersample}") first_column.append(f" - with fxaa: {with_fxaa}") first_column.append(f" - with upscale: {with_upscale}") first_column.append("") second_column = ["Settings:"] for (k, v) in sorted(preset.settings.items()): if isinstance(v, Enum): second_column.append(f" - {k.replace('_', ' ')}: {v.name.replace('_', ' ')}") elif isinstance(v, float): second_column.append(f" - {k.replace('_', ' ')}: {round(v, 3)}") else: second_column.append(f" - {k.replace('_', ' ')}: {v}") second_column.append("") out = [] for i in range(max(len(first_column), len(second_column))): if i < len(first_column): first = first_column[i] else: first = "" if i < len(second_column): second = second_column[i] else: second = "" out.append(f"{first:50} {second}") return out def apply(ctx, seed, filename, no_resize, with_fxaa, time, speed, preset_name, input_filename): if not seed: seed = random.randint(1, MAX_SEED_VALUE) value.set_seed(seed) reload_presets(PRESETS) input_shape = util.shape_from_file(input_filename) input_shape[2] = min(input_shape[2], 3) tensor = tf.image.convert_image_dtype(util.load(input_filename, channels=input_shape[2]), dtype=tf.float32) if preset_name == "random": preset_name = list(EFFECT_PRESETS)[random.randint(0, len(EFFECT_PRESETS) - 1)] print(f"{preset_name} (seed: {seed})") preset = EFFECT_PRESETS[preset_name] if no_resize: shape = input_shape else: shape = [1024, 1024, input_shape[2]] tensor = effects.square_crop_and_resize(tensor, input_shape, shape[0]) try: preset.render(seed=seed, tensor=tensor, shape=shape, with_fxaa=with_fxaa, time=time, speed=speed, filename=filename) except Exception as e: util.logger.error(f"preset.render() failed: {e}\nSeed: {seed}\nArgs: {preset.__dict__}") raise def animate(ctx, width, height, seed, effect_preset, filename, save_frames, frame_count, watermark, preview_filename, with_alt_text, with_supersample, with_fxaa, preset_name): if seed is None: seed = random.randint(1, MAX_SEED_VALUE) value.set_seed(seed) reload_presets(PRESETS) if preset_name == 'random': preset_name = list(GENERATOR_PRESETS)[random.randint(0, len(GENERATOR_PRESETS) - 1)] if effect_preset == 'random': effect_preset = list(EFFECT_PRESETS)[random.randint(0, len(EFFECT_PRESETS) - 1)] if effect_preset: print(f"{preset_name} vs. {effect_preset} (seed: {seed})") else: print(f"{preset_name} (seed: {seed})") preset = GENERATOR_PRESETS[preset_name] caption = None with tempfile.TemporaryDirectory() as tmp: for i in range(frame_count): frame_filename = f'{tmp}/{i:04d}.png' common_params = ['--seed', str(seed), '--time', f'{i/frame_count:0.4f}', '--filename', frame_filename] extra_params = [] if with_alt_text and i == 0: extra_params = ['--with-alt-text'] if with_supersample: extra_params += ['--with-supersample'] if with_fxaa: extra_params += ['--with-fxaa'] output = subprocess.check_output(['noisemaker', 'generate', preset_name, '--speed', str(_use_reasonable_speed(preset, frame_count)), '--height', str(height), '--width', str(width)] + common_params + extra_params, universal_newlines=True).strip().split("\n") if with_alt_text and i == 0: if len(output) == 6: # Useless extra crap that Tensorflow on Apple Silicon spews to stdout print(output[2]) else: print(output[1]) if effect_preset: extra_params = [] if with_fxaa: extra_params += ['--with-fxaa'] util.check_call(['noisemaker', 'apply', effect_preset, frame_filename, '--no-resize', '--speed', str(_use_reasonable_speed(EFFECT_PRESETS[effect_preset], frame_count))] + common_params + extra_params) if save_frames: shutil.copy(frame_filename, save_frames) if watermark: util.watermark(watermark, frame_filename) if preview_filename and i == 0: shutil.copy(frame_filename, preview_filename) if filename.endswith(".mp4"): util.check_call(["ffmpeg", "-framerate", "30", "-i", f"{tmp}/%04d.png", "-s", "1024x1024", "-c:v", "libx264", "-preset", "veryslow", "-crf", "15", "-pix_fmt", "yuv420p", "-b:v", "8000k", "-bufsize", "16000k", filename]) else: util.magick(f'{tmp}/*png', filename) @main.command(help="Blend a directory of .png or .jpg images") @cli.input_dir_option(required=True) @cli.filename_option(default="collage.png") @click.option("--control-filename", help="Control image filename (optional)") @cli.time_option() @click.option('--speed', help="Animation speed", type=float, default=0.25) @cli.seed_option() @click.pass_context def mashup(ctx, input_dir, filename, control_filename, time, speed, seed): filenames = [] for root, _, files in os.walk(input_dir): for f in files: if f.endswith(('.png', '.jpg')): filenames.append(os.path.join(root, f)) collage_count = min(random.randint(4, 6), len(filenames)) collage_images = [] for i in range(collage_count + 1): index = random.randint(0, len(filenames) - 1) input_filename = os.path.join(input_dir, filenames[index]) collage_input = tf.image.convert_image_dtype(util.load(input_filename, channels=3), dtype=tf.float32) collage_images.append(collage_input) if control_filename: control_shape = util.shape_from_file(control_filename) control = tf.image.convert_image_dtype(util.load(control_filename, channels=control_shape[2]), dtype=tf.float32) else: control = collage_images.pop() shape = tf.shape(control) # All images need to be the same size! control = value.value_map(control, shape, keepdims=True) value.set_seed(seed) base = generators.basic(freq=random.randint(2, 5), shape=shape, lattice_drift=random.randint(0, 1), hue_range=random.random(), time=time, speed=speed) value_shape = value.value_shape(shape) control = value.convolve(kernel=effects.ValueMask.conv2d_blur, tensor=control, shape=value_shape) tensor = effects.blend_layers(control, shape, random.random() * .5, *collage_images) tensor = value.blend(tensor, base, .125 + random.random() * .125) tensor = effects.bloom(tensor, shape, alpha=.25 + random.random() * .125) tensor = effects.shadow(tensor, shape, alpha=.25 + random.random() * .125, reference=control) tensor = tf.image.adjust_brightness(tensor, .1) tensor = tf.image.adjust_contrast(tensor, 1.5) util.save(tensor, filename) print('mashup') def _use_reasonable_speed(preset, frame_count): """Return a reasonable speed parameter for the given animation length.""" return preset.settings.get("speed", 0.25) * (frame_count / 50.0) def dream(width, height, filename): name, prompt, description = dreamer.dream(width, height, filename=filename) print(name) print(prompt) print(description) if __name__ == "__main__": main() #testPillow() #postprocessBrightness('/tmp/')