puresenseai commited on
Commit
d8de9ec
·
verified ·
1 Parent(s): 97e6aaa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -89
app.py CHANGED
@@ -2,7 +2,7 @@ import os
2
  import random
3
  import warnings
4
  import logging
5
- import urllib.parse # URL'leri düzeltmek için şart
6
  from fastapi import FastAPI, File, UploadFile, Form
7
  from fastapi.middleware.cors import CORSMiddleware
8
  from PIL import Image
@@ -13,6 +13,7 @@ import cv2
13
  import mediapipe as mp
14
  from transformers import Owlv2Processor, Owlv2ForObjectDetection
15
  from transformers import CLIPProcessor, CLIPModel
 
16
 
17
  # --- AYARLAR ---
18
  warnings.filterwarnings("ignore")
@@ -32,17 +33,17 @@ app.add_middleware(
32
  print("⏳ Modeller Yükleniyor...")
33
  device = "cpu"
34
 
35
- # OWL-v2 (Sorun Tespiti)
36
  owl_id = "google/owlv2-base-patch16-ensemble"
37
  owl_processor = Owlv2Processor.from_pretrained(owl_id)
38
  owl_model = Owlv2ForObjectDetection.from_pretrained(owl_id).to(device)
39
 
40
- # CLIP (Cilt Tipi)
41
  clip_id = "openai/clip-vit-base-patch32"
42
  clip_processor = CLIPProcessor.from_pretrained(clip_id)
43
  clip_model = CLIPModel.from_pretrained(clip_id).to(device)
44
 
45
- # MediaPipe (Maskeleme)
46
  mp_face_mesh = mp.solutions.face_mesh
47
  face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True, max_num_faces=1, refine_landmarks=True)
48
 
@@ -51,64 +52,94 @@ print("✅ Sunucu Hazır!")
51
  # --- SÖZLÜKLER ---
52
  TR_LABELS = {
53
  "acne": "Akne", "pimple": "Sivilce", "dark spot": "Leke",
54
- "wrinkles": "Kırışıklık", "oily skin": "Yağlanma",
55
  "dry flaky skin": "Kuruluk", "skin redness": "Kızarıklık",
56
  "peeling skin": "Deri Soyulması", "rough skin": "Pürüzlü",
57
  "whitehead pimple": "Beyaz Uçlu Sivilce", "red acne bumps": "Kızarık Akne"
58
  }
59
 
60
- # --- YENİ: GARANTİLİ LİNK OLUŞTURUCU ---
61
- def generate_search_link(market, query):
62
- # Türkçe karakterleri ve boşlukları URL formatına çevirir (Örn: "Çay Ağacı" -> "%C3%87ay%20A%C4%9Fac%C4%B1")
63
- encoded_query = urllib.parse.quote(query)
64
-
65
- if market == "Trendyol":
66
- return f"https://www.trendyol.com/sr?q={encoded_query}&os=1" # os=1: Stoktakileri göster
67
- elif market == "Hepsiburada":
68
- return f"https://www.hepsiburada.com/ara?q={encoded_query}"
69
- elif market == "Watsons":
70
- return f"https://www.watsons.com.tr/search?text={encoded_query}"
71
- elif market == "Amazon":
72
- return f"https://www.amazon.com.tr/s?k={encoded_query}"
73
- elif market == "Gratis":
74
- return f"https://www.gratis.com/arama?q={encoded_query}"
75
- return ""
76
-
77
- # --- ÜRÜN ÖNERİ MOTORU ---
78
- def get_products_smart(category_key, search_term, is_premium=False):
79
- products = []
80
-
81
- # Her kategori için farklı mağazalardan GARANTİ ÇALIŞAN arama linkleri oluşturuyoruz.
82
- # Artık "Ürün Bulunamadı" veya "Ana Sayfa" sorunu yok.
83
-
84
- # 1. Trendyol (En Popüler)
85
- products.append({
86
- "title": f"Trendyol: En İyi {search_term} Ürünleri",
87
- "link": generate_search_link("Trendyol", f"{search_term} en çok satanlar"),
88
- "source": "Trendyol"
89
- })
90
-
91
- # 2. Hepsiburada (Alternatif)
92
- products.append({
93
- "title": f"Hepsiburada: {search_term} Fırsatları",
94
- "link": generate_search_link("Hepsiburada", search_term),
95
- "source": "Hepsiburada"
96
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
- # Premium Kullanıcılar İçin Ekstra Mağazalar
99
- if is_premium:
100
- products.append({
101
- "title": f"Watsons: {search_term} Seçenekleri",
102
- "link": generate_search_link("Watsons", search_term),
103
- "source": "Watsons"
104
- })
105
- products.append({
106
- "title": f"Amazon: {search_term} (Hızlı Kargo)",
107
- "link": generate_search_link("Amazon", search_term),
108
- "source": "Amazon"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  })
110
-
111
- return products
112
 
113
  def generate_prescription_blocks(skin_type, issues):
114
  blocks = []
@@ -118,38 +149,25 @@ def generate_prescription_blocks(skin_type, issues):
118
  blocks.append({"title": "Günlük Temizleme", "key": "YAĞLI_TEMİZLİK", "search": "Yağlı Cilt Temizleme Jeli"})
119
  elif "KURU" in skin_type:
120
  blocks.append({"title": "Nemlendirici Bakım", "key": "KURU_NEM", "search": "Kuru Cilt Nemlendirici"})
121
- elif "KARMA" in skin_type:
122
- blocks.append({"title": "Dengeleyici Bakım", "key": "KARMA_BAKIM", "search": "Karma Cilt Temizleyici"})
123
 
124
  # Sorun Bloğu
125
  unique_issues = list(set(issues))
126
  for issue in unique_issues:
127
  if "acne" in issue or "pimple" in issue:
128
- blocks.append({"title": "Akne Tedavisi", "key": "AKNE_TEDAVİ", "search": "Salisilik Asit Serum"})
129
  elif "dark spot" in issue:
130
- blocks.append({"title": "Leke Giderici", "key": "LEKE_TEDAVİ", "search": "C Vitamini Leke Serumu"})
131
- elif "redness" in issue:
132
- blocks.append({"title": "Yatıştırıcı Bakım", "key": "KIZARIKLIK", "search": "Centella Asiatica Krem"})
133
- elif "dry" in issue or "peeling" in issue:
134
- if "KURU" not in skin_type: # Zaten kuru cilt önerisi varsa tekrar etme
135
- blocks.append({"title": "Onarıcı Bakım", "key": "KURULUK", "search": "Panthenol Krem"})
136
  elif "wrinkles" in issue:
137
- blocks.append({"title": "Yaşlanma Karşıtı", "key": "KIRIŞIKLIK", "search": "Retinol Serum"})
138
 
139
  return blocks
140
 
141
- # --- FONKSİYONLAR ---
142
- def get_skin_type(image):
143
- prompts = ["extremely oily shiny skin", "very dry flaky skin", "normal skin", "combination skin"]
144
- labels = ["YAĞLI", "KURU", "NORMAL", "KARMA"]
145
- inputs = clip_processor(text=prompts, images=image, return_tensors="pt", padding=True).to(device)
146
- with torch.no_grad(): probs = clip_model(**inputs).logits_per_image.softmax(dim=1)
147
- return labels[torch.max(probs, 1).indices.item()]
148
-
149
  # --- API ENDPOINT ---
150
  @app.get("/")
151
  def home():
152
- return {"status": "Pure Sense API (Fix V4) Çalışıyor"}
153
 
154
  @app.post("/analyze")
155
  async def analyze_skin(
@@ -162,13 +180,13 @@ async def analyze_skin(
162
  # 1. Cilt Tipi
163
  skin_type = get_skin_type(image)
164
 
165
- # 2. Sorun Tespiti (HASSAS AYARLI)
166
- text_queries = [["acne", "pimple", "dark spot", "skin redness", "dry flaky skin", "wrinkles"]]
 
167
  inputs = owl_processor(text=text_queries, images=image, return_tensors="pt").to(device)
168
  with torch.no_grad(): outputs = owl_model(**inputs)
169
 
170
  target_sizes = torch.Tensor([image.size[::-1]])
171
- # Threshold'u 0.02 (%2) yaptık. Çok düşük olursa gürültü olur, çok yüksek olursa kaçırır.
172
  results = owl_processor.post_process_object_detection(outputs=outputs, target_sizes=target_sizes, threshold=0.02)[0]
173
 
174
  detections = []
@@ -178,12 +196,15 @@ async def analyze_skin(
178
  lbl_en = text_queries[0][label]
179
  conf = round(score.item() * 100, 1)
180
 
181
- # --- FİLTRELEME (Gürültüyü Azaltma) ---
182
- # Akne gibi net şeylerde en az %8 emin olsun
183
- if lbl_en in ["acne", "pimple"] and conf < 8: continue
 
 
 
184
 
185
- # Kızarıklık gibi silik şeylerde %3 yeterli
186
- if lbl_en not in ["acne", "pimple"] and conf < 3: continue
187
 
188
  lbl_tr = TR_LABELS.get(lbl_en, lbl_en)
189
  if lbl_tr not in issues_found: issues_found.append(lbl_tr)
@@ -195,17 +216,12 @@ async def analyze_skin(
195
  })
196
 
197
  # 3. Reçete Hazırla
198
- # Bulunan Türkçe sorunları İngilizce köklerine çevirip reçete motoruna verelim
199
- raw_issues = []
200
- for i in issues_found:
201
- for k, v in TR_LABELS.items():
202
- if v == i: raw_issues.append(k)
203
-
204
  prescription_blocks = generate_prescription_blocks(skin_type, raw_issues)
205
 
206
  final_prescriptions = []
207
  for block in prescription_blocks:
208
- products = get_products_smart(block['key'], block['search'], is_premium)
209
  final_prescriptions.append({
210
  "title": block['title'],
211
  "ingredient": block['search'],
 
2
  import random
3
  import warnings
4
  import logging
5
+ import urllib.parse
6
  from fastapi import FastAPI, File, UploadFile, Form
7
  from fastapi.middleware.cors import CORSMiddleware
8
  from PIL import Image
 
13
  import mediapipe as mp
14
  from transformers import Owlv2Processor, Owlv2ForObjectDetection
15
  from transformers import CLIPProcessor, CLIPModel
16
+ from duckduckgo_search import DDGS
17
 
18
  # --- AYARLAR ---
19
  warnings.filterwarnings("ignore")
 
33
  print("⏳ Modeller Yükleniyor...")
34
  device = "cpu"
35
 
36
+ # OWL-v2
37
  owl_id = "google/owlv2-base-patch16-ensemble"
38
  owl_processor = Owlv2Processor.from_pretrained(owl_id)
39
  owl_model = Owlv2ForObjectDetection.from_pretrained(owl_id).to(device)
40
 
41
+ # CLIP
42
  clip_id = "openai/clip-vit-base-patch32"
43
  clip_processor = CLIPProcessor.from_pretrained(clip_id)
44
  clip_model = CLIPModel.from_pretrained(clip_id).to(device)
45
 
46
+ # MediaPipe
47
  mp_face_mesh = mp.solutions.face_mesh
48
  face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True, max_num_faces=1, refine_landmarks=True)
49
 
 
52
  # --- SÖZLÜKLER ---
53
  TR_LABELS = {
54
  "acne": "Akne", "pimple": "Sivilce", "dark spot": "Leke",
55
+ "deep wrinkles": "Kırışıklık", "oily skin": "Yağlanma", # Prompt değişti
56
  "dry flaky skin": "Kuruluk", "skin redness": "Kızarıklık",
57
  "peeling skin": "Deri Soyulması", "rough skin": "Pürüzlü",
58
  "whitehead pimple": "Beyaz Uçlu Sivilce", "red acne bumps": "Kızarık Akne"
59
  }
60
 
61
+ # --- MEGA ÜRÜN VERİTABANI ---
62
+ MEGA_DATABASE = {
63
+ "YAĞLI_AKNE": [
64
+ {"marka": "La Roche-Posay", "urun": "Effaclar Duo (+)", "link": "https://www.trendyol.com/sr?q=effaclar+duo"},
65
+ {"marka": "The Purest Solutions", "urun": "Salisilik Asit Tonik", "link": "https://www.trendyol.com/sr?q=the+purest+salisilik"},
66
+ {"marka": "CeraVe", "urun": "Blemish Control Gel", "link": "https://www.hepsiburada.com/ara?q=cerave+blemish"},
67
+ {"marka": "Bioderma", "urun": "Sebium Kerato+", "link": "https://www.trendyol.com/sr?q=bioderma+sebium+kerato"},
68
+ {"marka": "Cosrx", "urun": "BHA Blackhead Power Liquid", "link": "https://www.korendy.com.tr"},
69
+ {"marka": "Vichy", "urun": "Normaderm Phytosolution", "link": "https://www.trendyol.com/sr?q=vichy+normaderm"}
70
+ ],
71
+ "YAĞLI_TEMİZLİK": [
72
+ {"marka": "CeraVe", "urun": "Foaming Cleanser", "link": "https://www.trendyol.com/sr?q=cerave+foaming"},
73
+ {"marka": "La Roche-Posay", "urun": "Effaclar Jel", "link": "https://www.trendyol.com/sr?q=effaclar+jel"},
74
+ {"marka": "Bioderma", "urun": "Sebium Foaming Gel", "link": "https://www.trendyol.com/sr?q=bioderma+sebium+gel"},
75
+ {"marka": "Simple", "urun": "Daily Skin Detox", "link": "https://www.gratis.com"}
76
+ ],
77
+ "KURU_NEM": [
78
+ {"marka": "CeraVe", "urun": "Moisturizing Cream", "link": "https://www.trendyol.com/sr?q=cerave+moisturizing"},
79
+ {"marka": "Kiehl's", "urun": "Ultra Facial Cream", "link": "https://www.kiehls.com.tr"},
80
+ {"marka": "La Roche-Posay", "urun": "Lipikar Baume AP+M", "link": "https://www.trendyol.com/sr?q=lipikar+baume"},
81
+ {"marka": "Bioderma", "urun": "Atoderm Intensive Balm", "link": "https://www.trendyol.com/sr?q=bioderma+atoderm"}
82
+ ],
83
+ "HASSAS_YATIŞTIRICI": [
84
+ {"marka": "Dr. Jart+", "urun": "Cicapair Tiger Grass", "link": "https://www.sephora.com.tr"},
85
+ {"marka": "La Roche-Posay", "urun": "Cicaplast Baume B5", "link": "https://www.trendyol.com/sr?q=cicaplast"},
86
+ {"marka": "Skin1004", "urun": "Madagascar Centella", "link": "https://www.korendy.com.tr"},
87
+ {"marka": "Avene", "urun": "Cicalfate+ Repair Cream", "link": "https://www.trendyol.com/sr?q=avene+cicalfate"}
88
+ ],
89
+ "LEKE_TEDAVİSİ": [
90
+ {"marka": "Caudalie", "urun": "Vinoperfect Serum", "link": "https://www.trendyol.com/sr?q=caudalie+vinoperfect"},
91
+ {"marka": "SkinCeuticals", "urun": "Discoloration Defense", "link": "https://www.trendyol.com/sr?q=skinceuticals+discoloration"},
92
+ {"marka": "The Ordinary", "urun": "Alpha Arbutin 2% + HA", "link": "https://www.trendyol.com/sr?q=ordinary+arbutin"},
93
+ {"marka": "Garnier", "urun": "C Vitamini Parlaklık Serumu", "link": "https://www.gratis.com"}
94
+ ],
95
+ "YAŞLANMA_KARŞITI": [
96
+ {"marka": "L'Oreal", "urun": "Revitalift Retinol Serum", "link": "https://www.trendyol.com/sr?q=loreal+retinol"},
97
+ {"marka": "La Roche-Posay", "urun": "Retinol B3 Serum", "link": "https://www.trendyol.com/sr?q=la+roche+retinol"},
98
+ {"marka": "The Purest", "urun": "Retinol %1 Serum", "link": "https://www.trendyol.com/sr?q=the+purest+retinol"},
99
+ {"marka": "Kiehl's", "urun": "Retinol Skin-Renewing", "link": "https://www.kiehls.com.tr"}
100
+ ]
101
+ }
102
+
103
+ # --- FONKSİYONLAR ---
104
+ def get_skin_type(image):
105
+ prompts = ["extremely oily shiny skin", "very dry flaky skin", "normal skin", "combination skin"]
106
+ labels = ["YAĞLI", "KURU", "NORMAL", "KARMA"]
107
+ inputs = clip_processor(text=prompts, images=image, return_tensors="pt", padding=True).to(device)
108
+ with torch.no_grad(): probs = clip_model(**inputs).logits_per_image.softmax(dim=1)
109
+ return labels[torch.max(probs, 1).indices.item()]
110
+
111
+ def get_products(category_key, search_term, is_premium=False):
112
+ products_to_show = []
113
 
114
+ # 1. Veritabanından Çek
115
+ if category_key in MEGA_DATABASE:
116
+ db_products = MEGA_DATABASE[category_key][:] # Kopyasını al
117
+ random.shuffle(db_products)
118
+ limit = 6 if is_premium else 2
119
+ products_to_show = db_products[:limit]
120
+
121
+ # 2. Eğer veritabanı boşsa Canlı Arama Yap
122
+ if len(products_to_show) < 2:
123
+ try:
124
+ with DDGS() as ddgs:
125
+ query = f"site:trendyol.com {search_term} en çok satanlar"
126
+ results = list(ddgs.text(query, max_results=3))
127
+ for r in results:
128
+ products_to_show.append({
129
+ "marka": "Trend",
130
+ "urun": r['title'].split("|")[0],
131
+ "link": r['href']
132
+ })
133
+ except: pass
134
+
135
+ final_list = []
136
+ for p in products_to_show:
137
+ final_list.append({
138
+ "title": f"[{p['marka']}] {p['urun']}",
139
+ "link": p['link'],
140
+ "source": "Öneri"
141
  })
142
+ return final_list
 
143
 
144
  def generate_prescription_blocks(skin_type, issues):
145
  blocks = []
 
149
  blocks.append({"title": "Günlük Temizleme", "key": "YAĞLI_TEMİZLİK", "search": "Yağlı Cilt Temizleme Jeli"})
150
  elif "KURU" in skin_type:
151
  blocks.append({"title": "Nemlendirici Bakım", "key": "KURU_NEM", "search": "Kuru Cilt Nemlendirici"})
 
 
152
 
153
  # Sorun Bloğu
154
  unique_issues = list(set(issues))
155
  for issue in unique_issues:
156
  if "acne" in issue or "pimple" in issue:
157
+ blocks.append({"title": "Akne Tedavisi", "key": "YAĞLI_AKNE", "search": "Akne Kremi"})
158
  elif "dark spot" in issue:
159
+ blocks.append({"title": "Leke Giderici", "key": "LEKE_TEDAVİ", "search": "Leke Serumu"})
160
+ elif "redness" in issue or "dry" in issue:
161
+ blocks.append({"title": "Yatıştırıcı Bakım", "key": "HASSAS_YATIŞTIRICI", "search": "Cica Krem"})
 
 
 
162
  elif "wrinkles" in issue:
163
+ blocks.append({"title": "Yaşlanma Karşıtı", "key": "YAŞLANMA_KARŞITI", "search": "Retinol Serum"})
164
 
165
  return blocks
166
 
 
 
 
 
 
 
 
 
167
  # --- API ENDPOINT ---
168
  @app.get("/")
169
  def home():
170
+ return {"status": "Pure Sense API (Wrinkle Fix) Çalışıyor"}
171
 
172
  @app.post("/analyze")
173
  async def analyze_skin(
 
180
  # 1. Cilt Tipi
181
  skin_type = get_skin_type(image)
182
 
183
+ # 2. Sorun Tespiti (GÜNCELLENMİŞ PROMPTLAR)
184
+ # "wrinkles" yerine "deep wrinkles" yazdık ki ince çizgileri görmezden gelsin.
185
+ text_queries = [["acne", "pimple", "dark spot", "skin redness", "dry flaky skin", "deep wrinkles"]]
186
  inputs = owl_processor(text=text_queries, images=image, return_tensors="pt").to(device)
187
  with torch.no_grad(): outputs = owl_model(**inputs)
188
 
189
  target_sizes = torch.Tensor([image.size[::-1]])
 
190
  results = owl_processor.post_process_object_detection(outputs=outputs, target_sizes=target_sizes, threshold=0.02)[0]
191
 
192
  detections = []
 
196
  lbl_en = text_queries[0][label]
197
  conf = round(score.item() * 100, 1)
198
 
199
+ # --- GELİŞMİŞ FİLTRELEME ---
200
+ # KIRIŞIKLIK FİLTRESİ: Sadece %40'tan eminse göstersin.
201
+ if lbl_en == "deep wrinkles" and conf < 40: continue
202
+
203
+ # AKNE FİLTRESİ: %10 altı yok.
204
+ if lbl_en in ["acne", "pimple"] and conf < 10: continue
205
 
206
+ # Diğerleri için %3 yeterli
207
+ if conf < 3: continue
208
 
209
  lbl_tr = TR_LABELS.get(lbl_en, lbl_en)
210
  if lbl_tr not in issues_found: issues_found.append(lbl_tr)
 
216
  })
217
 
218
  # 3. Reçete Hazırla
219
+ raw_issues = [i.lower() for i in text_queries[0] if TR_LABELS.get(i,i) in issues_found]
 
 
 
 
 
220
  prescription_blocks = generate_prescription_blocks(skin_type, raw_issues)
221
 
222
  final_prescriptions = []
223
  for block in prescription_blocks:
224
+ products = get_products(block['key'], block['search'], is_premium)
225
  final_prescriptions.append({
226
  "title": block['title'],
227
  "ingredient": block['search'],