Source code for pyllusion.image.image_blob

import numpy as np
import PIL.Image, PIL.ImageDraw, PIL.ImageFilter, PIL.ImageFont, PIL.ImageOps
import scipy.signal

from .rescale import rescale
from .utilities import _coord_circle


[docs]def image_blobs(width=500, height=500, n=100, sd=8, weight=1): """Returns a PIL image with blobs of the same standard deviations (SD). Parameters ---------- width : int Width of the returned image. height : int Height of the returned image. n : int Number of gaussian blobs drawn in the returned image. sd : int The standard deviation of the gaussian blob. Unit in pixel. weight : int A multiplication weight in case there are several layers of SDs. Returns ------- Image Image of blob(s). Examples -------- >>> import pyllusion >>> >>> pyllusion.image_blobs(n=100) >>> pyllusion.image_blobs(n=[5, 300, 1000], sd=[50, 10, 5], weight=[1, 1.5, 2]) """ # Sanitize input if isinstance(sd, (int, float)): sd = [sd] if isinstance(n, (int, float)): n = [n] if isinstance(weight, (int, float)): weight = [weight] if len(n) != len(sd): raise TypeError("'n' must be of the same length as 'sd'.") if len(n) != len(weight): raise TypeError("'n' must be of the same length as 'weight'.") if isinstance(width, tuple): height = width[1] width = width[0] # Add layers array = np.zeros((height, width)) parent_width = 3 * np.max([width, height]) for i, current_sd in enumerate(sd): x = np.random.randint(width, size=n[i]) y = np.random.randint(height, size=n[i]) parent_blob = _image_blob_parent(sd=int(current_sd), parent_width=parent_width) w = np.int(len(parent_blob) / 2) for j in range(int(n[i])): # Crop the blob and multiply by weight array += (parent_blob[w - y[j] : (w - y[j]) + height, w - x[j] : (w - x[j]) + width] * weight[i]) array = (array - np.min(array)) / np.max(array) * 255 image = PIL.Image.fromarray(array.astype(np.uint8)) return image
[docs]def image_blob(x=450, y=100, width=800, height=600, sd=30): """Returns a PIL image of a blob. Parameters ---------- x : int x-coordinate of the center of the blob. Unit in pixel. y : int y-coordinate of the center of the blob. Unit in pixel. width : int Width of the returned image. height : int Height of the returned image. sd : int The standard deviation of the gaussian blob. Unit in pixel. Returns ------- Image Image of blob. >>> import pyllusion >>> >>> pyllusion.image_blob() """ blob = _image_blob(x=x, y=y, width=width, height=height) blob = rescale(blob, to=[0, 255]) image = PIL.Image.fromarray(blob.astype(np.uint8)) return image
# ============================================================================= # Internal # ============================================================================= def _image_blob(x=400, y=300, width=800, height=600, sd=30): """Returns a 2D Gaussian kernel. >>> import pyllusion >>> import matplotlib.pyplot as plt >>> array = _image_blob(sd=8) >>> plt.imshow(array) #doctest: +ELLIPSIS """ parent_blob = _image_blob_parent(x=x, y=y, width=width, height=height, sd=sd) w = np.int(len(parent_blob) / 2) return parent_blob[w - y : (w - y) + height, w - x : (w - x) + width] def _image_blob_parent(x=400, y=300, width=800, height=600, sd=30, parent_width=None): """ >>> import matplotlib.pyplot as plt >>> plt.imshow(_image_blob_parent(sd=30)) """ if parent_width is None: parent_width = 3 * (np.max([x, y, height - x, width - y])) gkern1d = scipy.signal.gaussian(parent_width, std=sd).reshape(parent_width, 1) return np.outer(gkern1d, gkern1d) def _draw_blob(width, height=None, size=0.1, blur=0, color="black"): # Retrieve dimensions if height is None: width, height = width elif isinstance(width, PIL.Image.Image): width, height = width.size # Create mask of image size blob = PIL.Image.new("RGBA", (width, height)) # Blob coordinates coord = _coord_circle( blob, diameter=size, x=np.random.uniform(-1, 1), y=np.random.uniform(-1, 1) ) # Draw blob draw = PIL.ImageDraw.Draw(blob) draw.ellipse(coord, fill=color) blob = blob.filter(PIL.ImageFilter.GaussianBlur(radius=blur * 0.01 * width)) return blob