Skip to content

Instantly share code, notes, and snippets.

@ghandic
Last active July 6, 2018 09:16
Show Gist options
  • Save ghandic/ffaa7656d2dc33541034a1b64a892d6c to your computer and use it in GitHub Desktop.
Save ghandic/ffaa7656d2dc33541034a1b64a892d6c to your computer and use it in GitHub Desktop.
Creates a labeled gif using opencv imageio and numpy
import imageio
from typing import NamedTuple
import cv2
import numpy as np
LabeledGIFState = NamedTuple('LabeledGIFState', [('image', np.ndarray), ('label', str)])
class GifSettings(object):
red = [255, 0, 0]
green = [0, 255, 0]
blue = [0, 0, 255]
orange = [255, 165, 0]
yellow = [255, 255, 0]
pink = [255, 192, 203]
purple = [128, 0, 128]
white = [255]*3
gainsboro = [220]*3
lightgray = [211]*3
silver = [192]*3
darkgray = [169]*3
gray = [128]*3
dimgray = [105]*3
black = [0]*3
lightgrey = lightgray
darkgrey = darkgray
dimgrey = dimgray
class LabeledGif(object):
def __init__(self, labeled_states, duration=1):
assert isinstance(labeled_states, list), '\
labeled_states should be a list of LabeledGIFState objects'
for ls in labeled_states:
assert isinstance(ls, LabeledGIFState) and \
isinstance(ls.image, np.ndarray) and \
isinstance(ls.label, str), '\
labeled_states should be a list of \
LabeledGIFState(np.ndarray, label)'
self.labeled_states = labeled_states
self.labeled_images = []
self.duration = duration
self.__make_as_big_as_biggest()
def add_labels(self, position='above', background_color=GifSettings.blue,
font_color=GifSettings.white, font_size=1,
font_thickness=2, text_padding=10):
"""Doc"""
for ls in self.labeled_states:
image_copy = ls.image.copy()
try:
image_copy = cv2.cvtColor(image_copy, cv2.COLOR_GRAY2RGB)
except:
pass
h, _, _ = image_copy.shape
shape, _ = cv2.getTextSize(ls.label, cv2.FONT_HERSHEY_SIMPLEX,
font_size, font_thickness)
if position == 'below':
c1 = cv2.copyMakeBorder(image_copy, 0, text_padding+shape[1], 0,
0, cv2.BORDER_CONSTANT, value=background_color)
c2 = cv2.putText(c1, ls.label, (0, h+shape[1]+int(text_padding/2)),
cv2.FONT_HERSHEY_SIMPLEX, font_size,
font_color, font_thickness)
elif position == 'above':
c1 = cv2.copyMakeBorder(image_copy, text_padding+shape[1], 0, 0,
0, cv2.BORDER_CONSTANT, value=background_color)
c2 = cv2.putText(c1, ls.label, (0, shape[1]), cv2.FONT_HERSHEY_SIMPLEX,
font_size, font_color, font_thickness)
self.labeled_images.append(c2)
def __make_as_big_as_biggest(self, background_color=GifSettings.white,
border_color=GifSettings.green, border_size=10):
"""Doc"""
new_labeled_states = []
mh, mw = (max([ls.image.shape[0] for ls in self.labeled_states]),
max([ls.image.shape[1] for ls in self.labeled_states]))
blank_image = np.zeros((mh+2*border_size, mw+2*border_size, 3), np.uint8)
blank_image[:, :] = background_color
for ls in self.labeled_states:
image_copy = ls.image.copy()
try:
image_copy = cv2.cvtColor(image_copy, cv2.COLOR_GRAY2RGB)
except:
pass
im_h, im_w, _ = image_copy.shape
new_img = blank_image.copy()
image_copy_with_border = cv2.copyMakeBorder(image_copy, border_size,
border_size, border_size,
border_size, cv2.BORDER_CONSTANT,
value=border_color)
new_img[0:im_h+2*border_size, 0:im_w+2*border_size] = image_copy_with_border
new_labeled_states.append(LabeledGIFState(new_img, ls.label))
self.labeled_states = new_labeled_states
def save(self, path):
"""Doc"""
if self.labeled_images:
imageio.mimsave(path, self.labeled_images, duration=self.duration)
else:
imageio.mimsave(path, [ls.image for ls in self.labeled_states], duration=self.duration)
if __name__ == '__main__':
# Read in an image and manipulate
IMAGE = cv2.imread('example.png')
# Changing colorscale
GRAY_IMAGE = cv2.cvtColor(IMAGE, cv2.COLOR_BGR2GRAY)
BINARY_IMAGE = cv2.threshold(GRAY_IMAGE, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# Changing scale
SCALED_IMAGE = cv2.resize(IMAGE, (0, 0), fx=0.2, fy=0.2)
SCALED_GRAY_IMAGE = cv2.resize(BINARY_IMAGE, (0, 0), fx=0.5, fy=0.5)
SCALED_BINARY_IMAGE = cv2.threshold(SCALED_GRAY_IMAGE, 0, 255,
cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# Make a GIF and save
GIF = LabeledGif([LabeledGIFState(IMAGE, 'Original image'),
LabeledGIFState(GRAY_IMAGE, 'Greyscale image'),
LabeledGIFState(BINARY_IMAGE, 'Binary image'),
LabeledGIFState(SCALED_GRAY_IMAGE, '20% Original image'),
LabeledGIFState(SCALED_GRAY_IMAGE, '50% Greyscale image'),
LabeledGIFState(SCALED_BINARY_IMAGE, '50% Binary image')],
duration=1)
# Add labels and then save
GIF.add_labels(font_color=GifSettings.white)
GIF.save('example.gif')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment