Spaces:
Runtime error
Runtime error
Commit ·
0f220e9
1
Parent(s): 59d3dd1
first release
Browse files- .gitignore +4 -0
- app.py +12 -4
- config.py +49 -0
- requirements.txt +5 -0
- utils.py +76 -0
.gitignore
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
**/__pycache__
|
| 2 |
+
flagged/
|
| 3 |
+
models/
|
| 4 |
+
static/
|
app.py
CHANGED
|
@@ -1,7 +1,15 @@
|
|
| 1 |
import gradio as gr
|
|
|
|
|
|
|
| 2 |
|
| 3 |
-
def
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
import utils
|
| 3 |
+
from config import KINETICS_600_LABELS, MODEL
|
| 4 |
|
| 5 |
+
def get_predictions(video_path):
|
| 6 |
+
video, frame_list = utils.preprocess_video(video_path)
|
| 7 |
+
model = MODEL
|
| 8 |
+
probs = model(video)
|
| 9 |
+
labels = utils.get_top_k(probs, label_map=KINETICS_600_LABELS)
|
| 10 |
+
return labels
|
| 11 |
|
| 12 |
+
label = gr.components.Label(num_top_classes=5)
|
| 13 |
+
vd = gr.components.Video()
|
| 14 |
+
iface = gr.Interface(fn=get_predictions, inputs=vd, outputs=label)
|
| 15 |
+
iface.launch(debug=True)
|
config.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import tensorflow as tf
|
| 2 |
+
import tensorflow_hub as hub
|
| 3 |
+
from keras.models import load_model
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
import numpy as np
|
| 6 |
+
import config
|
| 7 |
+
import os
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
FRAME_HT = 224
|
| 11 |
+
FRAME_WD = 224
|
| 12 |
+
FRAME_NUM = 8
|
| 13 |
+
TENSORFLOW_HUB_URL_LABELS = "https://raw.githubusercontent.com/tensorflow/models/f8af2291cced43fc9f1d9b41ddbf772ae7b0d7d2/official/projects/movinet/files/kinetics_600_labels.txt"
|
| 14 |
+
TENSORFLOW_HUB_URL_MODEL = "https://tfhub.dev/tensorflow/movinet/a2/base/kinetics-600/classification/3"
|
| 15 |
+
MODEL_PATH = os.path.join(os.getcwd(), 'models', 'Activity_recognition.h5')
|
| 16 |
+
|
| 17 |
+
def get_labels():
|
| 18 |
+
|
| 19 |
+
labels_path = tf.keras.utils.get_file(
|
| 20 |
+
fname=os.path.join(os.getcwd(), 'static', 'labels.txt'),
|
| 21 |
+
origin=config.TENSORFLOW_HUB_URL_LABELS
|
| 22 |
+
)
|
| 23 |
+
|
| 24 |
+
labels_path = Path(labels_path)
|
| 25 |
+
|
| 26 |
+
lines = labels_path.read_text().splitlines()
|
| 27 |
+
KINETICS_600_LABELS = np.array([line.strip() for line in lines])
|
| 28 |
+
|
| 29 |
+
return KINETICS_600_LABELS
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def get_model():
|
| 33 |
+
encoder = hub.KerasLayer(TENSORFLOW_HUB_URL_MODEL, trainable=True)
|
| 34 |
+
|
| 35 |
+
inputs = tf.keras.layers.Input(
|
| 36 |
+
shape=[FRAME_NUM, FRAME_HT, FRAME_WD, 3],
|
| 37 |
+
dtype=tf.float32,
|
| 38 |
+
name='image'
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
# [batch_size, 600]
|
| 42 |
+
outputs = encoder(dict(image=inputs))
|
| 43 |
+
|
| 44 |
+
model = tf.keras.Model(inputs, outputs, name='movinet')
|
| 45 |
+
|
| 46 |
+
return model
|
| 47 |
+
|
| 48 |
+
KINETICS_600_LABELS = get_labels()
|
| 49 |
+
MODEL = get_model()
|
requirements.txt
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
tensorflow-cpu
|
| 3 |
+
tensorflow-hub
|
| 4 |
+
numpy
|
| 5 |
+
opencv-python
|
utils.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import tensorflow as tf
|
| 2 |
+
import cv2
|
| 3 |
+
import os
|
| 4 |
+
import numpy as np
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
import config
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def preprocess_video(video_path : str) :
|
| 13 |
+
# load the video
|
| 14 |
+
video_capture = cv2.VideoCapture(video_path)
|
| 15 |
+
|
| 16 |
+
# the number of frames in the original video
|
| 17 |
+
original_number_of_frames = video_capture.get(cv2.CAP_PROP_FRAME_COUNT)
|
| 18 |
+
|
| 19 |
+
# gap between two consecutive frames to capture
|
| 20 |
+
frame_interval = int(original_number_of_frames / config.FRAME_NUM)
|
| 21 |
+
|
| 22 |
+
new_video , frame_list = [] , []
|
| 23 |
+
for i in range(0, config.FRAME_NUM ):
|
| 24 |
+
video_capture.set(cv2.CAP_PROP_POS_FRAMES, i*frame_interval)
|
| 25 |
+
success, frame = video_capture.read()
|
| 26 |
+
|
| 27 |
+
if not success :
|
| 28 |
+
print("video loading failed")
|
| 29 |
+
|
| 30 |
+
frame_list.append(frame)
|
| 31 |
+
# Resize the Frame to fixed height and width.
|
| 32 |
+
resized_frame = cv2.resize(frame, (config.FRAME_HT, config.FRAME_WD))
|
| 33 |
+
|
| 34 |
+
# Normalize the resized frame by dividing it with 255 so that each pixel value then lies between 0 and 1
|
| 35 |
+
normalized_frame = resized_frame / 255
|
| 36 |
+
|
| 37 |
+
# Append the normalized frame into the frames list
|
| 38 |
+
new_video.append(normalized_frame)
|
| 39 |
+
|
| 40 |
+
new_video_array = np.asarray(new_video)
|
| 41 |
+
|
| 42 |
+
input_tensor = tf.expand_dims(new_video_array, axis=0)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
video_capture.release()
|
| 46 |
+
|
| 47 |
+
return input_tensor, frame_list
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
# Get top_k labels and probabilities
|
| 51 |
+
def get_top_k(probs, label_map,k=5 ):
|
| 52 |
+
"""Outputs the top k model labels and probabilities on the given video.
|
| 53 |
+
|
| 54 |
+
Args:
|
| 55 |
+
probs: probability tensor of shape (num_frames, num_classes) that represents
|
| 56 |
+
the probability of each class on each frame.
|
| 57 |
+
k: the number of top predictions to select.
|
| 58 |
+
label_map: a list of labels to map logit indices to label strings.
|
| 59 |
+
|
| 60 |
+
Returns:
|
| 61 |
+
a tuple of the top-k labels and probabilities.
|
| 62 |
+
"""
|
| 63 |
+
# Sort predictions to find top_k
|
| 64 |
+
indices = tf.argsort(probs, direction='DESCENDING').numpy()[0][:k]
|
| 65 |
+
# collect the labels of top_k predictions
|
| 66 |
+
labels = tf.gather(label_map, indices).numpy()
|
| 67 |
+
# decode lablels
|
| 68 |
+
labels = [label.decode('utf8') for label in labels]
|
| 69 |
+
# top_k probabilities of the predictions
|
| 70 |
+
top_probs = tf.gather(probs[0], indices).numpy()
|
| 71 |
+
|
| 72 |
+
output = dict()
|
| 73 |
+
for label, prob in zip(labels, top_probs):
|
| 74 |
+
output[label] = float(prob) / 100
|
| 75 |
+
print(output)
|
| 76 |
+
return output
|