Module fontai.deployment.plotters
Expand source code
import io
import base64
import typing as t
import tensorflow as tf
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from abc import ABC, abstractmethod
from fontai.prediction.callbacks import SAAEFontSamplerCallback, TensorSAAEFontSamplerCallback
class AlphabetPlotter(ABC):
@classmethod
@abstractmethod
def generate_font(cls):
pass
@classmethod
@abstractmethod
def plot_font(cls):
pass
def fig_to_str(cls, in_fig, close_all=True, **save_args):
"""Maps a pyplot figure to base64 encoding for display inside a Dash app
Args:
in_fig : Matplotlib figure
close_all (bool, optional): Close all figures after saving to an internal buffer
**save_args: Arguments passed when saving figure to an internal buffer
Returns:
str: base64-encoded image
"""
out_img = io.BytesIO()
in_fig.savefig(out_img, format='png', **save_args)
if close_all:
in_fig.clf()
plt.close('all')
out_img.seek(0) # rewind file
encoded = base64.b64encode(out_img.read()).decode("ascii").replace("\n", "")
return f"data:image/png;base64,{encoded}"
class SAAEAlphabetPlotter(AlphabetPlotter):
@classmethod
def generate_font(cls, model:tf.keras.Model, style_vector: np.array, charset_size: int):
"""Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes images are along the first axis in the resulting tensor, i.e. images are output examples.
Args:
model (tf.keras.Model): Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor
style_vector (np.array): style vector
charset_size (int): number of characters in font
Returns:
np.array: four-dimensional array where the first dimension correspond to image indices and the last to image channels
"""
# sample one hot encoded labels
labels = []
for k in range(charset_size):
onehot = np.zeros((1,charset_size), dtype=np.float32)
onehot[0,k] = 1.0
labels.append(np.concatenate([style_vector,onehot],axis=-1))
fully_encoded = np.array(labels, dtype=np.float32)
chars = model.predict(fully_encoded)
return chars
@classmethod
def plot_font(cls, imgs: t.Union[tf.Tensor, np.ndarray], n_cols = 7) -> None:
"""Utility function to plot a sequence of images from numpy array in a matrix plot
Args:
imgs (t.Union[tf.Tensor, np.ndarray]): 4-dimensional array of images
output_file (str): output file
n_cols (int, optional): number of columns in output figure
"""
# plot multiple images
n_imgs, height, width, c = imgs.shape
n_rows = int(np.ceil(n_imgs/n_cols))
fig, axs = plt.subplots(n_rows, n_cols)
for i in range(n_imgs):
x = imgs[i]
if isinstance(x, np.ndarray):
x_ = x
else:
x_ = x.numpy()
np_x = (255 * x_).astype(np.uint8).reshape((height,width))
axs[int(i/n_cols), i%n_cols].imshow(np_x, cmap="Greys")
for k in range(n_rows*n_cols):
axs[int(k/n_cols), k%n_cols].axis("off")
return fig
class TensorSAAEAlphabetPlotter(AlphabetPlotter):
@classmethod
def generate_font(cls, model:tf.keras.Model, style_vector: np.array, *args, **kwargs):
"""Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes imags are along the last channels, i.e. images are channels in the resulting tensor. It does not pass character labels to the model as they are not needed (since they are encoded in the channel index).
Args:
model (tf.keras.Model): Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor
style_vector (np.array): style vector
charset_size (int): number of characters in font
Returns:
np.array: four-dimensional array where the first dimension correspond to image indices and the last to image channels
"""
# sample one hot encoded labels
chars = model.predict(style_vector.reshape((1,-1)))
return chars
@classmethod
def plot_font(cls, imgs: t.Union[tf.Tensor, np.ndarray], n_cols = 7) -> None:
"""Utility function to plot a sequence of images from numpy array in a matrix plot
Args:
imgs (t.Union[tf.Tensor, np.ndarray]): 4-dimensional array of images
output_file (str): output file
n_cols (int, optional): number of columns in output figure
"""
# plot multiple images
n_fonts, height, width, n_imgs = imgs.shape
n_rows = int(np.ceil(n_imgs/n_cols))
fig, axs = plt.subplots(n_rows, n_cols)
for i in range(n_imgs):
x = imgs[0,:,:,i]
if isinstance(x, np.ndarray):
x_ = x
else:
x_ = x.numpy()
np_x = (255 * x_).astype(np.uint8).reshape((height,width))
axs[int(i/n_cols), i%n_cols].imshow(np_x, cmap="Greys")
for k in range(n_rows*n_cols):
axs[int(k/n_cols), k%n_cols].axis("off")
return fig
Classes
class AlphabetPlotter
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code
class AlphabetPlotter(ABC): @classmethod @abstractmethod def generate_font(cls): pass @classmethod @abstractmethod def plot_font(cls): pass def fig_to_str(cls, in_fig, close_all=True, **save_args): """Maps a pyplot figure to base64 encoding for display inside a Dash app Args: in_fig : Matplotlib figure close_all (bool, optional): Close all figures after saving to an internal buffer **save_args: Arguments passed when saving figure to an internal buffer Returns: str: base64-encoded image """ out_img = io.BytesIO() in_fig.savefig(out_img, format='png', **save_args) if close_all: in_fig.clf() plt.close('all') out_img.seek(0) # rewind file encoded = base64.b64encode(out_img.read()).decode("ascii").replace("\n", "") return f"data:image/png;base64,{encoded}"
Ancestors
- abc.ABC
Subclasses
Static methods
def generate_font()
-
Expand source code
@classmethod @abstractmethod def generate_font(cls): pass
def plot_font()
-
Expand source code
@classmethod @abstractmethod def plot_font(cls): pass
Methods
def fig_to_str(cls, in_fig, close_all=True, **save_args)
-
Maps a pyplot figure to base64 encoding for display inside a Dash app
Args
- in_fig : Matplotlib figure
close_all
:bool
, optional- Close all figures after saving to an internal buffer
**save_args
- Arguments passed when saving figure to an internal buffer
Returns
str
- base64-encoded image
Expand source code
def fig_to_str(cls, in_fig, close_all=True, **save_args): """Maps a pyplot figure to base64 encoding for display inside a Dash app Args: in_fig : Matplotlib figure close_all (bool, optional): Close all figures after saving to an internal buffer **save_args: Arguments passed when saving figure to an internal buffer Returns: str: base64-encoded image """ out_img = io.BytesIO() in_fig.savefig(out_img, format='png', **save_args) if close_all: in_fig.clf() plt.close('all') out_img.seek(0) # rewind file encoded = base64.b64encode(out_img.read()).decode("ascii").replace("\n", "") return f"data:image/png;base64,{encoded}"
class SAAEAlphabetPlotter
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code
class SAAEAlphabetPlotter(AlphabetPlotter): @classmethod def generate_font(cls, model:tf.keras.Model, style_vector: np.array, charset_size: int): """Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes images are along the first axis in the resulting tensor, i.e. images are output examples. Args: model (tf.keras.Model): Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor style_vector (np.array): style vector charset_size (int): number of characters in font Returns: np.array: four-dimensional array where the first dimension correspond to image indices and the last to image channels """ # sample one hot encoded labels labels = [] for k in range(charset_size): onehot = np.zeros((1,charset_size), dtype=np.float32) onehot[0,k] = 1.0 labels.append(np.concatenate([style_vector,onehot],axis=-1)) fully_encoded = np.array(labels, dtype=np.float32) chars = model.predict(fully_encoded) return chars @classmethod def plot_font(cls, imgs: t.Union[tf.Tensor, np.ndarray], n_cols = 7) -> None: """Utility function to plot a sequence of images from numpy array in a matrix plot Args: imgs (t.Union[tf.Tensor, np.ndarray]): 4-dimensional array of images output_file (str): output file n_cols (int, optional): number of columns in output figure """ # plot multiple images n_imgs, height, width, c = imgs.shape n_rows = int(np.ceil(n_imgs/n_cols)) fig, axs = plt.subplots(n_rows, n_cols) for i in range(n_imgs): x = imgs[i] if isinstance(x, np.ndarray): x_ = x else: x_ = x.numpy() np_x = (255 * x_).astype(np.uint8).reshape((height,width)) axs[int(i/n_cols), i%n_cols].imshow(np_x, cmap="Greys") for k in range(n_rows*n_cols): axs[int(k/n_cols), k%n_cols].axis("off") return fig
Ancestors
- AlphabetPlotter
- abc.ABC
Static methods
def generate_font(model: tensorflow.python.keras.engine.training.Model, style_vector:
, charset_size: int) -
Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes images are along the first axis in the resulting tensor, i.e. images are output examples.
Args
model
:tf.keras.Model
- Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor
style_vector
:np.array
- style vector
charset_size
:int
- number of characters in font
Returns
np.array
- four-dimensional array where the first dimension correspond to image indices and the last to image channels
Expand source code
@classmethod def generate_font(cls, model:tf.keras.Model, style_vector: np.array, charset_size: int): """Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes images are along the first axis in the resulting tensor, i.e. images are output examples. Args: model (tf.keras.Model): Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor style_vector (np.array): style vector charset_size (int): number of characters in font Returns: np.array: four-dimensional array where the first dimension correspond to image indices and the last to image channels """ # sample one hot encoded labels labels = [] for k in range(charset_size): onehot = np.zeros((1,charset_size), dtype=np.float32) onehot[0,k] = 1.0 labels.append(np.concatenate([style_vector,onehot],axis=-1)) fully_encoded = np.array(labels, dtype=np.float32) chars = model.predict(fully_encoded) return chars
def plot_font(imgs: Union[tensorflow.python.framework.ops.Tensor, numpy.ndarray], n_cols=7) ‑> None
-
Utility function to plot a sequence of images from numpy array in a matrix plot
Args
imgs
:t.Union[tf.Tensor, np.ndarray]
- 4-dimensional array of images
output_file
:str
- output file
n_cols
:int
, optional- number of columns in output figure
Expand source code
@classmethod def plot_font(cls, imgs: t.Union[tf.Tensor, np.ndarray], n_cols = 7) -> None: """Utility function to plot a sequence of images from numpy array in a matrix plot Args: imgs (t.Union[tf.Tensor, np.ndarray]): 4-dimensional array of images output_file (str): output file n_cols (int, optional): number of columns in output figure """ # plot multiple images n_imgs, height, width, c = imgs.shape n_rows = int(np.ceil(n_imgs/n_cols)) fig, axs = plt.subplots(n_rows, n_cols) for i in range(n_imgs): x = imgs[i] if isinstance(x, np.ndarray): x_ = x else: x_ = x.numpy() np_x = (255 * x_).astype(np.uint8).reshape((height,width)) axs[int(i/n_cols), i%n_cols].imshow(np_x, cmap="Greys") for k in range(n_rows*n_cols): axs[int(k/n_cols), k%n_cols].axis("off") return fig
Inherited members
class TensorSAAEAlphabetPlotter
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code
class TensorSAAEAlphabetPlotter(AlphabetPlotter): @classmethod def generate_font(cls, model:tf.keras.Model, style_vector: np.array, *args, **kwargs): """Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes imags are along the last channels, i.e. images are channels in the resulting tensor. It does not pass character labels to the model as they are not needed (since they are encoded in the channel index). Args: model (tf.keras.Model): Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor style_vector (np.array): style vector charset_size (int): number of characters in font Returns: np.array: four-dimensional array where the first dimension correspond to image indices and the last to image channels """ # sample one hot encoded labels chars = model.predict(style_vector.reshape((1,-1))) return chars @classmethod def plot_font(cls, imgs: t.Union[tf.Tensor, np.ndarray], n_cols = 7) -> None: """Utility function to plot a sequence of images from numpy array in a matrix plot Args: imgs (t.Union[tf.Tensor, np.ndarray]): 4-dimensional array of images output_file (str): output file n_cols (int, optional): number of columns in output figure """ # plot multiple images n_fonts, height, width, n_imgs = imgs.shape n_rows = int(np.ceil(n_imgs/n_cols)) fig, axs = plt.subplots(n_rows, n_cols) for i in range(n_imgs): x = imgs[0,:,:,i] if isinstance(x, np.ndarray): x_ = x else: x_ = x.numpy() np_x = (255 * x_).astype(np.uint8).reshape((height,width)) axs[int(i/n_cols), i%n_cols].imshow(np_x, cmap="Greys") for k in range(n_rows*n_cols): axs[int(k/n_cols), k%n_cols].axis("off") return fig
Ancestors
- AlphabetPlotter
- abc.ABC
Static methods
def generate_font(model: tensorflow.python.keras.engine.training.Model, style_vector:
, *args, **kwargs) -
Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes imags are along the last channels, i.e. images are channels in the resulting tensor. It does not pass character labels to the model as they are not needed (since they are encoded in the channel index).
Args
model
:tf.keras.Model
- Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor
style_vector
:np.array
- style vector
charset_size
:int
- number of characters in font
Returns
np.array
- four-dimensional array where the first dimension correspond to image indices and the last to image channels
Expand source code
@classmethod def generate_font(cls, model:tf.keras.Model, style_vector: np.array, *args, **kwargs): """Creates a set of character images as numpy arrays from a given font style vector and charset size. Assumes imags are along the last channels, i.e. images are channels in the resulting tensor. It does not pass character labels to the model as they are not needed (since they are encoded in the channel index). Args: model (tf.keras.Model): Generative model. Its input must be a vector of size charset_size + style_dim, and it should output an image as a 3-dimensional tensor style_vector (np.array): style vector charset_size (int): number of characters in font Returns: np.array: four-dimensional array where the first dimension correspond to image indices and the last to image channels """ # sample one hot encoded labels chars = model.predict(style_vector.reshape((1,-1))) return chars
def plot_font(imgs: Union[tensorflow.python.framework.ops.Tensor, numpy.ndarray], n_cols=7) ‑> None
-
Utility function to plot a sequence of images from numpy array in a matrix plot
Args
imgs
:t.Union[tf.Tensor, np.ndarray]
- 4-dimensional array of images
output_file
:str
- output file
n_cols
:int
, optional- number of columns in output figure
Expand source code
@classmethod def plot_font(cls, imgs: t.Union[tf.Tensor, np.ndarray], n_cols = 7) -> None: """Utility function to plot a sequence of images from numpy array in a matrix plot Args: imgs (t.Union[tf.Tensor, np.ndarray]): 4-dimensional array of images output_file (str): output file n_cols (int, optional): number of columns in output figure """ # plot multiple images n_fonts, height, width, n_imgs = imgs.shape n_rows = int(np.ceil(n_imgs/n_cols)) fig, axs = plt.subplots(n_rows, n_cols) for i in range(n_imgs): x = imgs[0,:,:,i] if isinstance(x, np.ndarray): x_ = x else: x_ = x.numpy() np_x = (255 * x_).astype(np.uint8).reshape((height,width)) axs[int(i/n_cols), i%n_cols].imshow(np_x, cmap="Greys") for k in range(n_rows*n_cols): axs[int(k/n_cols), k%n_cols].axis("off") return fig
Inherited members