Spaces:
Sleeping
Sleeping
Upload 3 files
Browse files- 9_Regions_Model_Weights.pt +3 -0
- Acne_Detection_Model_Weights.pt +3 -0
- app.py +176 -0
9_Regions_Model_Weights.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3240aa65e3e26047b41f115e241ac19f3b5ddc65ba1f683302ad6462e654f454
|
| 3 |
+
size 5480467
|
Acne_Detection_Model_Weights.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d0d982e3a296ed680a1fac4b46aa651b024627c004566364cbecc2625996d227
|
| 3 |
+
size 40326317
|
app.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import numpy as np
|
| 3 |
+
from ultralytics import YOLO
|
| 4 |
+
from PIL import Image, ImageDraw
|
| 5 |
+
import torch
|
| 6 |
+
|
| 7 |
+
# Load acne detection models
|
| 8 |
+
regions_model = YOLO("9_Regions_Model_Weights.pt")
|
| 9 |
+
acne_model = YOLO("Acne_Detection_Model_Weights.pt")
|
| 10 |
+
|
| 11 |
+
# Define anatomical regions order
|
| 12 |
+
anatomical_order = [
|
| 13 |
+
"forehead", "left-eye", "right-eye", "left-cheek",
|
| 14 |
+
"nose", "right-cheek", "between-eyes", "mouth", "chin"
|
| 15 |
+
]
|
| 16 |
+
|
| 17 |
+
def process_region(region_img):
|
| 18 |
+
"""Detect acne in a region and draw bounding boxes"""
|
| 19 |
+
# Run acne detection
|
| 20 |
+
results = acne_model(region_img)
|
| 21 |
+
|
| 22 |
+
# Create PIL image
|
| 23 |
+
pil_img = Image.fromarray(region_img)
|
| 24 |
+
|
| 25 |
+
# Only draw bounding boxes if acne is detected
|
| 26 |
+
if results[0].boxes is not None:
|
| 27 |
+
draw = ImageDraw.Draw(pil_img)
|
| 28 |
+
for box in results[0].boxes:
|
| 29 |
+
x1, y1, x2, y2 = map(int, box.xyxy[0].cpu().numpy())
|
| 30 |
+
draw.rectangle([x1, y1, x2, y2], outline="blue", width=2)
|
| 31 |
+
|
| 32 |
+
return pil_img, len(results[0].boxes) if results[0].boxes else 0
|
| 33 |
+
|
| 34 |
+
def analyze_acne(region_counts):
|
| 35 |
+
"""Generate acne analysis report based on region counts"""
|
| 36 |
+
total_acne = sum(region_counts.values())
|
| 37 |
+
|
| 38 |
+
# Simple severity assessment
|
| 39 |
+
if total_acne == 0:
|
| 40 |
+
severity = "Healthy"
|
| 41 |
+
elif total_acne < 10:
|
| 42 |
+
severity = "Mild"
|
| 43 |
+
elif total_acne < 20:
|
| 44 |
+
severity = "Moderate"
|
| 45 |
+
else:
|
| 46 |
+
severity = "Severe"
|
| 47 |
+
|
| 48 |
+
# Identify most affected area
|
| 49 |
+
most_affected = max(region_counts, key=region_counts.get)
|
| 50 |
+
|
| 51 |
+
# Generate report
|
| 52 |
+
report = f"Acne Assessment\n"
|
| 53 |
+
report += f"• Total Acne: {total_acne}\n"
|
| 54 |
+
report += f"• Severity: {severity}\n"
|
| 55 |
+
report += f"• Most affected area: {most_affected.capitalize()} ({region_counts[most_affected]} Acne)\n\n"
|
| 56 |
+
report += "Region Breakdown:\n"
|
| 57 |
+
for region, count in region_counts.items():
|
| 58 |
+
report += f" • {region.capitalize()}: {count} Acne\n"
|
| 59 |
+
|
| 60 |
+
return report
|
| 61 |
+
|
| 62 |
+
def perform_prediction(pil_image):
|
| 63 |
+
"""Main processing function for Gradio"""
|
| 64 |
+
# Convert PIL to numpy array (RGB)
|
| 65 |
+
image = np.array(pil_image)
|
| 66 |
+
|
| 67 |
+
# Detect facial regions
|
| 68 |
+
regions = {}
|
| 69 |
+
results = regions_model(image)
|
| 70 |
+
|
| 71 |
+
# Extract first detected instance of each region
|
| 72 |
+
for box in results[0].boxes:
|
| 73 |
+
class_id = int(box.cls)
|
| 74 |
+
class_name = regions_model.names[class_id]
|
| 75 |
+
if class_name not in regions:
|
| 76 |
+
x1, y1, x2, y2 = map(int, box.xyxy[0].cpu().numpy())
|
| 77 |
+
regions[class_name] = image[y1:y2, x1:x2]
|
| 78 |
+
|
| 79 |
+
# Process each region in anatomical order
|
| 80 |
+
output_images = []
|
| 81 |
+
region_counts = {}
|
| 82 |
+
|
| 83 |
+
for region_name in anatomical_order:
|
| 84 |
+
region_img = regions.get(region_name, None)
|
| 85 |
+
|
| 86 |
+
if region_img is None or region_img.size == 0:
|
| 87 |
+
# Create placeholder for missing regions
|
| 88 |
+
blank = Image.new('RGB', (300, 300), color='white')
|
| 89 |
+
draw = ImageDraw.Draw(blank)
|
| 90 |
+
draw.text((10, 10), f"Missing: {region_name}", fill="black")
|
| 91 |
+
output_images.append(blank)
|
| 92 |
+
region_counts[region_name] = 0
|
| 93 |
+
else:
|
| 94 |
+
pil_img, count = process_region(region_img)
|
| 95 |
+
output_images.append(pil_img)
|
| 96 |
+
region_counts[region_name] = count
|
| 97 |
+
|
| 98 |
+
# Generate acne analysis report
|
| 99 |
+
analysis_report = analyze_acne(region_counts)
|
| 100 |
+
|
| 101 |
+
# Return each image individually + the analysis report
|
| 102 |
+
return (*output_images, analysis_report)
|
| 103 |
+
|
| 104 |
+
title = "DermaGPT - Acne Detection & Analysis"
|
| 105 |
+
description = """
|
| 106 |
+
**Comprehensive Facial Acne Analysis System**
|
| 107 |
+
|
| 108 |
+
This advanced dermatological tool provides a detailed assessment of acne conditions through a two-stage analysis process:
|
| 109 |
+
|
| 110 |
+
1. **Precision Acne Detection**
|
| 111 |
+
Utilizes state-of-the-art computer vision models to:
|
| 112 |
+
- Segment the face into 9 anatomical regions
|
| 113 |
+
- Detect and localize acne lesions with bounding boxes
|
| 114 |
+
- Provide visual mapping of affected areas
|
| 115 |
+
|
| 116 |
+
2. **Clinical Assessment Report**
|
| 117 |
+
Generates an analysis featuring:
|
| 118 |
+
- Quantitative lesion count and distribution mapping
|
| 119 |
+
- Severity classification (Healthy/Mild/Moderate/Severe)
|
| 120 |
+
- Identification of most affected facial zones
|
| 121 |
+
|
| 122 |
+
**Medical-Grade Insights**
|
| 123 |
+
Designed for both clinical professionals and personal skincare assessment, this tool provides objective, consistent analysis to support treatment planning and skin health monitoring. All outputs adhere to dermatological best practices and classification standards.
|
| 124 |
+
|
| 125 |
+
*Note: For optimal results, use well-lit front-facing images without obstructions.*
|
| 126 |
+
|
| 127 |
+
*Note: Due to free resources limitation on Hugging Face, We were unable to use out LLM model to generate the Clinical Assessment Report*
|
| 128 |
+
"""
|
| 129 |
+
|
| 130 |
+
# Create interface with combined outputs
|
| 131 |
+
with gr.Blocks() as demo:
|
| 132 |
+
gr.Markdown(f"## {title}")
|
| 133 |
+
gr.Markdown(description)
|
| 134 |
+
|
| 135 |
+
with gr.Row():
|
| 136 |
+
image_input = gr.Image(type="pil", label="Upload Face Image")
|
| 137 |
+
|
| 138 |
+
submit_btn = gr.Button("Analyze Acne", variant="primary")
|
| 139 |
+
|
| 140 |
+
with gr.Row():
|
| 141 |
+
gr.Markdown("### Facial Region Analysis")
|
| 142 |
+
|
| 143 |
+
# Create 3x3 grid for region images
|
| 144 |
+
region_outputs = []
|
| 145 |
+
with gr.Row():
|
| 146 |
+
for i in range(3):
|
| 147 |
+
with gr.Column():
|
| 148 |
+
for j in range(3):
|
| 149 |
+
idx = i*3 + j
|
| 150 |
+
if idx < len(anatomical_order):
|
| 151 |
+
region_output = gr.Image(
|
| 152 |
+
type="pil",
|
| 153 |
+
label=anatomical_order[idx].capitalize(),
|
| 154 |
+
elem_id=f"region-{idx}"
|
| 155 |
+
)
|
| 156 |
+
region_outputs.append(region_output)
|
| 157 |
+
|
| 158 |
+
with gr.Row():
|
| 159 |
+
gr.Markdown("### Acne Analysis Report")
|
| 160 |
+
|
| 161 |
+
with gr.Row():
|
| 162 |
+
analysis_output = gr.Textbox(
|
| 163 |
+
label="Detailed Acne Assessment",
|
| 164 |
+
interactive=False,
|
| 165 |
+
lines=10,
|
| 166 |
+
max_lines=20
|
| 167 |
+
)
|
| 168 |
+
|
| 169 |
+
submit_btn.click(
|
| 170 |
+
fn=perform_prediction,
|
| 171 |
+
inputs=image_input,
|
| 172 |
+
outputs=region_outputs + [analysis_output]
|
| 173 |
+
)
|
| 174 |
+
|
| 175 |
+
if __name__ == "__main__":
|
| 176 |
+
demo.launch()
|