Bhess7 commited on
Commit
b293971
·
verified ·
1 Parent(s): 58a6b0c

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +109 -0
app.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import torch.nn.functional as F
4
+ from torchvision import transforms, models
5
+ from PIL import Image
6
+ import json
7
+
8
+ # Load model metadata
9
+ CLASS_NAMES = [
10
+ "Crossbite",
11
+ "Crowding",
12
+ "Deepbite",
13
+ "No Treatment Needed",
14
+ "Open Bite",
15
+ "Overbite",
16
+ "Spacing",
17
+ "Underbite"
18
+ ]
19
+
20
+ # Condition descriptions
21
+ DESCRIPTIONS = {
22
+ "Crossbite": "A misalignment where upper teeth bite inside lower teeth.",
23
+ "Crowding": "Insufficient space causing teeth to overlap or twist.",
24
+ "Deepbite": "Upper front teeth excessively overlap lower front teeth.",
25
+ "No Treatment Needed": "Teeth appear to be properly aligned.",
26
+ "Open Bite": "Upper and lower teeth don\'t touch when mouth is closed.",
27
+ "Overbite": "Upper front teeth protrude significantly over lower teeth.",
28
+ "Spacing": "Gaps or spaces between teeth.",
29
+ "Underbite": "Lower teeth protrude beyond upper teeth."
30
+ }
31
+
32
+ # Load model
33
+ print("Loading model...")
34
+ model = models.resnet18(weights=None)
35
+ model.fc = torch.nn.Linear(model.fc.in_features, 8)
36
+ state_dict = torch.load("pytorch_model.pth", map_location="cpu", weights_only=True)
37
+ model.load_state_dict(state_dict)
38
+ model.eval()
39
+ print("Model loaded!")
40
+
41
+ # Image preprocessing
42
+ transform = transforms.Compose([
43
+ transforms.Resize((512, 512)),
44
+ transforms.ToTensor(),
45
+ transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
46
+ ])
47
+
48
+ def predict(image):
49
+ """Predict orthodontic condition from image"""
50
+ if image is None:
51
+ return {"error": "No image provided"}
52
+
53
+ # Convert to PIL if needed
54
+ if not isinstance(image, Image.Image):
55
+ image = Image.fromarray(image)
56
+
57
+ image = image.convert("RGB")
58
+
59
+ # Preprocess
60
+ img_tensor = transform(image).unsqueeze(0)
61
+
62
+ # Predict
63
+ with torch.no_grad():
64
+ outputs = model(img_tensor)
65
+ probabilities = F.softmax(outputs, dim=1)[0]
66
+ confidence, predicted_idx = torch.max(probabilities, 0)
67
+
68
+ predicted_condition = CLASS_NAMES[predicted_idx.item()]
69
+ confidence_pct = confidence.item() * 100
70
+
71
+ # Get all probabilities
72
+ all_probs = {CLASS_NAMES[i]: float(probabilities[i].item() * 100)
73
+ for i in range(len(CLASS_NAMES))}
74
+
75
+ # Determine recommendation
76
+ if predicted_condition == "No Treatment Needed":
77
+ recommendation = "not_candidate"
78
+ recommendation_text = "Based on the AI analysis, you may not need orthodontic treatment at this time."
79
+ elif confidence_pct >= 70:
80
+ recommendation = "candidate"
81
+ recommendation_text = f"You appear to be a good candidate for orthodontic treatment to address {predicted_condition.lower()}."
82
+ else:
83
+ recommendation = "requires_evaluation"
84
+ recommendation_text = "We recommend scheduling a consultation with an orthodontist for a thorough evaluation."
85
+
86
+ return {
87
+ "predicted_condition": predicted_condition,
88
+ "confidence": round(confidence_pct, 2),
89
+ "all_probabilities": {k: round(v, 2) for k, v in all_probs.items()},
90
+ "recommendation": recommendation,
91
+ "recommendation_text": recommendation_text,
92
+ "condition_description": DESCRIPTIONS.get(predicted_condition, ""),
93
+ "model_version": "ResNet18_512x512",
94
+ "training_accuracy": 72.73
95
+ }
96
+
97
+ # Create Gradio interface
98
+ demo = gr.Interface(
99
+ fn=predict,
100
+ inputs=gr.Image(type="pil", label="Upload Dental Photo"),
101
+ outputs=gr.JSON(label="Prediction Results"),
102
+ title="Orthodontic Condition Classifier",
103
+ description="Upload a photo of teeth to get an AI-powered orthodontic screening. This is for informational purposes only and should not replace professional evaluation.",
104
+ examples=None,
105
+ api_name="predict"
106
+ )
107
+
108
+ if __name__ == "__main__":
109
+ demo.launch()