From 1fb7b50be7505c077cfc81d69d8d8d2a656698fd Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Fri, 11 Nov 2022 10:30:44 -0500 Subject: [PATCH 1/2] Revert "enhance outcropping with ability to direct contents of new regions" This reverts commit 8aa94d5774af2c392ba70ba3f15baaa4e0afe481. --- docs/features/OUTPAINTING.md | 15 --------------- ldm/generate.py | 24 ++++++++---------------- ldm/invoke/args.py | 5 ----- ldm/invoke/restoration/outcrop.py | 4 ++-- scripts/invoke.py | 14 ++++---------- 5 files changed, 14 insertions(+), 48 deletions(-) diff --git a/docs/features/OUTPAINTING.md b/docs/features/OUTPAINTING.md index 380467d571..122c732605 100644 --- a/docs/features/OUTPAINTING.md +++ b/docs/features/OUTPAINTING.md @@ -92,21 +92,6 @@ The new image is larger than the original (576x704) because 64 pixels were added to the top and right sides. You will need enough VRAM to process an image of this size. -#### Outcropping non-InvokeAI images - -You can outcrop an arbitrary image that was not generated by InvokeAI, -but your results will vary. The `inpainting-1.5` model is highly -recommended, but if not feasible, then you may be able to improve the -output by conditioning the outcropping with a text prompt that -describes the scene using the `--new_prompt` argument: - -```bash -invoke> !fix images/vacation.png --outcrop top 128 --new_prompt "family vacation" -``` - -You may also provide a different seed for outcropping to use by passing -`-S`. A seed of "0" will generate a new random seed. - A number of caveats: 1. Although you can specify any pixel values, they will be rounded up to the diff --git a/ldm/generate.py b/ldm/generate.py index 4cabeb6810..aa4bd7fc8e 100644 --- a/ldm/generate.py +++ b/ldm/generate.py @@ -561,22 +561,18 @@ class Generate: ): # retrieve the seed from the image; seed = None + image_metadata = None prompt = None args = metadata_from_png(image_path) - if opt.seed is not None: - seed = opt.seed - elif args.seed >= 0: - seed = args.seed + seed = args.seed + prompt = args.prompt or '' + if seed == 0: + seed = random.randrange(0, np.iinfo(np.uint32).max) + opt.seed = seed + print(f'>> generated new seed {seed} and prompt "{prompt}" for {image_path}') else: - seed = random.randrange(0, np.iinfo(np.uint32).max) - - if opt.prompt is not None: - prompt = opt.prompt - else: - prompt = args.prompt - - print(f'>> using seed {seed} and prompt "{prompt}" for {image_path}') + print(f'>> retrieved seed {seed} and prompt "{prompt}" from {image_path}') # try to reuse the same filename prefix as the original file. # we take everything up to the first period @@ -623,10 +619,6 @@ class Generate: extend_instructions[direction]=int(pixels) except ValueError: print(f'** invalid extension instruction. Use ..., as in "top 64 left 128 right 64 bottom 64"') - - opt.seed = seed - opt.prompt = prompt - if len(extend_instructions)>0: restorer = Outcrop(image,self,) return restorer.process ( diff --git a/ldm/invoke/args.py b/ldm/invoke/args.py index 5a2d7ae97c..8e0d641870 100644 --- a/ldm/invoke/args.py +++ b/ldm/invoke/args.py @@ -864,11 +864,6 @@ class Args(object): default=32, help='When outpainting, the tile size to use for filling outpaint areas', ) - postprocessing_group.add_argument( - '--new_prompt', - type=str, - help='Change the text prompt applied during postprocessing (default, use original generation prompt)', - ) postprocessing_group.add_argument( '-ft', '--facetool', diff --git a/ldm/invoke/restoration/outcrop.py b/ldm/invoke/restoration/outcrop.py index ac0bf41b9e..1a0aaf2c8f 100644 --- a/ldm/invoke/restoration/outcrop.py +++ b/ldm/invoke/restoration/outcrop.py @@ -32,8 +32,8 @@ class Outcrop(object): image_callback(img,preferred_seed,use_prefix=prefix,**kwargs) result= self.generate.prompt2image( - opt.prompt, - seed = opt.seed if opt.seed else orig_opt.seed, + orig_opt.prompt, + seed = orig_opt.seed if orig_opt.seed>0 else opt.seed, sampler = self.generate.sampler, steps = opt.steps, cfg_scale = opt.cfg_scale, diff --git a/scripts/invoke.py b/scripts/invoke.py index 1c1d44dd16..25917f7030 100755 --- a/scripts/invoke.py +++ b/scripts/invoke.py @@ -282,7 +282,7 @@ def main_loop(gen, opt): filename = f'{prefix}.{use_prefix}.{seed}.png' tm = opt.text_mask[0] th = opt.text_mask[1] if len(opt.text_mask)>1 else 0.5 - formatted_dream_prompt = f'!mask {opt.input_file_path} -tm {tm} {th}' + formatted_dream_prompt = f'!mask {opt.prompt} -tm {tm} {th}' path = file_writer.save_image_and_prompt_to_png( image = image, dream_prompt = formatted_dream_prompt, @@ -322,7 +322,7 @@ def main_loop(gen, opt): tool = re.match('postprocess:(\w+)',opt.last_operation).groups()[0] add_postprocessing_to_metadata( opt, - opt.input_file_path, + opt.prompt, filename, tool, formatted_dream_prompt, @@ -620,16 +620,10 @@ def do_textmask(gen, opt, callback): ) def do_postprocess (gen, opt, callback): - file_path = opt.prompt # treat the prompt as the file pathname - if opt.new_prompt is not None: - opt.prompt = opt.new_prompt - else: - opt.prompt = None - + file_path = opt.prompt # treat the prompt as the file pathname if os.path.dirname(file_path) == '': #basename given file_path = os.path.join(opt.outdir,file_path) - opt.input_file_path = file_path tool=None if opt.facetool_strength > 0: tool = opt.facetool @@ -719,7 +713,7 @@ def prepare_image_metadata( elif len(prior_variations) > 0: formatted_dream_prompt = opt.dream_prompt_str(seed=first_seed) elif operation == 'postprocess': - formatted_dream_prompt = '!fix '+opt.dream_prompt_str(seed=seed,prompt=opt.input_file_path) + formatted_dream_prompt = '!fix '+opt.dream_prompt_str(seed=seed) else: formatted_dream_prompt = opt.dream_prompt_str(seed=seed) return filename,formatted_dream_prompt From 78f7bef1a3f42bb6055725c11785eb4e57b988eb Mon Sep 17 00:00:00 2001 From: Lincoln Stein Date: Fri, 11 Nov 2022 10:30:44 -0500 Subject: [PATCH 2/2] Revert "enable outcropping of random JPG/PNG images" This reverts commit 48aa6416dc194d0caf4ddff988d953a42dc585b1. --- ldm/generate.py | 13 ++++++------- ldm/invoke/generator/base.py | 2 +- ldm/invoke/prompt_parser.py | 2 +- ldm/invoke/restoration/outcrop.py | 5 ++--- scripts/invoke.py | 7 ++----- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/ldm/generate.py b/ldm/generate.py index aa4bd7fc8e..55cd5c5435 100644 --- a/ldm/generate.py +++ b/ldm/generate.py @@ -566,13 +566,12 @@ class Generate: args = metadata_from_png(image_path) seed = args.seed - prompt = args.prompt or '' - if seed == 0: - seed = random.randrange(0, np.iinfo(np.uint32).max) - opt.seed = seed - print(f'>> generated new seed {seed} and prompt "{prompt}" for {image_path}') - else: - print(f'>> retrieved seed {seed} and prompt "{prompt}" from {image_path}') + prompt = args.prompt + print(f'>> retrieved seed {seed} and prompt "{prompt}" from {image_path}') + + if not seed: + print('* Could not recover seed for image. Replacing with 42. This will not affect image quality') + seed = 42 # try to reuse the same filename prefix as the original file. # we take everything up to the first period diff --git a/ldm/invoke/generator/base.py b/ldm/invoke/generator/base.py index 719d08c7c0..3c6eca08a2 100644 --- a/ldm/invoke/generator/base.py +++ b/ldm/invoke/generator/base.py @@ -63,7 +63,7 @@ class Generator(): **kwargs ) results = [] - seed = seed if seed is not None and seed > 0 else self.new_seed() + seed = seed if seed is not None else self.new_seed() first_seed = seed seed, initial_noise = self.generate_initial_noise(seed, width, height) diff --git a/ldm/invoke/prompt_parser.py b/ldm/invoke/prompt_parser.py index 42c83188aa..3dbcc1bb4b 100644 --- a/ldm/invoke/prompt_parser.py +++ b/ldm/invoke/prompt_parser.py @@ -636,7 +636,7 @@ def split_weighted_subprompts(text, skip_normalize=False)->list: weight_sum = sum(map(lambda x: x[1], parsed_prompts)) if weight_sum == 0: print( - "* Warning: Subprompt weights add up to zero. Discarding and using even weights instead.") + "Warning: Subprompt weights add up to zero. Discarding and using even weights instead.") equal_weight = 1 / max(len(parsed_prompts), 1) return [(x[0], equal_weight) for x in parsed_prompts] return [(x[0], x[1] / weight_sum) for x in parsed_prompts] diff --git a/ldm/invoke/restoration/outcrop.py b/ldm/invoke/restoration/outcrop.py index 1a0aaf2c8f..b5d42250c5 100644 --- a/ldm/invoke/restoration/outcrop.py +++ b/ldm/invoke/restoration/outcrop.py @@ -28,12 +28,11 @@ class Outcrop(object): self.generate._set_sampler() def wrapped_callback(img,seed,**kwargs): - preferred_seed = orig_opt.seed if orig_opt.seed> 0 else seed - image_callback(img,preferred_seed,use_prefix=prefix,**kwargs) + image_callback(img,orig_opt.seed,use_prefix=prefix,**kwargs) result= self.generate.prompt2image( orig_opt.prompt, - seed = orig_opt.seed if orig_opt.seed>0 else opt.seed, + seed = orig_opt.seed, # uncomment to make it deterministic sampler = self.generate.sampler, steps = opt.steps, cfg_scale = opt.cfg_scale, diff --git a/scripts/invoke.py b/scripts/invoke.py index 25917f7030..cca49bcdc9 100755 --- a/scripts/invoke.py +++ b/scripts/invoke.py @@ -29,7 +29,6 @@ infile = None def main(): """Initialize command-line parsers and the diffusion model""" global infile - print('* Initializing, be patient...') opt = Args() args = opt.parse_args() @@ -47,6 +46,7 @@ def main(): print('--max_loaded_models must be >= 1; using 1') args.max_loaded_models = 1 + print('* Initializing, be patient...') from ldm.generate import Generate # these two lines prevent a horrible warning message from appearing @@ -662,10 +662,7 @@ def do_postprocess (gen, opt, callback): def add_postprocessing_to_metadata(opt,original_file,new_file,tool,command): original_file = original_file if os.path.exists(original_file) else os.path.join(opt.outdir,original_file) new_file = new_file if os.path.exists(new_file) else os.path.join(opt.outdir,new_file) - try: - meta = retrieve_metadata(original_file)['sd-metadata'] - except AttributeError: - meta = retrieve_metadata(new_file)['sd-metadata'] + meta = retrieve_metadata(original_file)['sd-metadata'] if 'image' not in meta: meta = metadata_dumps(opt,seeds=[opt.seed])['image'] meta['image'] = {}