Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,73 +1,99 @@
|
|
1 |
-
|
2 |
from ultralytics import YOLO
|
3 |
-
from PIL import Image
|
4 |
import io
|
5 |
-
|
6 |
-
from pydantic import BaseModel
|
7 |
-
import uvicorn
|
8 |
|
9 |
-
#
|
10 |
-
|
11 |
-
x1: float
|
12 |
-
y1: float
|
13 |
-
x2: float
|
14 |
-
y2: float
|
15 |
-
confidence: float
|
16 |
-
class_name: str
|
17 |
|
18 |
-
|
19 |
-
|
|
|
|
|
20 |
|
21 |
-
|
22 |
-
app = FastAPI(title="Skin Condition Detection API")
|
23 |
-
model = YOLO('best.pt')
|
24 |
class_names = ['Acne', 'Dark circles', 'blackheads', 'eczema', 'rosacea', 'whiteheads', 'wrinkles']
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
"""
|
31 |
-
# Validate file
|
32 |
-
if not file.content_type.startswith("image/"):
|
33 |
-
raise HTTPException(status_code=400, detail="File must be an image")
|
34 |
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
|
|
|
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
x1=float(box[0].item()),
|
58 |
-
y1=float(box[1].item()),
|
59 |
-
x2=float(box[2].item()),
|
60 |
-
y2=float(box[3].item()),
|
61 |
-
confidence=confidence,
|
62 |
-
class_name=class_names[class_id]
|
63 |
-
)
|
64 |
-
predictions.append(prediction)
|
65 |
|
66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
|
68 |
-
|
69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
|
71 |
-
# For local development
|
72 |
if __name__ == "__main__":
|
73 |
-
|
|
|
1 |
+
import streamlit as st
|
2 |
from ultralytics import YOLO
|
3 |
+
from PIL import Image, ImageDraw
|
4 |
import io
|
5 |
+
import json
|
|
|
|
|
6 |
|
7 |
+
# Set page config
|
8 |
+
st.set_page_config(page_title="Skin Condition Classifier", layout="wide")
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
+
# Initialize the model
|
11 |
+
@st.cache_resource
|
12 |
+
def load_model():
|
13 |
+
return YOLO('best.pt')
|
14 |
|
15 |
+
model = load_model()
|
|
|
|
|
16 |
class_names = ['Acne', 'Dark circles', 'blackheads', 'eczema', 'rosacea', 'whiteheads', 'wrinkles']
|
17 |
|
18 |
+
def process_image(image):
|
19 |
+
# Resize image
|
20 |
+
resized_image = image.copy()
|
21 |
+
resized_image.thumbnail((640, 640))
|
|
|
|
|
|
|
|
|
22 |
|
23 |
+
# Get predictions
|
24 |
+
results = model(resized_image)[0]
|
25 |
+
predictions = []
|
26 |
+
|
27 |
+
if results.boxes is not None:
|
28 |
+
boxes = results.boxes.xyxy
|
29 |
+
confidences = results.boxes.conf
|
30 |
+
classes = results.boxes.cls
|
31 |
|
32 |
+
for i in range(len(boxes)):
|
33 |
+
box = boxes[i]
|
34 |
+
confidence = confidences[i].item()
|
35 |
+
class_id = int(classes[i].item())
|
36 |
+
prediction = {
|
37 |
+
"x1": box[0].item(),
|
38 |
+
"y1": box[1].item(),
|
39 |
+
"x2": box[2].item(),
|
40 |
+
"y2": box[3].item(),
|
41 |
+
"confidence": confidence,
|
42 |
+
"class": class_names[class_id],
|
43 |
+
}
|
44 |
+
predictions.append(prediction)
|
45 |
+
|
46 |
+
return predictions
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
+
def draw_boxes(image, predictions):
|
49 |
+
draw = ImageDraw.Draw(image)
|
50 |
+
for pred in predictions:
|
51 |
+
x1, y1, x2, y2 = pred["x1"], pred["y1"], pred["x2"], pred["y2"]
|
52 |
+
draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
|
53 |
+
label = f"{pred['class']} ({pred['confidence']:.2f})"
|
54 |
+
draw.text((x1, y1-10), label, fill="red")
|
55 |
+
return image
|
56 |
|
57 |
+
def main():
|
58 |
+
st.title("Skin Condition Classifier")
|
59 |
+
|
60 |
+
# File uploader
|
61 |
+
uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
|
62 |
+
|
63 |
+
if uploaded_file is not None:
|
64 |
+
# Create columns for layout
|
65 |
+
col1, col2 = st.columns(2)
|
66 |
+
|
67 |
+
# Display original image
|
68 |
+
image = Image.open(uploaded_file)
|
69 |
+
col1.subheader("Original Image")
|
70 |
+
col1.image(image, use_column_width=True)
|
71 |
+
|
72 |
+
# Process image and get predictions
|
73 |
+
predictions = process_image(image)
|
74 |
+
|
75 |
+
# Draw boxes on image
|
76 |
+
image_with_boxes = image.copy()
|
77 |
+
image_with_boxes = draw_boxes(image_with_boxes, predictions)
|
78 |
+
|
79 |
+
# Display annotated image
|
80 |
+
col2.subheader("Detected Conditions")
|
81 |
+
col2.image(image_with_boxes, use_column_width=True)
|
82 |
+
|
83 |
+
# Display predictions in a nice format
|
84 |
+
st.subheader("Detailed Results")
|
85 |
+
for pred in predictions:
|
86 |
+
st.write(f"- Detected {pred['class']} with {pred['confidence']:.2f} confidence")
|
87 |
+
|
88 |
+
# Add download button for JSON results
|
89 |
+
if predictions:
|
90 |
+
json_results = json.dumps({"predictions": predictions}, indent=2)
|
91 |
+
st.download_button(
|
92 |
+
label="Download Results as JSON",
|
93 |
+
data=json_results,
|
94 |
+
file_name="predictions.json",
|
95 |
+
mime="application/json"
|
96 |
+
)
|
97 |
|
|
|
98 |
if __name__ == "__main__":
|
99 |
+
main()
|