Skip to content

Instantly share code, notes, and snippets.

@tomowarkar
Last active January 14, 2021 15:09
Show Gist options
  • Save tomowarkar/27ef1b18367c9f75fa5faf234a301d7f to your computer and use it in GitHub Desktop.
Save tomowarkar/27ef1b18367c9f75fa5faf234a301d7f to your computer and use it in GitHub Desktop.
visual timer
import cv2
import numpy as np
from tqdm import tqdm
from datetime import timedelta
import math
### base image config
h, w = 2160, 3840
channel = 3
base = np.zeros((h, w, channel), dtype=np.uint8)
# set back ground with white
base[:, :, :3] = 255
#######################
### video config
fps = 30
run_time = 30
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
video = cv2.VideoWriter("TEST.mp4", fourcc, fps, (w, h))
#######################
### common settings
blue = (223, 156, 148)
black = (51, 51, 51)
white = (255, 255, 255)
font = cv2.FONT_HERSHEY_COMPLEX_SMALL | cv2.FONT_ITALIC
major_axis, minor_axis = 600, 600 # cv2.ellipse
axis = (major_axis, minor_axis) # cv2.ellipse
center = (w//2, h//2) # cv2.ellipse and cv2.circle
angle = -90 # cv2.ellipse
start_angle = 0 # cv2.ellipse
#######################
def putTextCenter(img, text, font, fontSize, thickness, color):
textsize = cv2.getTextSize(text, font, fontSize, thickness)[0]
textX = (img.shape[1] - textsize[0]) // 2
textY = (img.shape[0] + textsize[1]) // 2
cv2.putText(img, text, (textX, textY), font, fontSize, color, thickness)
### main tasks
for i in tqdm(range(fps*run_time)):
img = base.copy()
end_angle = (i*360/(fps*run_time))
cv2.ellipse(img, center, axis, angle, start_angle, end_angle, blue, thickness=-1)
cv2.circle(img, center, minor_axis//2, white, thickness=-1)
text = str(timedelta(seconds=math.ceil((fps*run_time-(i+1))/fps)))
putTextCenter(img, text, font, 10, 10, black)
video.write(img)
video.release()
import os
import cv2
import numpy as np
from tqdm import tqdm
from datetime import timedelta
import math
class MkVideo:
_output_dir = None
def __init__(self, base_img, run_time, fps=30):
assert isinstance(base_img, np.ndarray)
self.fps = fps
self.run_time = run_time
self.img = base_img
@property
def output_dir(self):
if self._output_dir is None:
self._output_dir = "./"
return self._output_dir
@output_dir.setter
def output_dir(self, path):
if os.path.isdir(path):
self._output_dir = path
else:
raise Exception
@property
def width(self):
"""video width"""
return self.img.shape[1]
@property
def height(self):
"""video height"""
return self.img.shape[0]
@property
def duration(self):
"""num of video frames"""
return self.fps * self.run_time
def run(self, codec, filename, nooverwrite=True):
filename = os.path.join(self.output_dir, filename)
if nooverwrite and os.path.isfile(filename):
raise FileExistsError
fourcc = cv2.VideoWriter_fourcc(*codec)
video = cv2.VideoWriter(filename, fourcc, self.fps, (self.width, self.height))
for i in tqdm(range(self.duration)):
img = self._updater(i)
video.write(img)
video.release()
print("[EOR] output:", filename)
def _updater(self, i):
img = self.img.copy()
return self.updater(i, img)
def updater(self, i, img):
raise Exception
class Timer(MkVideo):
def draw_circle_counter(self, tick, img):
"""orverlay counter to img"""
center = (self.width//2, self.height//2) # cv2.ellipse and cv2.circle
major_axis, minor_axis = 600, 600 # cv2.ellipse
axis = (major_axis, minor_axis)
angle = -90 # cv2.ellipse
start_angle = 0 # cv2.ellipse
end_angle = tick*360/self.duration
red = (125, 93, 205)
white = (255, 255, 255)
cv2.ellipse(img, center, axis, angle, start_angle, end_angle, red, thickness=-1)
cv2.circle(img, center, minor_axis//2, white, thickness=-1)
def draw_time_counter(self, tick, img):
"""orverlay timer to img"""
black = (51, 51, 51)
font = cv2.FONT_HERSHEY_COMPLEX_SMALL | cv2.FONT_ITALIC
fontSize = 10
thickness = 10
text = str(timedelta(seconds=math.ceil((self.duration-(tick+1))/self.fps)))
textsize = cv2.getTextSize(text, font, fontSize, thickness)[0]
textX = (self.width - textsize[0]) // 2
textY = (self.height + textsize[1]) // 2
cv2.putText(img, text, (textX, textY), font, fontSize, black, thickness)
def updater(self, i, img):
self.draw_circle_counter(i, img)
self.draw_time_counter(i, img)
return img
h, w, channel = 2160, 3840, 3
base_img = np.zeros((h, w, channel), dtype=np.uint8)
base_img[:,:,:3]=255 # background: white
timer = Timer(base_img, run_time=60)
timer.output_dir = "%s/Desktop" % os.path.expanduser("~")
timer.run("mp4v", "hoge.mp4", nooverwrite=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment