File size: 5,196 Bytes
e3b59c9
4434fcc
7ec9059
4434fcc
 
 
 
 
d62389e
4434fcc
 
 
 
 
dc2e565
4434fcc
7ec9059
dc2e565
4434fcc
 
dc2e565
4434fcc
 
 
 
d62389e
4434fcc
 
d62389e
4434fcc
d62389e
4434fcc
 
 
 
dc2e565
4434fcc
 
dc2e565
4434fcc
 
dc2e565
4434fcc
 
dc2e565
 
4434fcc
 
 
 
 
 
 
 
7ec9059
4434fcc
dc2e565
 
4434fcc
 
 
7ec9059
4434fcc
 
 
 
 
7ec9059
4434fcc
7ec9059
4434fcc
 
 
 
 
 
 
 
 
 
 
 
 
7ec9059
dc2e565
d62389e
4434fcc
 
dc2e565
4434fcc
dc2e565
4434fcc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7ec9059
dc2e565
4434fcc
 
 
 
 
7ec9059
4434fcc
 
 
dc2e565
4434fcc
 
 
 
 
 
 
51cdf3a
4434fcc
51cdf3a
d62389e
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
import gradio as gr
from huggingface_hub import InferenceApi
from transformers import pipeline
import requests
from PIL import Image
import io
import os
import openai

# -----------------------------
# CONFIGURATION
# -----------------------------
# Hugging Face model for acne classification
MODEL_ID = "imfarzanansari/skintelligent-acne"

# Use local pipeline for image classification (faster and more stable)
classifier = pipeline("image-classification", model=MODEL_ID)

# Set your Mistral API key (via environment variable)
openai.api_key = os.getenv("MISTRAL_API_KEY")

# -----------------------------
# HELPER FUNCTIONS
# -----------------------------
def classify_acne(image_url):
    try:
        response = requests.get(image_url)
        img = Image.open(io.BytesIO(response.content)).convert("RGB")
    except Exception as e:
        return "❌ Could not load image. Please check the URL.", "", None

    # Run the acne classification
    preds = classifier(img)
    if not preds:
        return "No prediction.", "", img

    top_pred = preds[0]["label"]
    score = preds[0]["score"]

    # Explanation text
    explanation = explain_acne_type(top_pred)

    result_text = f"**Detected Acne Type:** {top_pred}\n\n**Confidence:** {score:.2f}"
    return result_text, explanation, img


def explain_acne_type(acne_type):
    explanations = {
        "Blackheads": "Blackheads are open comedones caused by clogged hair follicles with sebum and dead skin. They appear black due to oxidation.",
        "Whiteheads": "Whiteheads are closed comedones formed when pores are clogged with oil and dead skin but remain closed at the surface.",
        "Papules": "Papules are small, red, inflamed bumps without visible pus. They often result from irritated or infected clogged pores.",
        "Pustules": "Pustules are pus-filled pimples with a white or yellow center. They can be tender and are often caused by bacterial infection.",
        "Nodules": "Nodules are large, painful lumps deep under the skin caused by severe inflammation and infection in clogged pores.",
        "Cysts": "Cysts are severe acne lesions filled with pus and can cause scarring if not treated properly.",
    }
    return explanations.get(acne_type, "This acne type is uncommon or not specifically defined in the dataset.")


def query_acne_info(acne_type, user_query):
    if not user_query.strip():
        return "Please enter a question."
    try:
        prompt = f"You are an expert dermatologist. The user has acne type '{acne_type}'. Answer this query:\n{user_query}"
        completion = openai.ChatCompletion.create(
            model="mistral-tiny",
            messages=[{"role": "user", "content": prompt}],
            temperature=0.6,
        )
        return completion.choices[0].message["content"]
    except Exception as e:
        return f"Error: {str(e)}"


# -----------------------------
# GRADIO INTERFACE
# -----------------------------
with gr.Blocks(theme=gr.themes.Soft(), title="Acne Type Classifier & Chatbot") as demo:
    gr.Markdown(
        """
        # 🧴 Acne Type Classifier & Dermatology Assistant  
        Upload or paste the URL of an acne image to detect its type.  
        Then ask any query about the detected acne type using the chatbot below.
        """
    )

    with gr.Row():
        image_url = gr.Textbox(label="🔗 Enter Image URL", placeholder="Paste image URL here...")
        submit_btn = gr.Button("Classify", variant="primary")

    with gr.Row():
        with gr.Column(scale=1):
            image_output = gr.Image(label="Uploaded Image", type="pil")

        with gr.Column(scale=2):
            result_box = gr.Markdown(label="Prediction Result", elem_classes="big-box")
            explanation_box = gr.Textbox(
                label="Acne Explanation",
                lines=6,
                interactive=False,
                elem_classes="big-box"
            )

    # Chatbot section
    with gr.Accordion("💬 Ask Dermatology Chatbot", open=True):
        with gr.Row():
            user_query = gr.Textbox(
                label="Enter your query about the detected acne",
                placeholder="e.g., What is the best treatment for cystic acne?",
                lines=2,
            )
        with gr.Row():
            chat_response = gr.Textbox(
                label="Chatbot Response",
                lines=6,
                interactive=False,
                elem_classes="big-box"
            )
        chat_btn = gr.Button("Ask Chatbot", variant="secondary")

    # Button functionality
    submit_btn.click(
        classify_acne,
        inputs=[image_url],
        outputs=[result_box, explanation_box, image_output],
    )

    chat_btn.click(
        query_acne_info,
        inputs=[result_box, user_query],
        outputs=[chat_response],
    )

    gr.Markdown(
        "#### ⚕️ Disclaimer: This app provides general information and should not replace professional medical advice."
    )

# Custom CSS to enlarge boxes
demo.css = """
.big-box textarea, .big-box pre, .big-box .wrap {
    height: 220px !important;
    font-size: 16px;
}
"""

# Launch app
if __name__ == "__main__":
    demo.launch()