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