ArtificalFaceDetector / src /image_manager.py
VanKee's picture
hw2
6f6e572
"""
Image Management Module
Responsible for indexing, validating, and selecting facial images required for the game.
"""
import os
import random
from pathlib import Path
from typing import List, Dict, Literal
class ImagePool:
"""Manages indexing and selection of AI-generated and real human face images"""
def __init__(self, ai_dir: str = "image/ai", real_dir: str = "image/real"):
"""
Initialize image pool
Args:
ai_dir: Directory path for AI-generated images
real_dir: Directory path for real human images
Raises:
ValueError: If either directory contains less than 10 images
"""
self.ai_dir = ai_dir
self.real_dir = real_dir
self.ai_images = self._scan_directory(ai_dir)
self.real_images = self._scan_directory(real_dir)
self.validate()
def _scan_directory(self, directory: str) -> List[str]:
"""
Scan directory and return paths of all valid image files
Args:
directory: Directory path to scan
Returns:
List of image file paths
"""
valid_extensions = {'.jpg', '.jpeg', '.png', '.webp', '.bmp'}
image_paths = []
if not os.path.exists(directory):
return image_paths
for file in Path(directory).rglob('*'):
if file.is_file() and file.suffix.lower() in valid_extensions:
image_paths.append(str(file))
return sorted(image_paths) # Sort for consistency
@property
def total_ai(self) -> int:
"""Return total number of AI-generated images"""
return len(self.ai_images)
@property
def total_real(self) -> int:
"""Return total number of real human images"""
return len(self.real_images)
def validate(self) -> None:
"""
Validate that image count meets requirements
Raises:
ValueError: If either category has less than 10 images
"""
if self.total_ai < 10:
raise ValueError(
f"Insufficient AI images: need at least 10, found {self.total_ai} in {self.ai_dir}"
)
if self.total_real < 10:
raise ValueError(
f"Insufficient real images: need at least 10, found {self.total_real} in {self.real_dir}"
)
def create_game_set(self) -> List[Dict[str, str]]:
"""
Create a random set of 20 images for a new game (10 AI + 10 real)
Returns:
List of 20 ImageItem dictionaries, each containing 'path' and 'label' fields
Images are in random order
"""
# Randomly select 10 AI images
selected_ai = random.sample(self.ai_images, 10)
# Randomly select 10 real images
selected_real = random.sample(self.real_images, 10)
# Create ImageItem dictionary list
all_images = [
{"path": path, "label": "AI"} for path in selected_ai
] + [
{"path": path, "label": "Human"} for path in selected_real
]
# Shuffle order
random.shuffle(all_images)
return all_images
def get_random_image(self, label: Literal["AI", "Human"]) -> str:
"""
Get a random image path from specified category
Args:
label: Image category, "AI" or "Human"
Returns:
Randomly selected image path
"""
if label == "AI":
return random.choice(self.ai_images)
else:
return random.choice(self.real_images)