import streamlit as st import os import zipfile import numpy as np import pickle import tensorflow as tf from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input from tensorflow.keras.preprocessing import image from tensorflow.keras.layers import GlobalMaxPool2D from sklearn.neighbors import NearestNeighbors from numpy.linalg import norm from PIL import Image # -------------------------------- # 1. ZIP DOSYASINI AÇMA (En Önemli Kısım) # -------------------------------- # Eğer images klasörü boşsa veya yoksa zip'i açar if not os.path.exists("images") or len(os.listdir("images")) < 10: if os.path.exists("images.zip"): with st.spinner("Resimler paketten çıkarılıyor (296 MB)..."): with zipfile.ZipFile("images.zip", "r") as zip_ref: zip_ref.extractall(".") else: st.error("Hata: images.zip dosyası bulunamadı!") # -------------------------------- # SAYFA AYARI # -------------------------------- st.set_page_config(page_title="Moda Öneri Sistemi", layout="centered") st.title("🛍️ Moda Öneri Sistemi") # -------------------------------- # MODEL YÜKLE # -------------------------------- @st.cache_resource def load_model(): base_model = ResNet50(weights="imagenet", include_top=False, input_shape=(224,224,3)) base_model.trainable = False model = tf.keras.models.Sequential([base_model, GlobalMaxPool2D()]) return model model = load_model() # -------------------------------- # DATA YÜKLE # -------------------------------- @st.cache_resource def load_data(): features = np.array(pickle.load(open("Images_features.pkl","rb"))) filenames = pickle.load(open("filenames.pkl","rb")) return features, filenames feature_list, filenames = load_data() # -------------------------------- # FEATURE ÇIKARMA # -------------------------------- def extract_features(img_path, model): img = image.load_img(img_path, target_size=(224,224)) img_array = image.img_to_array(img) expanded_img = np.expand_dims(img_array, axis=0) preprocessed = preprocess_input(expanded_img) result = model.predict(preprocessed).flatten() normalized = result / norm(result) return normalized # -------------------------------- # ARAYÜZ VE RESİM YÜKLEME # -------------------------------- uploaded_file = st.file_uploader("Bir kıyafet resmi yükleyin", type=["jpg","png","jpeg"]) if uploaded_file is not None: img = Image.open(uploaded_file) st.image(img, width=300, caption="Seçtiğiniz ürün") with open("temp.jpg","wb") as f: f.write(uploaded_file.getbuffer()) with st.spinner("Benzer ürünler bulunuyor..."): input_feature = extract_features("temp.jpg", model) neighbors = NearestNeighbors(n_neighbors=6, algorithm="brute", metric="euclidean") neighbors.fit(feature_list) distances, indices = neighbors.kneighbors([input_feature]) st.subheader("✨ Benzer Ürünler") cols = st.columns(5) # Akıllı Resim Arama (Hangi klasörde olursa olsun bulur) image_db = {} for root, dirs, files in os.walk('images'): for f in files: image_db[f.lower()] = os.path.join(root, f) for i in range(1, 6): with cols[i-1]: raw_path = filenames[indices[0][i]].replace("\\", "/") file_name = os.path.basename(raw_path).lower() if file_name in image_db: st.image(image_db[file_name], use_container_width=True) else: st.write("Eksik:", file_name) # Hata Ayıklama Paneli (Yan tarafta) if os.path.exists("images"): file_count = sum([len(files) for r, d, files in os.walk("images")]) st.sidebar.write(f"📂 images klasöründeki resim sayısı: {file_count}")