add web interface for seamless option

This commit is contained in:
Lincoln Stein 2022-09-03 13:43:04 -04:00
commit a01b7bdc40
6 changed files with 46 additions and 3 deletions

View File

@ -138,6 +138,13 @@ You may also pass a -v<count> option to generate count variants on the original
passing the first generated image back into img2img the requested number of times. It generates interesting
variants.
## Seamless Tiling
The seamless tiling mode causes generated images to seamlessly tile with itself. To use it, add the --seamless option when starting the script which will result in all generated images to tile, or for each dream> prompt as shown here:
```
dream> "pond garden with lotus by claude monet" --seamless -s100 -n4
```
## GFPGAN and Real-ESRGAN Support
The script also provides the ability to do face restoration and

View File

@ -59,6 +59,8 @@ class PromptFormatter:
switches.append(f'-H{opt.height or t2i.height}')
switches.append(f'-C{opt.cfg_scale or t2i.cfg_scale}')
switches.append(f'-A{opt.sampler_name or t2i.sampler_name}')
if opt.seamless or t2i.seamless:
switches.append(f'--seamless')
if opt.init_img:
switches.append(f'-I{opt.init_img}')
if opt.fit:

View File

@ -70,7 +70,8 @@ class DreamServer(BaseHTTPRequestHandler):
steps = int(post_data['steps'])
width = int(post_data['width'])
height = int(post_data['height'])
fit = 'fit' in post_data
fit = 'fit' in post_data
seamless = 'seamless' in post_data
cfgscale = float(post_data['cfgscale'])
sampler_name = post_data['sampler']
gfpgan_strength = float(post_data['gfpgan_strength']) if gfpgan_model_exists else 0
@ -164,6 +165,7 @@ class DreamServer(BaseHTTPRequestHandler):
gfpgan_strength = gfpgan_strength,
upscale = upscale,
sampler_name = sampler_name,
seamless = seamless,
step_callback=image_progress,
image_callback=image_done)
else:
@ -185,6 +187,7 @@ class DreamServer(BaseHTTPRequestHandler):
width = width,
height = height,
fit = fit,
seamless = seamless,
gfpgan_strength=gfpgan_strength,
upscale = upscale,
step_callback=image_progress,

View File

@ -14,6 +14,7 @@ from PIL import Image
from tqdm import tqdm, trange
from itertools import islice
from einops import rearrange, repeat
from torch import nn
from torchvision.utils import make_grid
from pytorch_lightning import seed_everything
from torch import autocast
@ -109,6 +110,7 @@ class T2I:
downsampling_factor
precision
strength
seamless
embedding_path
The vast majority of these arguments default to reasonable values.
@ -132,6 +134,7 @@ class T2I:
precision='autocast',
full_precision=False,
strength=0.75, # default in scripts/img2img.py
seamless=False,
embedding_path=None,
device_type = 'cuda',
# just to keep track of this parameter when regenerating prompt
@ -153,6 +156,7 @@ class T2I:
self.precision = precision
self.full_precision = True if choose_torch_device() == 'mps' else full_precision
self.strength = strength
self.seamless = seamless
self.embedding_path = embedding_path
self.device_type = device_type
self.model = None # empty for now
@ -217,6 +221,7 @@ class T2I:
step_callback = None,
width = None,
height = None,
seamless = False,
# these are specific to img2img
init_img = None,
fit = False,
@ -240,6 +245,7 @@ class T2I:
width // width of image, in multiples of 64 (512)
height // height of image, in multiples of 64 (512)
cfg_scale // how strongly the prompt influences the image (7.5) (must be >1)
seamless // whether the generated image should tile
init_img // path to an initial image - its dimensions override width and height
strength // strength for noising/unnoising init_img. 0.0 preserves image exactly, 1.0 replaces it completely
gfpgan_strength // strength for GFPGAN. 0.0 preserves image exactly, 1.0 replaces it completely
@ -268,6 +274,7 @@ class T2I:
steps = steps or self.steps
width = width or self.width
height = height or self.height
seamless = seamless or self.seamless
cfg_scale = cfg_scale or self.cfg_scale
ddim_eta = ddim_eta or self.ddim_eta
iterations = iterations or self.iterations
@ -278,6 +285,10 @@ class T2I:
model = (
self.load_model()
) # will instantiate the model or return it from cache
for m in model.modules():
if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d)):
m.padding_mode = 'circular' if seamless else m._orig_padding_mode
assert cfg_scale > 1.0, 'CFG_Scale (-C) must be >1.0'
assert (
0.0 <= strength <= 1.0
@ -603,6 +614,10 @@ class T2I:
self._set_sampler()
for m in self.model.modules():
if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d)):
m._orig_padding_mode = m.padding_mode
return self.model
# returns a tensor filled with random numbers from a normal distribution

View File

@ -62,6 +62,7 @@ def main():
grid = opt.grid,
# this is solely for recreating the prompt
latent_diffusion_weights=opt.laion400m,
seamless=opt.seamless,
embedding_path=opt.embedding_path,
device_type=opt.device
)
@ -87,6 +88,9 @@ def main():
print(f'{e}. Aborting.')
sys.exit(-1)
if opt.seamless:
print(">> changed to seamless tiling mode")
# preload the model
tic = time.time()
t2i.load_model()
@ -418,6 +422,11 @@ def create_argv_parser():
default='outputs/img-samples',
help='Directory to save generated images and a log of prompts and seeds. Default: outputs/img-samples',
)
parser.add_argument(
'--seamless',
action='store_true',
help='Change the model to seamless tiling (circular) mode',
)
parser.add_argument(
'--embedding_path',
type=str,
@ -540,6 +549,11 @@ def create_cmd_parser():
default=None,
help='Directory to save generated images and a log of prompts and seeds',
)
parser.add_argument(
'--seamless',
action='store_true',
help='Change the model to seamless tiling (circular) mode',
)
parser.add_argument(
'-i',
'--individual',

View File

@ -37,6 +37,8 @@
<option value="k_euler_a">KEULER_A</option>
<option value="k_heun">KHEUN</option>
</select>
<input type="checkbox" name="seamless" id="seamless">
<label for="seamless">Seamless circular tiling</label>
<br>
<label title="Set to multiple of 64" for="width">Width:</label>
<select id="width" name="width" value="512">
@ -64,7 +66,7 @@
<input value="-1" type="number" id="seed" name="seed">
<button type="button" id="reset-seed">&olarr;</button>
<input type="checkbox" name="progress_images" id="progress_images">
<label for="progress_images">Display in-progress images (slows down generation):</label>
<label for="progress_images">Display in-progress images (slower)</label>
<button type="button" id="reset-all">Reset to Defaults</button>
</div>
<div id="img2img">
@ -74,7 +76,7 @@
<label for="strength">Img2Img Strength:</label>
<input value="0.75" type="number" id="strength" name="strength" step="0.01" min="0" max="1">
<input type="checkbox" id="fit" name="fit" checked>
<label title="Rescale image to fit within requested width and height" for="fit">Fit to width/height:</label>
<label title="Rescale image to fit within requested width and height" for="fit">Fit to width/height</label>
</div>
<div id="gfpgan">
<label title="Strength of the gfpgan (face fixing) algorithm." for="gfpgan_strength">GPFGAN Strength (0 to disable):</label>