cailean
1 month ago
commit
213321e0fc
6 changed files with 91035 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||
/main_dataset/ |
|||
/dataset/ |
@ -0,0 +1,167 @@ |
|||
from deepface import DeepFace |
|||
import os |
|||
import glob |
|||
import json |
|||
import numpy as np |
|||
|
|||
baseFolderPath = "main_dataset" |
|||
lostFolderPath = "lost-images" |
|||
output_file = "sv_embeddings.json" |
|||
|
|||
embeddings = [] |
|||
|
|||
backends = [ |
|||
'opencv', |
|||
'ssd', |
|||
'dlib', |
|||
'mtcnn', |
|||
'fastmtcnn', |
|||
'retinaface', |
|||
'mediapipe', |
|||
'yolov8', |
|||
'yunet', |
|||
'centerface', |
|||
] |
|||
|
|||
def main(): |
|||
video_folders = setup() |
|||
for folder_info in video_folders: |
|||
|
|||
foldername, video_path, image_paths = folder_info |
|||
|
|||
print(f"Processing {foldername}\n") |
|||
|
|||
run(image_paths, foldername, video_path) |
|||
saveToJson() |
|||
|
|||
def processImage(image, idx, foldername, video_path): |
|||
try: |
|||
|
|||
print(f"Processing {image}", end="\r") |
|||
|
|||
# Initialize variables to accumulate sums |
|||
sums = { |
|||
'angry': 0, |
|||
'disgust': 0, |
|||
'fear': 0, |
|||
'happy': 0, |
|||
'sad': 0, |
|||
'surprise': 0, |
|||
'neutral': 0 |
|||
} |
|||
|
|||
anaylse_obj = DeepFace.analyze( |
|||
img_path=image, |
|||
actions=['emotion'], |
|||
enforce_detection=True, |
|||
detector_backend=backends[5], |
|||
silent=True |
|||
) |
|||
|
|||
emotions = anaylse_obj[0]['emotion'] |
|||
|
|||
selected_emotions = [ |
|||
emotions['happy'], |
|||
emotions['sad'], |
|||
emotions['angry'], |
|||
emotions['neutral'] |
|||
] |
|||
|
|||
num_of_faces = len(anaylse_obj) |
|||
|
|||
# Get average emotion |
|||
# for face in anaylse_obj: |
|||
# emotions = face['emotion'] |
|||
# for emotion in sums: |
|||
# sums[emotion] += emotions.get(emotion, 0) |
|||
|
|||
# averages = {emotion: sums[emotion] / num_of_faces for emotion in sums} |
|||
|
|||
raw_emotions = [value for value in emotions.values()] |
|||
|
|||
#normalized_emotions = [value / 100 for value in raw_emotions] |
|||
|
|||
normalized_emotions = [value / 100 for value in selected_emotions] |
|||
|
|||
|
|||
#normalised_emotions = l2_normalize(np.array(raw_emotions)) |
|||
|
|||
# normalised_emotions = normalised_emotions.tolist() |
|||
|
|||
entry = { |
|||
"folder": foldername, |
|||
"image": image, # Extract the filename from the path |
|||
"error": 0, |
|||
"vector": normalized_emotions |
|||
} |
|||
|
|||
# Add the entry to the JSON data list |
|||
embeddings.append(entry) |
|||
except: |
|||
# if model does not detect any emotions |
|||
# set lost -> 1 & generate a random emotion vector |
|||
random_vector = np.random.rand(4) |
|||
random_vector_list = random_vector.tolist() |
|||
|
|||
entry = { |
|||
"folder": foldername, |
|||
"image": image, # Extract the filename from the path |
|||
"error": 1, |
|||
"vector": random_vector_list |
|||
} |
|||
|
|||
# Add the entry to the JSON data list |
|||
embeddings.append(entry) |
|||
pass |
|||
|
|||
print(entry["vector"]) |
|||
|
|||
|
|||
|
|||
def setup(): |
|||
video_folders = [] |
|||
|
|||
subfolders = [f.path for f in os.scandir(baseFolderPath) if f.is_dir()] |
|||
|
|||
for subfolder in subfolders: |
|||
frames_folder_path = os.path.join(subfolder, "segmented_images") |
|||
|
|||
# Find the video file in the subfolder |
|||
# video_files = [f for f in os.listdir(subfolder) if f.endswith(('.mp4', '.avi', '.mov'))] |
|||
# if video_files: |
|||
# video_path = os.path.join(subfolder, video_files[0]) |
|||
|
|||
# List of all image files in the frames folder |
|||
image_files = glob.glob(os.path.join(frames_folder_path, '*')) |
|||
|
|||
# Filter by specific image extensions (e.g., .jpg, .png) |
|||
image_paths = [img for img in image_files if img.endswith(('.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.gif'))] |
|||
|
|||
# Sort the image paths by filename (assuming the filenames are numerically ordered) |
|||
image_paths.sort(key=lambda x: int(os.path.splitext(os.path.basename(x))[0])) |
|||
|
|||
video_path = "null" |
|||
|
|||
# Add the information to the list |
|||
video_folders.append((os.path.basename(subfolder), video_path, image_paths)) |
|||
|
|||
return video_folders |
|||
|
|||
|
|||
def run(image_paths, foldername, video_path): |
|||
for idx, image in enumerate(image_paths): |
|||
processImage(image, idx, foldername, video_path) |
|||
|
|||
def l2_normalize(vector): |
|||
norm = np.linalg.norm(vector) |
|||
if norm == 0: |
|||
return vector |
|||
return vector / norm |
|||
|
|||
def saveToJson(): |
|||
with open(output_file, 'w') as f: |
|||
json.dump(embeddings, f, indent=4) |
|||
print("Successfully created JSON file.") |
|||
|
|||
if __name__ == "__main__": |
|||
main() |
@ -0,0 +1,117 @@ |
|||
import os |
|||
import subprocess |
|||
import re |
|||
import shutil |
|||
|
|||
def convert_video(video_path, output_path): |
|||
print(f"Converting video, {video_path}") |
|||
|
|||
# Codec that works with openframeworks! |
|||
|
|||
command = [ |
|||
"ffmpeg", |
|||
"-i", video_path, # Input file |
|||
"-c:v", "libx264", # Video codec |
|||
"-profile:v", "high", # Video profile |
|||
"-c:a", "copy", # Copy audio without re-encoding |
|||
output_path # Output file |
|||
] |
|||
|
|||
results = subprocess.run(command, stderr=subprocess.PIPE, text=True) |
|||
output = results.stderr |
|||
|
|||
print(f"Video converted {output}") |
|||
|
|||
def get_frame_rate(video_path): |
|||
""" |
|||
Get the frame rate of a video file using ffmpeg. |
|||
""" |
|||
command = [ |
|||
'ffmpeg', |
|||
'-i', video_path, |
|||
'-vcodec', 'png', |
|||
'-f', 'null', |
|||
'-' |
|||
] |
|||
|
|||
result = subprocess.run(command, stderr=subprocess.PIPE, text=True) |
|||
output = result.stderr |
|||
|
|||
match = re.search(r'(\d+(\.\d+)?) fps', output) |
|||
if match: |
|||
return float(match.group(1)) |
|||
else: |
|||
raise ValueError("Frame rate not found in video information.") |
|||
|
|||
def extract_frames_from_video(video_path, output_folder): |
|||
""" |
|||
Extract frames from a video file at 1 fps. |
|||
""" |
|||
os.makedirs(output_folder, exist_ok=True) |
|||
|
|||
command = [ |
|||
'ffmpeg', |
|||
'-i', video_path, # Input file |
|||
'-vf', 'fps=1/10', # Extract 1 frame per second |
|||
'-vsync', 'vfr', # Variable frame rate |
|||
os.path.join(output_folder, 'frame_%09d.png') # Output pattern |
|||
] |
|||
|
|||
subprocess.run(command, check=True) |
|||
|
|||
def rename_frames(output_folder, frame_rate): |
|||
""" |
|||
Rename the extracted frames to match their original frame numbers. |
|||
""" |
|||
frame_files = sorted(f for f in os.listdir(output_folder) if f.startswith('frame_') and f.endswith('.png')) |
|||
for i, filename in enumerate(frame_files): |
|||
# Calculate the original frame number |
|||
original_frame_number = int(i * frame_rate) |
|||
|
|||
# Create the new filename with the original frame number |
|||
new_filename = f"{original_frame_number:09d}.png" |
|||
os.rename( |
|||
os.path.join(output_folder, filename), |
|||
os.path.join(output_folder, new_filename) |
|||
) |
|||
|
|||
def process_videos_in_folder(folder_path): |
|||
""" |
|||
Process all video files in the specified folder and extract frames from each video. |
|||
""" |
|||
for filename in os.listdir(folder_path): |
|||
if filename.lower().endswith(('.mp4', '.avi', '.mov', '.mkv', '.flv')): |
|||
|
|||
video_path = os.path.join(folder_path, filename) |
|||
|
|||
output_folder = os.path.join(folder_path, os.path.splitext(filename)[0]) # Create a folder for each video |
|||
|
|||
# New location for .mp4 |
|||
video_copy_location = os.path.join(output_folder, filename) |
|||
|
|||
# Create frames folder |
|||
frames_folder = os.path.join(output_folder, "frames") |
|||
|
|||
if not os.path.exists(output_folder): |
|||
os.mkdir(output_folder) |
|||
|
|||
if not os.path.exists(frames_folder): |
|||
os.mkdir(frames_folder) |
|||
|
|||
print(f'Processing video: {video_path}') |
|||
|
|||
try: |
|||
#convert_video(video_path, video_copy_location) |
|||
frame_rate = get_frame_rate(video_path) |
|||
print(f'Original frame rate: {frame_rate} fps') |
|||
extract_frames_from_video(video_path, frames_folder) |
|||
rename_frames(frames_folder, frame_rate) |
|||
print(f'Frames saved and renamed to: {frames_folder}') |
|||
except ValueError as e: |
|||
print(f'Error processing video {video_path}: {e}') |
|||
|
|||
if __name__ == "__main__": |
|||
# Path to the folder containing videos |
|||
folder_path = 'main_dataset' |
|||
|
|||
process_videos_in_folder(folder_path) |
@ -0,0 +1,74 @@ |
|||
absl-py==2.1.0 |
|||
astunparse==1.6.3 |
|||
beautifulsoup4==4.12.3 |
|||
blinker==1.8.2 |
|||
certifi==2024.7.4 |
|||
charset-normalizer==3.3.2 |
|||
click==8.1.7 |
|||
deepface==0.0.93 |
|||
filelock==3.15.4 |
|||
fire==0.6.0 |
|||
Flask==3.0.3 |
|||
Flask-Cors==5.0.0 |
|||
flatbuffers==24.3.25 |
|||
gast==0.6.0 |
|||
gdown==5.2.0 |
|||
google-pasta==0.2.0 |
|||
grpcio==1.65.4 |
|||
gunicorn==23.0.0 |
|||
h5py==3.11.0 |
|||
idna==3.7 |
|||
importlib_metadata==8.2.0 |
|||
itsdangerous==2.2.0 |
|||
Jinja2==3.1.4 |
|||
keras==3.5.0 |
|||
libclang==18.1.1 |
|||
Markdown==3.6 |
|||
markdown-it-py==3.0.0 |
|||
MarkupSafe==2.1.5 |
|||
mdurl==0.1.2 |
|||
ml-dtypes==0.4.0 |
|||
mtcnn==0.1.1 |
|||
namex==0.0.8 |
|||
numpy==1.26.4 |
|||
nvidia-cublas-cu12==12.3.4.1 |
|||
nvidia-cuda-cupti-cu12==12.3.101 |
|||
nvidia-cuda-nvcc-cu12==12.3.107 |
|||
nvidia-cuda-nvrtc-cu12==12.3.107 |
|||
nvidia-cuda-runtime-cu12==12.3.101 |
|||
nvidia-cudnn-cu12==8.9.7.29 |
|||
nvidia-cufft-cu12==11.0.12.1 |
|||
nvidia-curand-cu12==10.3.4.107 |
|||
nvidia-cusolver-cu12==11.5.4.101 |
|||
nvidia-cusparse-cu12==12.2.0.103 |
|||
nvidia-nccl-cu12==2.19.3 |
|||
nvidia-nvjitlink-cu12==12.3.101 |
|||
opencv-python==4.10.0.84 |
|||
opt-einsum==3.3.0 |
|||
optree==0.12.1 |
|||
packaging==24.1 |
|||
pandas==2.2.2 |
|||
pillow==10.4.0 |
|||
protobuf==4.25.4 |
|||
Pygments==2.18.0 |
|||
PySocks==1.7.1 |
|||
python-dateutil==2.9.0.post0 |
|||
pytz==2024.1 |
|||
requests==2.32.3 |
|||
retina-face==0.0.17 |
|||
rich==13.7.1 |
|||
six==1.16.0 |
|||
soupsieve==2.6 |
|||
tensorboard==2.17.1 |
|||
tensorboard-data-server==0.7.2 |
|||
tensorflow==2.17.0 |
|||
tensorflow-io-gcs-filesystem==0.37.1 |
|||
termcolor==2.4.0 |
|||
tf_keras==2.17.0 |
|||
tqdm==4.66.5 |
|||
typing_extensions==4.12.2 |
|||
tzdata==2024.1 |
|||
urllib3==2.2.2 |
|||
Werkzeug==3.0.3 |
|||
wrapt==1.16.0 |
|||
zipp==3.20.0 |
File diff suppressed because it is too large
Loading…
Reference in new issue