deepfake-shield-api / utils /frame_processor.py
adidtiya
Deploy Deepfake Shield Backend v2.0
91491b1
Raw History Blame Contribute Delete
3.76 kB
"""
frame_processor.py
==================
Utilitas untuk preprocessing frame video sebelum dimasukkan ke model.
Termasuk: resize, quality enhancement, dan konversi format.
"""
import cv2
import numpy as np
from typing import Tuple, Optional
def decode_base64_frame(b64_string: str) -> Optional[np.ndarray]:
"""
Decode string base64 menjadi frame OpenCV BGR.
Args:
b64_string: String base64 (dengan atau tanpa data URL prefix)
Returns:
numpy array [H, W, 3] BGR, atau None jika gagal
"""
import base64
# Hapus prefix data URL jika ada
if "," in b64_string:
b64_string = b64_string.split(",", 1)[1]
try:
# Decode base64 → bytes → numpy
raw_bytes = base64.b64decode(b64_string)
arr = np.frombuffer(raw_bytes, dtype=np.uint8)
frame = cv2.imdecode(arr, cv2.IMREAD_COLOR)
return frame
except Exception:
return None
def preprocess_frame(
frame: np.ndarray,
target_size: Tuple[int, int] = (640, 480),
enhance_quality: bool = True
) -> np.ndarray:
"""
Preprocess frame video untuk optimasi deteksi.
Args:
frame : Frame BGR dari OpenCV
target_size : (width, height) target untuk resize
enhance_quality: Terapkan CLAHE untuk perbaikan kontras
Returns:
Frame BGR yang sudah dipreprocess
"""
# Resize frame jika terlalu besar (menghemat waktu proses)
h, w = frame.shape[:2]
target_w, target_h = target_size
# Hanya resize jika lebih besar dari target
if w > target_w or h > target_h:
frame = cv2.resize(frame, target_size, interpolation=cv2.INTER_LINEAR)
# CLAHE (Contrast Limited Adaptive Histogram Equalization)
# Meningkatkan kontras lokal untuk membantu deteksi wajah
if enhance_quality:
lab = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB) # Konversi ke LAB color space
l_channel, a, b = cv2.split(lab)
# Terapkan CLAHE hanya pada channel L (luminance/kecerahan)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
l_enhanced = clahe.apply(l_channel)
# Gabungkan kembali channel
enhanced_lab = cv2.merge([l_enhanced, a, b])
frame = cv2.cvtColor(enhanced_lab, cv2.COLOR_LAB2BGR)
return frame
def draw_detection_overlay(
frame: np.ndarray,
face_boxes: list,
label: str,
score: float
) -> np.ndarray:
"""
Gambar bounding box dan label deteksi di atas frame.
Args:
frame : Frame BGR
face_boxes: List of [x, y, w, h] dalam piksel
label : Label deteksi ('REAL', 'FAKE', 'UNCERTAIN')
score : Skor keaslian (0.0 - 1.0)
Returns:
Frame dengan overlay
"""
# Pilih warna berdasarkan label
color_map = {
"REAL" : (0, 255, 100), # Hijau neon
"FAKE" : (0, 50, 255), # Merah
"UNCERTAIN": (0, 165, 255), # Oranye
"NO_FACE" : (128, 128, 128), # Abu-abu
}
color = color_map.get(label, (255, 255, 255))
# Gambar bounding box untuk setiap wajah
for (x, y, w, h) in face_boxes:
# Bounding box utama
cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
# Label teks di atas bounding box
label_text = f"{label} {score:.0%}"
cv2.putText(
frame, label_text,
(x, max(y - 10, 10)), # Posisi: di atas bbox, minimal y=10
cv2.FONT_HERSHEY_SIMPLEX, # Font
0.7, # Scale
color, # Warna
2, # Tebal
cv2.LINE_AA # Anti-aliasing
)
return frame