Last active
July 6, 2018 09:16
-
-
Save ghandic/ffaa7656d2dc33541034a1b64a892d6c to your computer and use it in GitHub Desktop.
Creates a labeled gif using opencv imageio and numpy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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