code: def get_matched_noise(
      _np_src_image, np_mask_rgb, noise_q=1, color_variation=0.05
  ):
      # helper fft routines that keep ortho normalization and auto-shift before and after fft
      def _fft2(data):
          if data.ndim > 2:  # has channels
              out_fft = np.zeros(
                  (data.shape[0], data.shape[1], data.shape[2]),
                  dtype=np.complex128,
              )
              for c in range(data.shape[2]):
                  c_data = data[:, :, c]
                  out_fft[:, :, c] = np.fft.fft2(
                      np.fft.fftshift(c_data), norm="ortho"
                  )
                  out_fft[:, :, c] = np.fft.ifftshift(out_fft[:, :, c])
          else:  # one channel
              out_fft = np.zeros(
                  (data.shape[0], data.shape[1]), dtype=np.complex128
              )
              out_fft[:, :] = np.fft.fft2(
                  np.fft.fftshift(data), norm="ortho"
              )
              out_fft[:, :] = np.fft.ifftshift(out_fft[:, :])
  
          return out_fft
  
      def _ifft2(data):
          if data.ndim > 2:  # has channels
              out_ifft = np.zeros(
                  (data.shape[0], data.shape[1], data.shape[2]),
                  dtype=np.complex128,
              )
              for c in range(data.shape[2]):
                  c_data = data[:, :, c]
                  out_ifft[:, :, c] = np.fft.ifft2(
                      np.fft.fftshift(c_data), norm="ortho"
                  )
                  out_ifft[:, :, c] = np.fft.ifftshift(
                      out_ifft[:, :, c]
                  )
          else:  # one channel
              out_ifft = np.zeros(
                  (data.shape[0], data.shape[1]), dtype=np.complex128
              )
              out_ifft[:, :] = np.fft.ifft2(
                  np.fft.fftshift(data), norm="ortho"
              )
              out_ifft[:, :] = np.fft.ifftshift(out_ifft[:, :])
  
          return out_ifft
  
      def _get_gaussian_window(width, height, std=3.14, mode=0):
          window_scale_x = float(width / min(width, height))
          window_scale_y = float(height / min(width, height))
  
          window = np.zeros((width, height))
          x = (np.arange(width) / width * 2.0 - 1.0) * window_scale_x
          for y in range(height):
              fy = (y / height * 2.0 - 1.0) * window_scale_y
              if mode == 0:
                  window[:, y] = np.exp(-(x**2 + fy**2) * std)
              else:
                  window[:, y] = (
                      1 / ((x**2 + 1.0) * (fy**2 + 1.0))
                  ) ** (
                      std / 3.14
                  )  # hey wait a minute that's not gaussian
  
          return window
  
      def _get_masked_window_rgb(np_mask_grey, hardness=1.0):
          np_mask_rgb = np.zeros(
              (np_mask_grey.shape[0], np_mask_grey.shape[1], 3)
          )
          if hardness != 1.0:
              hardened = np_mask_grey[:] ** hardness
          else:
              hardened = np_mask_grey[:]
          for c in range(3):
              np_mask_rgb[:, :, c] = hardened[:]
          return np_mask_rgb
  
      width = _np_src_image.shape[0]
      height = _np_src_image.shape[1]
      num_channels = _np_src_image.shape[2]
  
      _np_src_image[:] * (1.0 - np_mask_rgb)
      np_mask_grey = np.sum(np_mask_rgb, axis=2) / 3.0
      img_mask = np_mask_grey > 1e-6
      ref_mask = np_mask_grey < 1e-3
  
      windowed_image = _np_src_image * (
          1.0 - _get_masked_window_rgb(np_mask_grey)
      )
      windowed_image /= np.max(windowed_image)
      windowed_image += (
          np.average(_np_src_image) * np_mask_rgb
      )  # / (1.-np.average(np_mask_rgb))  # rather than leave the masked area black, we get better results from fft by filling the average unmasked color
  
      src_fft = _fft2(
          windowed_image
      )  # get feature statistics from masked src img
      src_dist = np.absolute(src_fft)
      src_phase = src_fft / src_dist
  
      # create a generator with a static seed to make outpainting deterministic / only follow global seed
      rng = np.random.default_rng(0)
  
      noise_window = _get_gaussian_window(
          width, height, mode=1
      )  # start with simple gaussian noise
      noise_rgb = rng.random((width, height, num_channels))
      noise_grey = np.sum(noise_rgb, axis=2) / 3.0
      noise_rgb *= color_variation  # the colorfulness of the starting noise is blended to greyscale with a parameter
      for c in range(num_channels):
          noise_rgb[:, :, c] += (1.0 - color_variation) * noise_grey
  
      noise_fft = _fft2(noise_rgb)
      for c in range(num_channels):
          noise_fft[:, :, c] *= noise_window
      noise_rgb = np.real(_ifft2(noise_fft))
      shaped_noise_fft = _fft2(noise_rgb)
      shaped_noise_fft[:, :, :] = (
          np.absolute(shaped_noise_fft[:, :, :]) ** 2
          * (src_dist**noise_q)
          * src_phase
      )  # perform the actual shaping
  
      brightness_variation = 0.0  # color_variation # todo: temporarily tieing brightness variation to color variation for now
      contrast_adjusted_np_src = (
          _np_src_image[:] * (brightness_variation + 1.0)
          - brightness_variation * 2.0
      )
  
      # scikit-image is used for histogram matching, very convenient!
      shaped_noise = np.real(_ifft2(shaped_noise_fft))
      shaped_noise -= np.min(shaped_noise)
      shaped_noise /= np.max(shaped_noise)
      shaped_noise[img_mask, :] = skimage.exposure.match_histograms(
          shaped_noise[img_mask, :] ** 1.0,
          contrast_adjusted_np_src[ref_mask, :],
          channel_axis=1,
      )
      shaped_noise = (
          _np_src_image[:] * (1.0 - np_mask_rgb)
          + shaped_noise * np_mask_rgb
      )
  
      matched_noise = shaped_noise[:]
  
      return np.clip(matched_noise, 0.0, 1.0)
  
file_path: stable-diffusion-webui/scripts/outpainting_mk_2.py
imports: import math
  import numpy
  import skimage
  import modules.scripts
  import gradio
  from PIL import Image, ImageDraw
  from modules import images
  from modules.processing import Processed, process_images
  from modules.shared import opts, state
label_desc: Use image node_id 1 for calling a global function with example usage: get_matched_noise(_np_src_image, np_mask_rgb, noise_q, color_variation) and returns: np, out_fft, out_ifft, window, np_mask_rgb