CoolFace
Apppublic

wamaa/DermaMate

sourceHugging Facemitupdated 9mo agoView on Hugging Face
0likes
app.py264 linesDownload Raw Back to root
1import gradio as gr2from ultralytics import YOLO3from PIL import Image4import os5from fpdf import FPDF6from datetime import datetime7from gtts import gTTS8 9# ---------------------------------------------------------10# 1. SETUP & MODEL LOADING11# ---------------------------------------------------------12model_path = 'best.pt' 13TEMP_IMG_PATH = "temp_skin_image.jpg"14PDF_REPORT_PATH = "Skin_Analysis_Report.pdf"15AUDIO_PATH = "diagnosis_audio.mp3"16 17print(f"๐Ÿ”„ Loading model from: {model_path}...")18try:19    if os.path.exists(model_path):20        model = YOLO(model_path)21        print("โœ… Model loaded successfully!")22    else:23        print(f"โŒ Error: Model file '{model_path}' not found.")24        # Fallback to standard model to prevent crash (optional)25        model = YOLO("yolov8n-cls.pt") 26except Exception as e:27    print(f"โŒ Critical Error: {e}")28 29# ---------------------------------------------------------30# 2. MEDICAL KNOWLEDGE BASE31# ---------------------------------------------------------32disease_info = {33    "Acne": {34        "desc": "A common skin condition that occurs when hair follicles become plugged with oil and dead skin cells.",35        "treat": "Over-the-counter creams (Benzoyl peroxide, Salicylic acid), avoid touching the face, keep skin clean."36    },37    "Blackhead": {38        "desc": "Open bumps on the skin caused by excess oil and dead skin. They look like dirt bumps but are actually oxidized oil.",39        "treat": "Salicylic acid cleansers, retinoids, gentle exfoliation. Avoid squeezing them to prevent scarring."40    },41    "Whitehea": {42        "desc": "Closed comedones where the follicle is completely blocked. They appear as small white bumps.",43        "treat": "Topical retinoids, Benzoyl peroxide, facial steaming to open pores. Do not pop them."44    },45    "Cystic": {46        "desc": "The most serious type of acne. It develops when cysts form deep underneath your skin. It can be painful.",47        "treat": "Requires a dermatologist. Isotretinoin (Accutane), oral antibiotics, or corticosteroid injections."48    },49    "Papular": {50        "desc": "Small, red, raised bumps caused by inflamed or infected hair follicles.",51        "treat": "Benzoyl peroxide wash, topical antibiotics (Clindamycin). Avoid scrubbing skin too hard."52    },53    "Purulent": {54        "desc": "Pustules (pimples) containing yellowish fluid (pus). They are red and tender.",55        "treat": "Gently wash with salicylic acid. Do not pop (causes infection). Spot treatment with benzoyl peroxide."56    },57    "Conglobata": {58        "desc": "A rare and severe form of acne characterized by burrowing abscesses and irregular scars.",59        "treat": "Urgent dermatologist visit required. Systemic steroids, Isotretinoin, and close medical supervision."60    },61    "Keloid": {62        "desc": "A raised scar after an injury has healed. It grows much larger than the original injury.",63        "treat": "Silicone gel sheets, corticosteroid injections, laser therapy, or cryotherapy."64    },65    "Milium": {66        "desc": "Tiny white bumps (cysts) that appear when dead skin flakes become trapped under the surface of the skin.",67        "treat": "Usually disappear on their own. Retinoid cream or professional extraction by a dermatologist."68    },69    "Flat_wart": {70        "desc": "Smooth, flat-topped bumps usually found on the face and legs. Caused by HPV virus.",71        "treat": "Salicylic acid, cryotherapy (freezing), or prescription creams (Imiquimod)."72    },73    "Syringoma": {74        "desc": "Harmless sweat duct tumors. They are typically found in clusters on eyelids.",75        "treat": "Cosmetic removal via laser, electrosurgery, or excision if desired (they are benign)."76    },77    "Folliculitis": {78        "desc": "Inflammation of hair follicles, often looking like red bumps or white-headed pimples.",79        "treat": "Warm compress, antibacterial soap, topical antibiotics. Stop shaving the area temporarily."80    },81    "Scars": {82        "desc": "Marks left on the skin after a wound or severe acne has healed.",83        "treat": "Laser resurfacing, chemical peels, microneedling, or fillers depending on scar type."84    },85    "Crystanlline": {86        "desc": "A mild form of heat rash affecting sweat ducts in the top layer of skin.",87        "treat": "Keep the area cool and dry. Wear loose clothing. Usually resolves without treatment."88    },89    "Sebo-crystan-conglo": {90        "desc": "A complex presentation of sebaceous cysts or conglobata-like symptoms.",91        "treat": "Consult a dermatologist for proper diagnosis and plan, likely involving antibiotics or drainage."92    },93     "Unlabeled": {94        "desc": "The model could not identify a specific condition with high certainty.",95        "treat": "If you are concerned about a spot, please consult a doctor for a physical examination."96    }97}98 99# ---------------------------------------------------------100# 3. HELPER FUNCTIONS (PDF & AUDIO)101# ---------------------------------------------------------102class PDFReport(FPDF):103    def header(self):104        self.set_font('Arial', 'B', 15)105        self.cell(0, 10, 'AI Skin Analysis Report', 0, 1, 'C')106        self.ln(5)107    def footer(self):108        self.set_y(-15)109        self.set_font('Arial', 'I', 8)110        self.cell(0, 10, 'Disclaimer: AI-generated report. Not a medical diagnosis.', 0, 0, 'C')111 112def create_pdf(image_path, diagnosis, confidence, desc, treat):113    pdf = PDFReport()114    pdf.add_page()115    pdf.set_auto_page_break(auto=True, margin=15)116    117    # Date118    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")119    pdf.set_font("Arial", size=10)120    pdf.cell(0, 10, txt=f"Date: {now}", ln=True, align='R')121    122    # Image123    pdf.ln(5)124    # Ensure image exists before adding125    if os.path.exists(image_path):126        pdf.image(image_path, x=10, y=None, w=60)127    pdf.ln(65)128    129    # Diagnosis130    pdf.set_fill_color(200, 220, 255)131    pdf.cell(0, 10, txt="  Diagnosis Results", ln=True, fill=True)132    pdf.ln(5)133    pdf.set_font("Arial", 'B', size=14)134    pdf.set_text_color(0, 51, 102)135    pdf.cell(0, 10, txt=f"Condition: {diagnosis}", ln=True)136    pdf.set_font("Arial", size=11)137    pdf.set_text_color(0, 0, 0)138    pdf.cell(0, 10, txt=f"Confidence: {confidence:.1f}%", ln=True)139    pdf.ln(5)140    141    # Details142    pdf.set_font("Arial", 'B', size=12)143    pdf.cell(0, 10, txt="Description:", ln=True)144    pdf.set_font("Arial", size=11)145    pdf.multi_cell(0, 8, txt=desc)146    pdf.ln(5)147    pdf.set_font("Arial", 'B', size=12)148    pdf.cell(0, 10, txt="Treatment / Advice:", ln=True)149    pdf.set_font("Arial", size=11)150    pdf.multi_cell(0, 8, txt=treat)151    152    pdf.output(PDF_REPORT_PATH)153    return PDF_REPORT_PATH154 155def generate_audio(text_content):156    """Generates MP3 audio from text"""157    try:158        # Clean text159        clean_text = text_content.replace("*", "").replace("#", "").replace("๐Ÿฉบ", "").replace("๐Ÿ’Š", "")160        tts = gTTS(text=clean_text, lang='en', slow=False)161        tts.save(AUDIO_PATH)162        return AUDIO_PATH163    except Exception as e:164        print(f"Audio generation failed: {e}")165        return None166 167# ---------------------------------------------------------168# 4. MAIN PREDICTION LOGIC169# ---------------------------------------------------------170def predict_full_pipeline(image):171    if image is None:172        return None, None, None, None173    174    # A. Prediction175    results = model.predict(image)176    probs = results[0].probs177    names = results[0].names178    179    confidences = {}180    if probs.top5:181        for i in range(len(probs.top5)):182            idx = probs.top5[i]183            score = float(probs.top5conf[i])184            confidences[names[idx]] = score185    186    top_name = names[probs.top1]187    top_score = float(probs.top1conf)188    info = disease_info.get(top_name, {"desc": "N/A", "treat": "Consult a doctor"})189 190    # B. Generate Content191    image.save(TEMP_IMG_PATH)192    193    if top_score > 0.4:194        # High Confidence195        info_text = f"""196        ### ๐Ÿฉบ Diagnosis: **{top_name}**197        **๐Ÿ“„ Description:** {info['desc']}198        199        **๐Ÿ’Š Treatment:** {info['treat']}200        201        *(Confidence: {top_score*100:.1f}%)*202        """203        # Audio Text204        audio_text = f"The diagnosis is {top_name}. {info['desc']}. Suggested treatment includes: {info['treat']}"205        206        pdf_file = create_pdf(TEMP_IMG_PATH, top_name, top_score*100, info['desc'], info['treat'])207    else:208        # Low Confidence209        top_name = "Uncertain"210        info_text = "### โš ๏ธ Low Confidence\nThe model is unsure. Please consult a dermatologist."211        audio_text = "The model is unsure about this image. Please consult a dermatologist for a physical examination."212        pdf_file = create_pdf(TEMP_IMG_PATH, "Uncertain", top_score*100, "N/A", "Consult Doctor")213 214    # C. Generate Audio215    audio_file = generate_audio(audio_text)216 217    return confidences, info_text, pdf_file, audio_file218 219# ---------------------------------------------------------220# 5. UI LAYOUT (Glass Theme)221# ---------------------------------------------------------222theme = gr.themes.Glass(223    primary_hue="cyan",224    secondary_hue="slate"225).set(body_background_fill="*neutral_50")226 227with gr.Blocks(theme=theme, title="DermaLens AI") as demo:228    229    gr.HTML("""230    <div style="background: linear-gradient(90deg, #00d2ff 0%, #3a7bd5 100%); padding: 20px; border-radius: 15px; text-align: center; color: white; margin-bottom: 20px;">231        <h1 style="margin:0;">๐Ÿงด DermaLens AI</h1>232        <p style="margin:5px 0 0; opacity: 0.9;">Visual Analysis, PDF Reports & Voice Assistance</p>233    </div>234    """)235    236    with gr.Row():237        # Left: Input238        with gr.Column(scale=2):239            input_image = gr.Image(type="pil", label="Upload Image", sources=["upload", "clipboard"], height=350)240            analyze_btn = gr.Button("๐Ÿ” Analyze Now", variant="primary", size="lg")241        242        # Right: Output243        with gr.Column(scale=3):244            with gr.Tabs():245                with gr.TabItem("๐Ÿ“Š Results & Audio"):246                    output_chart = gr.Label(num_top_classes=3, label="Top Predictions")247                    248                    gr.Markdown("### ๐Ÿ”Š Dr. Voice:")249                    output_audio = gr.Audio(label="Audio Explanation", type="filepath")250                    251                    output_info = gr.Markdown()252                253                with gr.TabItem("๐Ÿ“„ PDF Report"):254                    gr.Markdown("### Download Medical Report:")255                    output_pdf = gr.File(label="Generated PDF", file_count="single")256 257    analyze_btn.click(258        fn=predict_full_pipeline, 259        inputs=input_image, 260        outputs=[output_chart, output_info, output_pdf, output_audio]261    )262 263if __name__ == "__main__":264    demo.launch()