-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathc3d.py
More file actions
123 lines (91 loc) · 4.23 KB
/
c3d.py
File metadata and controls
123 lines (91 loc) · 4.23 KB
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
""" This code has been obtained from https://github.com/ptirupat/AnomalyDetection_CVPR18
This is helper code for C3D feature Extractor
NOT MY WORK
"""
# -*- coding: utf-8 -*-
"""C3D model for Keras
# Reference:
- [Learning Spatiotemporal Features with 3D Convolutional Networks](https://arxiv.org/abs/1412.0767)
Based on code from @albertomontesg
"""
import PIL
import keras.backend as K
from keras.models import Sequential
from keras.models import Model
from keras.layers.core import Dense, Dropout, Flatten
import configuration as cfg
from keras.layers.convolutional import Conv3D, MaxPooling3D, ZeroPadding3D
import numpy as np
from keras.utils.data_utils import get_file
C3D_MEAN_PATH = 'https://github.com/adamcasson/c3d/releases/download/v0.1/c3d_mean.npy'
def preprocess_input(video):
"""Resize and subtract mean from video input
Keyword arguments:
video -- video frames to preprocess. Expected shape
(frames, rows, columns, channels). If the input has more than 16 frames
then only 16 evenly samples frames will be selected to process.
Returns:
A numpy array.
"""
intervals = np.ceil(np.linspace(0, video.shape[0] - 1, 16)).astype(int)
frames = video[intervals]
# Reshape to 128x171
reshape_frames = np.zeros((frames.shape[0], 128, 171, frames.shape[3]))
for i, img in enumerate(frames):
#the dims are (width, height)
img = np.array(PIL.Image.fromarray(img).resize((171,128), PIL.Image.BICUBIC)) #changed this to use resize from PIL
reshape_frames[i, :, :, :] = img
mean_path = get_file('c3d_mean.npy',
C3D_MEAN_PATH,
cache_subdir='models',
md5_hash='08a07d9761e76097985124d9e8b2fe34')
# Subtract mean
mean = np.load(mean_path)
reshape_frames -= mean
# Crop to 112x112
reshape_frames = reshape_frames[:, 8:120, 30:142, :]
# Add extra dimension for samples
reshape_frames = np.expand_dims(reshape_frames, axis=0)
return reshape_frames
def C3D(weights='sports1M'):
"""Instantiates a C3D Kerasl model
Keyword arguments:
weights -- weights to load into model. (default is sports1M)
Returns:
A Keras model.
"""
if weights not in {'sports1M', None}:
raise ValueError('weights should be either be sports1M or None')
if K.image_data_format() == 'channels_last':
shape = (16, 112, 112,3)
else:
shape = (3, 16, 112, 112)
model = Sequential()
model.add(Conv3D(64, 3, activation='relu', padding='same', name='conv1', input_shape=shape))
model.add(MaxPooling3D(pool_size=(1,2,2), strides=(1,2,2), padding='same', name='pool1'))
model.add(Conv3D(128, 3, activation='relu', padding='same', name='conv2'))
model.add(MaxPooling3D(pool_size=(2,2,2), strides=(2,2,2), padding='valid', name='pool2'))
model.add(Conv3D(256, 3, activation='relu', padding='same', name='conv3a'))
model.add(Conv3D(256, 3, activation='relu', padding='same', name='conv3b'))
model.add(MaxPooling3D(pool_size=(2,2,2), strides=(2,2,2), padding='valid', name='pool3'))
model.add(Conv3D(512, 3, activation='relu', padding='same', name='conv4a'))
model.add(Conv3D(512, 3, activation='relu', padding='same', name='conv4b'))
model.add(MaxPooling3D(pool_size=(2,2,2), strides=(2,2,2), padding='valid', name='pool4'))
model.add(Conv3D(512, 3, activation='relu', padding='same', name='conv5a'))
model.add(Conv3D(512, 3, activation='relu', padding='same', name='conv5b'))
model.add(ZeroPadding3D(padding=(0,1,1)))
model.add(MaxPooling3D(pool_size=(2,2,2), strides=(2,2,2), padding='valid', name='pool5'))
model.add(Flatten())
model.add(Dense(4096, activation='relu', name='fc6'))
model.add(Dropout(0.5))
model.add(Dense(4096, activation='relu', name='fc7'))
model.add(Dropout(0.5))
model.add(Dense(487, activation='softmax', name='fc8'))
if weights == 'sports1M':
model.load_weights(cfg.c3d_model_weights)
return model
def c3d_feature_extractor():
model = C3D()
layer_name = 'fc6'
feature_extractor_model = Model(inputs=model.input, outputs=model.get_layer(layer_name).output)
return feature_extractor_model