ronn12/truth
0
1import os2import cv23import numpy as np4import tensorflow as tf5import librosa6import pandas as pd7from joblib import load8from moviepy.editor import VideoFileClip9from fastapi import FastAPI, UploadFile, File, HTTPException10from starlette.responses import JSONResponse11 12app = FastAPI()13 14UPLOAD_FOLDER = "uploads"15os.makedirs(UPLOAD_FOLDER, exist_ok=True)16 17saved_model = tf.keras.models.load_model("./lstm_without_masking(94).h5")18audio_model = tf.keras.models.load_model("./audio_model.h5")19scaler = load("./scaler.joblib")20 21latest_result = None22 23# Function to validate input video (one person, clear face)24def input_validation(input_video):25 import mediapipe as mp26 mp_face_detection = mp.solutions.face_detection27 face_detection = mp_face_detection.FaceDetection()28 cap = cv2.VideoCapture(input_video)29 30 valid = True31 while cap.isOpened():32 ret, frame = cap.read()33 if not ret:34 break35 rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)36 results = face_detection.process(rgb_frame)37 if not results.detections or len(results.detections) > 1:38 valid = False39 break40 cap.release()41 return valid42 43# Function to check if the video has audio44def check_audio_in_video(video_file):45 video = VideoFileClip(video_file)46 return 1 if video.audio else 047 48# Extract audio from video49def extract_audio_from_video(video_file, audio_file):50 video = VideoFileClip(video_file)51 audio = video.audio52 audio.write_audiofile(audio_file, codec='pcm_s16le')53 54# Split audio into segments55def split_and_pad_audio(audio_file, segment_duration=10, sample_rate=16000):56 segment_samples = segment_duration * sample_rate57 audio, _ = librosa.load(audio_file, sr=sample_rate)58 num_segments = len(audio) // segment_samples59 remainder = len(audio) % segment_samples60 segments = [audio[i * segment_samples : (i + 1) * segment_samples] for i in range(num_segments)]61 if remainder > 0:62 last_segment = np.pad(audio[num_segments * segment_samples:], (0, segment_samples - remainder), mode='constant')63 segments.append(last_segment)64 return segments65 66# Extract MFCC features67def extract_mfcc_from_segments(segments, sample_rate=16000, n_mfcc=13):68 features = []69 for segment in segments:70 mfcc = librosa.feature.mfcc(y=segment, sr=sample_rate, n_mfcc=n_mfcc)71 mfcc_mean = np.mean(mfcc, axis=1)72 mfcc_std = np.std(mfcc, axis=1)73 features.append(np.concatenate([mfcc_mean, mfcc_std]))74 return np.array(features)75 76# Predict audio lie/truth77def make_prediction_audio(input_video):78 if not check_audio_in_video(input_video):79 return [1] # Default to truth if no audio80 audio_file = "extracted_audio.wav"81 extract_audio_from_video(input_video, audio_file)82 segments = split_and_pad_audio(audio_file)83 mfcc_features = extract_mfcc_from_segments(segments)84 mfcc_features = scaler.transform(mfcc_features)85 mfcc_features = np.expand_dims(mfcc_features, axis=1)86 predictions = audio_model.predict(mfcc_features)87 return 1 - np.argmax(predictions, axis=1)88 89# Predict facial lie/truth90def make_prediction(input_video):91 video_capture = cv2.VideoCapture(input_video)92 if not video_capture.isOpened():93 raise HTTPException(status_code=400, detail="Could not open video")94 if not input_validation(input_video):95 raise HTTPException(status_code=400, detail="Video should contain one person with a clear face")96 predictions = []97 frame_count = 098 cur_video32 = []99 while True:100 ret, frame = video_capture.read()101 if not ret:102 break103 frame_count += 1104 cur_video32.append(np.zeros(478 * 3)) # Placeholder since face mesh isn't implemented here105 if frame_count == 32:106 predictions.append(np.argmax(saved_model.predict(np.array([cur_video32]))))107 cur_video32 = []108 frame_count = 0109 video_capture.release()110 return predictions111 112# Final decision function113def final_decision(input_video):114 global latest_result115 voice_preds = make_prediction_audio(input_video)116 face_preds = make_prediction(input_video)117 voice_preds = np.repeat(voice_preds, 10)[:len(face_preds)]118 face_preds = np.pad(face_preds, (0, max(0, len(voice_preds) - len(face_preds))), constant_values=1)119 hard_vote = (voice_preds + face_preds) >= 1120 final_result = "Lie" if np.sum(hard_vote) > len(hard_vote) / 2 else "Truth"121 confidence = (max(np.sum(hard_vote), len(hard_vote) - np.sum(hard_vote)) / len(hard_vote)) * 100122 latest_result = {"final_decision": final_result, "confidence": confidence}123 return latest_result124 125@app.post("/process_video")126async def process_video(video: UploadFile = File(...)):127 file_path = os.path.join(UPLOAD_FOLDER, video.filename)128 with open(file_path, "wb") as f:129 f.write(await video.read())130 result = final_decision(file_path)131 return JSONResponse(content=result)132 133@app.get("/result")134async def get_result():135 if latest_result is None:136 raise HTTPException(status_code=404, detail="No analysis performed yet")137 return JSONResponse(content=latest_result)138 