import cv2 import numpy as np import gradio as gr def detect_skin_type_from_image(img): # ---- Resize and preprocess ---- img = cv2.resize(img, (400, 400)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.equalizeHist(gray) # ---- Oiliness detection ---- _, highlights = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY) oily_score = np.sum(highlights > 0) / highlights.size # ---- Dryness detection ---- laplacian = cv2.Laplacian(gray, cv2.CV_64F) texture_score = laplacian.var() # ---- Combination detection ---- h, w = gray.shape regions = { "forehead": gray[0:int(h*0.3), :], "nose": gray[int(h*0.3):int(h*0.6), int(w*0.4):int(w*0.6)], "cheeks": gray[int(h*0.3):int(h*0.7), int(w*0.1):int(w*0.9)] } region_oiliness = [] for r in regions.values(): _, r_highlights = cv2.threshold(r, 220, 255, cv2.THRESH_BINARY) r_score = np.sum(r_highlights > 0) / r_highlights.size region_oiliness.append(np.float64(r_score)) combo_score = np.std(region_oiliness) # ---- Normalize ---- oily_norm = min(oily_score / 0.30, 1.0) dry_norm = min(texture_score / 6000.0, 1.0) combo_norm = min(combo_score * 5, 1.0) normal_norm = max(1.0 - (oily_norm + dry_norm + combo_norm) / 3, 0.0) # ---- Percentages ---- total = oily_norm + dry_norm + combo_norm + normal_norm + 1e-6 percentages = { "Oily": round(100 * oily_norm / total, 2), "Dry": round(100 * dry_norm / total, 2), "Combination": round(100 * combo_norm / total, 2), "Normal": round(100 * normal_norm / total, 2) } # ---- Only highest percentage ---- final_type = max(percentages, key=percentages.get) final_value = percentages[final_type] return f"{final_type} ({final_value}%)" # ---- Gradio Interface ---- iface = gr.Interface( fn=detect_skin_type_from_image, inputs=gr.Image(type="numpy"), outputs=gr.Textbox(label="Predicted Skin Type"), title="Skin Type Detector", description="Upload an image of your face to detect your skin type (Oily, Dry, Combination, Normal). Only the dominant type will be shown." ) iface.launch()