-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmovement.py
90 lines (80 loc) · 3.52 KB
/
movement.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import numpy as np
import cv2 as cv
from video import Video
from utils import curry
from multiprocessing import Pool
class Movement:
def background_subtractor(self, algo, **kwargs):
if algo == 'MOG2':
backSub = cv.createBackgroundSubtractorMOG2(**kwargs)
elif algo == 'KNN':
backSub = cv.createBackgroundSubtractorKNN(**kwargs)
elif algo == 'MOG':
backSub = cv.bgsegm.createBackgroundSubtractorMOG(**kwargs)
elif algo == 'GMG':
backSub = cv.bgsegm.createBackgroundSubtractorGMG(**kwargs)
elif algo == 'CNT':
backSub = cv.bgsegm.createBackgroundSubtractorCNT(**kwargs)
else:
raise ValueError("pick and algorithm 'MOG', 'GMG', 'CNT', 'MOG2' or 'KNN")
return backSub
def dense_flow(self, algo, **kwargs):
if algo == "farnebeck":
denseFlow = cv.FarnebackOpticalFlow_create(**kwargs)
elif algo == "dualtvl1":
denseFlow = cv.optflow.DualTVL1OpticalFlow_create(**kwargs)
else:
raise ValueError("pick an algorithm 'dualtvl1' or 'farnebeck'")
return denseFlow
# TODO need to fix the both section and find a way to normalize
def dense_flow_calculate(self, frame1, frame2, dense_flow, what, **kwargs):
if frame1.shape != frame2.shape:
raise ValueError("Your video frames are not the same shape")
else:
flow = dense_flow.calc(frame1, frame2, flow=None, **kwargs)
mag, ang = cv.cartToPolar(flow[..., 0], flow[..., 1])
ang = ang * 180 / np.pi / 2
if what == "magnitude":
return mag
elif what == "angle":
return ang
elif what == "both":
return np.stack([mag, ang], axis=2)
else:
raise ValueError("you can get either magnitude, angle or both")
def movement(self, Video, method, function, get=None, frames=None, inplace=True):
if len(Video.frames) == 0 and frames is None:
raise ValueError("you did not specify any frames")
elif frames is None and len(Video.frames) > 0:
frames = Video.frames
elif frames is not None and len(Video.frames) > 0:
raise ValueError("you specified 2 sets of frames")
masks = []
if method == "background":
for frame in frames:
mask = function.apply(frame)
masks.append(mask)
elif method == "optical":
masks.append(np.zeros_like(frames[0]))
for i in range(1, len(frames)):
mask = self.dense_flow_calculate(frames[i - 1], frames[i], function,
what=get)
masks.append(mask)
else:
raise ValueError("methods can only be 'background' or 'optical'")
if inplace:
Video.masks = masks
else:
return masks
# this just sums up all the values, it is not meaningful for angles
def calculate(self, Video=None, masks=None):
if Video is not None and masks is not None:
raise ValueError("Provided 2 sets of masks")
elif Video is not None and masks is None:
masks = Video.masks
elif Video is None and masks is None:
raise ValueError("did not provide any mask values")
sums=[]
for mask in masks:
sums.append(mask.sum())
return sums