File size: 5,694 Bytes
19030fe | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | 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) |