Skip to content

Commit 8412d34

Browse files
author
axwalker
committed
Can create video heatmaps
1 parent 979bd31 commit 8412d34

File tree

5 files changed

+66
-2
lines changed

5 files changed

+66
-2
lines changed

heatmappy/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from heatmappy.heatmap import Heatmapper,\
22
GreyHeatMapper,\
33
PILGreyHeatmapper,\
4-
PySideGreyHeatmapper
4+
PySideGreyHeatmapper
5+
6+
from heatmappy.video import VideoHeatmapper
1.01 MB
Binary file not shown.

heatmappy/heatmap.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ def _colourised(self, img):
8989
rgba_img = self.cmap(arr, bytes=True)
9090
return Image.fromarray(rgba_img)
9191

92-
9392
@staticmethod
9493
def _cmap_from_image_path(img_path):
9594
img = Image.open(img_path)

heatmappy/video.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from collections import defaultdict
2+
import random
3+
4+
from moviepy.editor import *
5+
import numpy as np
6+
7+
from heatmappy import Heatmapper
8+
9+
10+
class VideoHeatmapper:
11+
def __init__(self, heatmapper):
12+
self.heatmapper = heatmapper
13+
14+
def heatmap_on_video(self, video_path, points, heat_fps=25):
15+
base = VideoFileClip(video_path)
16+
width, height = base.size
17+
18+
frame_points = self._frame_points(points, heat_fps)
19+
heatmap_frames = self._heatmap_frames(width, height, frame_points)
20+
heatmap_clips = self._heatmap_clips(heatmap_frames, heat_fps)
21+
22+
return CompositeVideoClip([base] + list(heatmap_clips))
23+
24+
@staticmethod
25+
def _frame_points(pts, fps):
26+
frames = defaultdict(list)
27+
for x, y, t in pts:
28+
start = (t // fps) * fps
29+
frames[start].append((x, y))
30+
return frames
31+
32+
def _heatmap_frames(self, width, height, frame_points):
33+
for frame_start, points in frame_points.items():
34+
heatmap = self.heatmapper.heatmap(width, height, points)
35+
yield frame_start, np.array(heatmap)
36+
37+
@staticmethod
38+
def _heatmap_clips(heatmap_frames, fps):
39+
for frame_start, heat in heatmap_frames:
40+
yield (ImageClip(heat)
41+
.set_start(frame_start/1000)
42+
.set_duration(fps/1000)
43+
.set_fps(fps))
44+
45+
46+
if __name__ == '__main__':
47+
def rand_point(max_x, max_y, max_t):
48+
return random.randint(0, max_x), random.randint(0, max_y), random.randint(0, max_t)
49+
50+
example_points = (rand_point(720, 480, 4000) for _ in range(15000))
51+
example_vid = 'assets\SampleVideo_720x480_1mb.mp4'
52+
53+
img_heatmapper = Heatmapper(colours='default')
54+
video_heatmapper = VideoHeatmapper(img_heatmapper)
55+
56+
video = heatmap_video = video_heatmapper.heatmap_on_video(
57+
video_path=example_vid,
58+
points=example_points
59+
)
60+
61+
video.write_videofile('out.mp4', bitrate="5000k", fps=24)
62+

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cycler==0.9.0
22
matplotlib==1.5.0
3+
moviepy==0.2.2.11
34
numpy==1.10.1
45
Pillow==3.0.0
56
pyparsing==2.0.6

0 commit comments

Comments
 (0)