Skip to content

Commit

Permalink
feat(gui): produce noise based on source image histogram
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Jan 14, 2023
1 parent c8c5481 commit b24b1eb
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 39 deletions.
64 changes: 64 additions & 0 deletions api/onnx_web/image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from numpy import random
from PIL import Image, ImageStat
from typing import Tuple

import numpy as np

def blend_mask_inverse_source(source: Tuple[int, int, int], mask: Tuple[int, int, int], noise: int) -> Tuple[int, int, int]:
m = float(noise) / 256
n = 1.0 - m

return (
int((source[0] * n) + (mask[0] * m)),
int((source[1] * n) + (mask[1] * m)),
int((source[2] * n) + (mask[2] * m)),
)


def blend_source_histogram(source_image: Image, dims: Tuple[int, int], sigma = 200) -> Tuple[float, float, float]:
r, g, b = source_image.split()
width, height = dims

hist_r = r.histogram()
hist_g = g.histogram()
hist_b = b.histogram()

rng_r = random.choice(256, p=hist_r)
rng_g = random.choice(256, p=hist_g)
rng_b = random.choice(256, p=hist_b)

noise_r = rng_r.integers(0, size=width * height)
noise_g = rng_g.integers(0, size=width * height)
noise_b = rng_b.integers(0, size=width * height)

noise = Image.fromarray(zip(noise_r, noise_g, noise_b))

return noise



# based on https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/master/scripts/outpainting_mk_2.py#L175-L232
def expand_image(source_image: Image, mask_image: Image, dims: Tuple[int, int, int, int], fill = 'white', blend_source=blend_source_histogram, blend_op=blend_mask_inverse_source):
left, right, top, bottom = dims

full_width = left + source_image.width + right
full_height = top + source_image.height + bottom

full_source = Image.new('RGB', (full_width, full_height), fill)
full_source.paste(source_image, (left, top))

full_mask = Image.new('RGB', (full_width, full_height), fill)
full_mask.paste(mask_image, (left, top))

full_noise = blend_source(source_image, (full_width, full_height))

for x in range(full_source.width):
for y in range(full_source.height):
mask_color = full_mask.getpixel((x, y))
noise_color = full_noise.getpixel((x, y))
source_color = full_source.getpixel((x, y))

if mask_color[0] > 0:
full_source.putpixel((x, y), blend_op(source_color, mask_color, noise_color))

return (full_source, full_mask, (full_width, full_height))
42 changes: 3 additions & 39 deletions api/onnx_web/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@
from flask_executor import Executor
from hashlib import sha256
from io import BytesIO
from PIL import Image, ImageDraw
from PIL import Image
from struct import pack
from os import environ, makedirs, path, scandir
from typing import Any, Dict, Tuple, Union

from .image import expand_image

import json
import numpy as np

Expand Down Expand Up @@ -102,44 +104,6 @@ def get_latents_from_seed(seed: int, width: int, height: int) -> np.ndarray:
return image_latents


def blend_pixel(source: Tuple[int, int, int], mask: Tuple[int, int, int], noise: int) -> Tuple[int, int, int]:
m = float(noise) / 256
n = 1.0 - m

return (
int((source[0] * n) + (mask[0] * m)),
int((source[1] * n) + (mask[1] * m)),
int((source[2] * n) + (mask[2] * m)),
)


# based on https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/master/scripts/outpainting_mk_2.py#L175-L232
def expand_image(source_image: Image, mask_image: Image, dims: Tuple[int, int, int, int]):
(left, right, top, bottom) = dims

full_width = left + source_image.width + right
full_height = top + source_image.height + bottom

full_source = Image.new('RGB', (full_width, full_height), 'white')
full_source.paste(source_image, (left, top))

full_mask = Image.new('RGB', (full_width, full_height), 'white')
full_mask.paste(mask_image, (left, top))

full_noise = Image.effect_noise((full_width, full_height), 200)

for x in range(full_source.width):
for y in range(full_source.height):
mask_color = full_mask.getpixel((x, y))
noise_color = full_noise.getpixel((x, y))
source_color = full_source.getpixel((x, y))

if mask_color[0] > 0:
full_source.putpixel((x, y), blend_pixel(source_color, mask_color, noise_color))

return (full_source, full_mask, (full_width, full_height))


def load_pipeline(pipeline: DiffusionPipeline, model: str, provider: str, scheduler):
global last_pipeline_instance
global last_pipeline_scheduler
Expand Down

0 comments on commit b24b1eb

Please sign in to comment.