SummerAIse / FrameProcessor /graph /steps /extract_features.py
Israaabdelghany's picture
update
0d9760b
Raw
History Blame Contribute Delete
2.19 kB
# FrameProcessor/graph/steps/extract_features.py
import os
import cv2
import base64
import numpy as np
from PIL import Image
from io import BytesIO
from typing import Dict, Any
from langgraph.graph import StateGraph, END
from types_.state import GraphState
def extract_frame_features(state: GraphState) -> GraphState:
"""Extracts visual features from the frame image."""
frame_path = state["frame_path"]
try:
img = cv2.imread(frame_path)
if img is None:
state["frame_features"] = {"error": "Failed to load frame"}
state["next_step"] = "evaluate_importance"
return state
height, width, channels = img.shape
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
contrast = np.std(gray)
brightness = np.mean(gray)
dark_pixels = np.sum(gray < 30) / (height * width)
color_variance = np.var(img.reshape(-1, 3), axis=0).sum()
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
has_faces = len(faces) > 0
state["frame_features"] = {
"dimensions": {"height": height, "width": width},
"contrast": float(contrast),
"brightness": float(brightness),
"dark_ratio": float(dark_pixels),
"color_variance": float(color_variance),
"has_faces": has_faces,
"face_count": len(faces),
}
# Convert to base64
pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
buffered = BytesIO()
pil_img.save(buffered, format="JPEG")
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
state["frame_data"] = {
"base64_image": img_str,
"file_name": os.path.basename(frame_path)
}
except Exception as e:
print(f"Error extracting frame features: {str(e)}")
state["frame_features"] = {"error": f"Feature extraction failed: {str(e)}"}
state["frame_data"] = {"file_name": os.path.basename(frame_path)}
state["next_step"] = "evaluate_importance"
return state