Muhammad Haris
Update app.py
ff3ab89 verified
import tensorflow as tf
import cv2
import numpy as np
import gradio as gr
import math
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
class ShopliftingPrediction:
def __init__(self, model_path, frame_width, frame_height, sequence_length):
self.frame_width = frame_width
self.frame_height = frame_height
self.sequence_length = sequence_length
self.model_path = model_path
self.message = ''
def load_model(self):
# Define custom objects for loading the model
custom_objects = {
'Conv2D': tf.keras.layers.Conv2D,
'MaxPooling2D': tf.keras.layers.MaxPooling2D,
'TimeDistributed': tf.keras.layers.TimeDistributed,
'LSTM': tf.keras.layers.LSTM,
'Dense': tf.keras.layers.Dense,
'Flatten': tf.keras.layers.Flatten,
'Dropout': tf.keras.layers.Dropout,
'Orthogonal': tf.keras.initializers.Orthogonal,
}
# Load the model with custom objects
self.model = tf.keras.models.load_model(self.model_path, custom_objects=custom_objects)
logging.info("Model loaded successfully.")
def generate_message_content(self, probability, label):
if label == 0:
if probability <=50:
self.message = "No theft"
elif probability <= 75:
self.message = "There is little chance of theft"
elif probability <= 85:
self.message = "High probability of theft"
else:
self.message = "Very high probability of theft"
elif label == 1:
if probability <=50:
self.message = "No theft"
elif probability <= 75:
self.message = "The movement is confusing, watch"
elif probability <= 85:
self.message = "I think it's normal, but it's better to watch"
else:
self.message = "Movement is normal"
def Pre_Process_Video(self, current_frame, previous_frame):
diff = cv2.absdiff(current_frame, previous_frame)
diff = cv2.GaussianBlur(diff, (3, 3), 0)
resized_frame = cv2.resize(diff, (self.frame_height, self.frame_width))
gray_frame = cv2.cvtColor(resized_frame, cv2.COLOR_BGR2GRAY)
normalized_frame = gray_frame / 255
return normalized_frame
def Read_Video(self, filePath):
self.video_reader = cv2.VideoCapture(filePath)
self.original_video_width = int(self.video_reader.get(cv2.CAP_PROP_FRAME_WIDTH))
self.original_video_height = int(self.video_reader.get(cv2.CAP_PROP_FRAME_HEIGHT))
self.fps = self.video_reader.get(cv2.CAP_PROP_FPS)
def Single_Frame_Predict(self, frames_queue):
probabilities = self.model.predict(np.expand_dims(frames_queue, axis=0))[0]
predicted_label = np.argmax(probabilities)
probability = math.floor(max(probabilities[0], probabilities[1]) * 100)
return [probability, predicted_label]
def Predict_Video(self, video_file_path, output_file_path):
self.load_model()
self.Read_Video(video_file_path)
video_writer = cv2.VideoWriter(output_file_path, cv2.VideoWriter_fourcc('M', 'P', '4', 'V'),
self.fps, (self.original_video_width, self.original_video_height))
success, frame = self.video_reader.read()
previous = frame.copy()
frames_queue = []
while self.video_reader.isOpened():
ok, frame = self.video_reader.read()
if not ok:
break
normalized_frame = self.Pre_Process_Video(frame, previous)
previous = frame.copy()
frames_queue.append(normalized_frame)
if len(frames_queue) == self.sequence_length:
[probability, predicted_label] = self.Single_Frame_Predict(frames_queue)
self.generate_message_content(probability, predicted_label)
message = "{}:{}%".format(self.message, probability)
frames_queue = []
logging.info(message)
cv2.rectangle(frame, (0, 0), (640, 40), (255, 255, 255), -1)
cv2.putText(frame, self.message, (1, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
video_writer.write(frame)
self.video_reader.release()
video_writer.release()
return output_file_path
def inference(model_path):
shoplifting_prediction = ShopliftingPrediction(model_path, 90, 90, sequence_length=160)
def process_video(video_path):
output_file_path = '/tmp/output.mp4'
return shoplifting_prediction.Predict_Video(video_path, output_file_path)
return process_video
model_path = 'lrcn_160S_90_90Q.h5'
process_video = inference(model_path)
iface = gr.Interface(
fn=process_video,
inputs=gr.Video(),
outputs="video",
live=True,
)
iface.launch()