DetectMeBotBackend / backend /app /services /image_analyzer.py
Gradii's picture
fixed images
1e931f8
Raw
History Blame
3.18 kB
import io
import logging
import time
import gc
from typing import Dict, Any
from PIL import Image
from transformers import pipeline
# Importujemy helper do konfiguracji oraz wyj膮tek braku konfiguracji
from app.config_manager import get_active_image_model
from app.utils.exceptions import SetupRequiredError
logger = logging.getLogger(__name__)
# Przechowujemy referencje do aktualnie za艂adowanego modelu obraz贸w
_loaded_model_name = None
_image_classifier = None
def _load_model(target_model_name: str):
global _image_classifier, _loaded_model_name
# Je艣li model o tej nazwie jest ju偶 za艂adowany w pami臋ci, u偶ywamy go ponownie
if _image_classifier is not None and _loaded_model_name == target_model_name:
return _image_classifier
logger.info(f"Wymagana zmiana modelu obrazu. Obecny w RAM: {_loaded_model_name}, Nowy: {target_model_name}")
# Czyszczenie pami臋ci po poprzednim modelu obraz贸w
_image_classifier = None
gc.collect()
logger.info(f"艁adowanie modelu image detector: {target_model_name}...")
_image_classifier = pipeline(
"image-classification",
model=target_model_name,
device=-1 # -1 oznacza CPU
)
_loaded_model_name = target_model_name
logger.info(f"Model {target_model_name} zosta艂 pomy艣lnie za艂adowany.")
return _image_classifier
async def analyze_image(image_bytes: bytes, guild_id: str) -> Dict[str, Any]:
start_time = time.time()
# 1. Sprawdzamy konfiguracj臋 modelu dla danego serwera Discord
active_model = get_active_image_model(guild_id)
# BLOKADA: Je偶eli model to 'none' lub brak konfiguracji, natychmiast przerywamy i zg艂aszamy b艂膮d
if not active_model:
logger.warning(f"Zablokowano zapytanie! Serwer {guild_id} nie ma skonfigurowanego modelu dla obraz贸w.")
raise SetupRequiredError(
f"Serwer o ID '{guild_id}' nie zosta艂 jeszcze skonfigurowany pod k膮tem analizy obraz贸w. "
"U偶yj komendy setup na Discordzie przed wykonaniem analizy."
)
logger.info(f"Starting image analysis for guild: {guild_id}, model: {active_model}, size: {len(image_bytes)} bytes")
try:
image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
except Exception as e:
logger.error(f"Failed to parse image bytes: {str(e)}")
raise ValueError("Invalid image format or corrupted bytes") from e
# 2. Dynamicznie pobieramy/艂adujemy wskazany model
classifier = _load_model(active_model)
result = classifier(image)
label = result[0]["label"]
score = result[0]["score"]
# Dostosowanie do najcz臋stszych etykiet fa艂szywych obraz贸w (np. "fake", "ai", "synthetic")
is_deepfake = label.lower() in ["fake", "ai", "synthetic", "label_1"]
confidence = score
analysis_time = time.time() - start_time
response = {
"is_deepfake": is_deepfake,
"confidence": round(confidence, 3),
"analysis_time": round(analysis_time, 3),
"used_model": active_model,
}
logger.info(f"Image analysis completed. Result: {response}")
return response