from flask import Flask, request, send_file import cv2 import numpy as np import io import os import easyocr import requests from PIL import Image, ImageFilter, ImageEnhance app = Flask(__name__) # --- MODEL YÜKLEMELERİ --- print("OCR Modeli Yükleniyor...") # EasyOCR model yolu model_storage = os.environ.get('EASYOCR_MODULE_PATH', './.EasyOCR') reader = easyocr.Reader(['en', 'tr'], gpu=False, model_storage_directory=model_storage) print("OCR Modeli Hazır.") # --- YENİ NESİL YÜZ TANIMA (YUNET) --- # Haar Cascade yerine Deep Learning tabanlı yüz tanıma kullanıyoruz. def get_face_detector(): face_model_path = "face_detection_yunet_2023mar.onnx" if not os.path.exists(face_model_path): print("Gelişmiş Yüz Tanıma AI Modeli İndiriliyor...") # OpenCV Zoo'dan resmi YuNet modeli url = "https://github.com/opencv/opencv_zoo/raw/master/models/face_detection_yunet/face_detection_yunet_2023mar.onnx" try: resp = requests.get(url) with open(face_model_path, "wb") as f: f.write(resp.content) print("Model İndirildi.") except Exception as e: print(f"Model indirilemedi: {e}") return None # OpenCV DNN Modülü ile modeli yükle return cv2.FaceDetectorYN.create( face_model_path, "", (320, 320), # Başlangıç boyutu, dinamik olarak değişecek 0.6, # Score threshold (Emin olma oranı) 0.3, # NMS threshold 5000 # Top K ) face_detector = get_face_detector() print("Yapay Zeka Yüz Tanıma Hazır.") # --- İŞLEME FONKSİYONLARI --- def apply_smart_eco_polish(img_pil): # Renkleri ve kontrastı hafifçe canlandır img_pil = ImageEnhance.Color(img_pil).enhance(1.05) img_pil = ImageEnhance.Contrast(img_pil).enhance(1.02) return img_pil.filter(ImageFilter.UnsharpMask(radius=1.0, percent=90, threshold=8)) def ai_face_aware_crop(img): h, w = img.shape[:2] target_w, target_h = 800, 400 target_aspect = 2.0 center_x, center_y = w // 2, h // 2 # --- AI YÜZ TESPİTİ KISMI --- if face_detector: # Modelin giriş boyutunu resme göre ayarla face_detector.setInputSize((w, h)) # Yüzleri tara _, faces = face_detector.detect(img) if faces is not None: # En büyük yüzü bul (faces[i][2] * faces[i][3] = genişlik * yükseklik) faces = sorted(faces, key=lambda f: f[2]*f[3], reverse=True) # YuNet çıktısı: [x, y, w, h, ...] face = faces[0] fx, fy, fw, fh = int(face[0]), int(face[1]), int(face[2]), int(face[3]) # Yüzün merkezini al ama biraz yukarı kaydır (Göz hizası estetiği için) center_x = fx + (fw // 2) center_y = fy + (fh // 3) # --- KIRPMA MANTIĞI --- input_aspect = w / h if input_aspect > target_aspect: # Resim çok geniş, yanlardan kırp new_w = int(h * target_aspect) start_x = center_x - (new_w // 2) start_x = max(0, min(start_x, w - new_w)) img_cropped = img[:, start_x:start_x+new_w] else: # Resim çok uzun, alttan/üstten kırp new_h = int(w / target_aspect) start_y = center_y - (new_h // 2) start_y = max(0, min(start_y, h - new_h)) img_cropped = img[start_y:start_y+new_h, :] return cv2.resize(img_cropped, (target_w, target_h), interpolation=cv2.INTER_LANCZOS4) # --- API ENDPOINT --- @app.route('/process', methods=['POST']) def process_image(): if not request.files: return "Dosya bulunamadı", 400 first_key = next(iter(request.files)) file = request.files[first_key] try: in_memory_file = io.BytesIO() file.save(in_memory_file) data = np.frombuffer(in_memory_file.getvalue(), dtype=np.uint8) img = cv2.imdecode(data, cv2.IMREAD_COLOR) # 1. ADIM: OCR ile Metin Bulma results = reader.readtext(img) mask = np.zeros(img.shape[:2], dtype=np.uint8) logo_bulundu = False # Logoları maskele for (bbox, text, prob) in results: if any(key in text.lower() for key in ["anka", "onka", "anko"]): (tl, tr, br, bl) = bbox tl = [int(x) for x in tl] br = [int(x) for x in br] # Maskeyi biraz geniş tutuyoruz ki harf izi kalmasın cv2.rectangle(mask, (tl[0]-15, tl[1]-15), (br[0]+15, br[1]+15), (255), -1) logo_bulundu = True # Logo bulunamazsa sağ üst köşeyi varsayılan olarak maskele if not logo_bulundu: h_o, w_o = img.shape[:2] cv2.rectangle(mask, (w_o-250, 20), (w_o-10, 120), (255), -1) # 2. ADIM: Inpainting (Logoyu silip doldurma) # Telea algoritması hızlı ve etkilidir img = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA) # 3. ADIM: AI Destekli Kırpma ve Parlatma img_cropped = ai_face_aware_crop(img) img_pil = Image.fromarray(cv2.cvtColor(img_cropped, cv2.COLOR_BGR2RGB)) img_final = apply_smart_eco_polish(img_pil) output_io = io.BytesIO() img_final.save(output_io, 'WEBP', quality=80, method=6) output_io.seek(0) return send_file(output_io, mimetype='image/webp') except Exception as e: return str(e), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=7860)