Spaces:
Runtime error
Runtime error
Update main.py
Browse files
main.py
CHANGED
@@ -2,14 +2,15 @@ from flask import Flask, request, jsonify
|
|
2 |
from flask_cors import CORS
|
3 |
from PIL import Image, ImageDraw
|
4 |
import io
|
5 |
-
import base64
|
|
|
6 |
|
7 |
from model import predict
|
8 |
|
9 |
app = Flask(__name__)
|
10 |
CORS(app)
|
11 |
|
12 |
-
#global variables
|
13 |
threshold = 0.02
|
14 |
diagnosis = ''
|
15 |
pc_source = False
|
@@ -24,10 +25,9 @@ def process_annotation():
|
|
24 |
source = data.get('source', 'pc') if data else 'pc'
|
25 |
|
26 |
if source == "pc":
|
27 |
-
|
28 |
global pc_source
|
29 |
pc_source = True
|
30 |
-
|
31 |
if not data:
|
32 |
return jsonify({"error": "No JSON data provided"}), 400
|
33 |
img_data = data.get('image')
|
@@ -35,7 +35,6 @@ def process_annotation():
|
|
35 |
category = data.get('category')
|
36 |
view = data.get('view')
|
37 |
|
38 |
-
#Decode base64 image
|
39 |
header, encoded = img_data.split(',', 1)
|
40 |
img_bytes = base64.b64decode(encoded)
|
41 |
img = Image.open(io.BytesIO(img_bytes))
|
@@ -46,21 +45,22 @@ def process_annotation():
|
|
46 |
bbox['x'] + bbox['width'],
|
47 |
bbox['y'] + bbox['height']
|
48 |
))
|
|
|
49 |
print(f"\nParameters:[Category-{category}, View-{view}, Annotations-{bbox}]\n")
|
50 |
print("Processing...\n")
|
51 |
time.sleep(2)
|
|
|
52 |
error = predict(cropped, view, category)
|
53 |
label = get_label(error)
|
54 |
confidence = 100 - (100 * float(error))
|
55 |
diagnosis = build_diagnosis(error, confidence)
|
56 |
-
|
57 |
draw = ImageDraw.Draw(img)
|
58 |
draw.rectangle(
|
59 |
[bbox['x'], bbox['y'], bbox['x'] + bbox['width'], bbox['y'] + bbox['height']],
|
60 |
outline="red", width=3
|
61 |
)
|
62 |
|
63 |
-
# Re-encode processed images to base64
|
64 |
buffered = io.BytesIO()
|
65 |
cropped.save(buffered, format="PNG")
|
66 |
processed_b64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
|
@@ -68,7 +68,7 @@ def process_annotation():
|
|
68 |
|
69 |
print(f"Results: Error-{error}, Comment-{label}, Confidence-{confidence}, Diagnosis-{diagnosis}\n")
|
70 |
print(f"Rendering results to: {source} \n")
|
71 |
-
|
72 |
return jsonify({
|
73 |
"processed_image": processed_data_url,
|
74 |
"category": category,
|
@@ -84,31 +84,28 @@ def process_annotation():
|
|
84 |
view = request.form.get('view')
|
85 |
source_field = request.form.get('source')
|
86 |
image_file = request.files.get('image')
|
87 |
-
|
88 |
if not image_file:
|
89 |
return jsonify({"error": "No image file provided"}), 400
|
90 |
-
|
91 |
if not category or not view:
|
92 |
return jsonify({"error": "Missing category or view"}), 400
|
93 |
|
94 |
try:
|
95 |
img = Image.open(image_file)
|
96 |
-
|
97 |
if img.mode != 'RGB':
|
98 |
img = img.convert('RGB')
|
99 |
-
|
100 |
except Exception as e:
|
101 |
return jsonify({"error": f"Invalid image file: {str(e)}"}), 400
|
102 |
|
103 |
-
print(f"\nParameters:[Category-{category}, View-{view}, Image size-{img.size}\n")
|
104 |
print("Processing...\n")
|
105 |
-
|
106 |
error = predict(img, view, category)
|
107 |
label = get_label(error)
|
108 |
confidence = 100 - (100 * float(error))
|
109 |
diagnosis = build_diagnosis(error, confidence)
|
110 |
-
|
111 |
-
# Convert image back to base64 for response
|
112 |
buffered = io.BytesIO()
|
113 |
img.save(buffered, format="PNG")
|
114 |
processed_b64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
|
@@ -128,8 +125,9 @@ def process_annotation():
|
|
128 |
|
129 |
print(f"Results: Error-{error}, Comment-{label}, Confidence-{confidence}, Diagnosis-{diagnosis}\n")
|
130 |
print(f"Rendering results to: {source} \n")
|
131 |
-
|
132 |
return jsonify(response_data)
|
|
|
133 |
else:
|
134 |
return jsonify({"error": "Unsupported source"}), 400
|
135 |
|
@@ -138,26 +136,19 @@ def process_annotation():
|
|
138 |
return jsonify({"error": str(e)}), 500
|
139 |
|
140 |
def get_label(error):
|
141 |
-
|
142 |
-
return label
|
143 |
|
144 |
-
#RUBRIC
|
145 |
def build_diagnosis(error, confidence):
|
146 |
if confidence < 100 and confidence > 98 and error > threshold:
|
147 |
diagnosis = 'High probability that there is an anomaly in the structure.'
|
148 |
elif confidence < 98 and confidence > 96 and error > threshold:
|
149 |
diagnosis = 'My analysis concludes there could be an anomaly in the structure, but either the structure is not well annotated or the image could be distorted, small, unclear or bad hence the uncertainty.'
|
150 |
elif confidence < 96 and confidence > 92 and error > threshold:
|
151 |
-
diagnosis = 'High possibility that anomaly is false
|
152 |
elif confidence < 92 and error > threshold:
|
153 |
diagnosis = 'Please upload a good ultrasound scan to obtain diagnosis. I cannot recognize the image nor the outlined structure.'
|
154 |
elif confidence < 100 and confidence > 98 and error < threshold:
|
155 |
diagnosis = 'Healthy structure detected. Annotation is correct OR model partially detects healthy area.'
|
156 |
-
|
157 |
-
|
158 |
-
diagnosis += " THIS IS NOT PROFESSIONAL MEDICAL ADVICE. LIAS WITH AN EXPERT"
|
159 |
-
|
160 |
-
return diagnosis
|
161 |
|
162 |
-
|
163 |
-
|
|
|
2 |
from flask_cors import CORS
|
3 |
from PIL import Image, ImageDraw
|
4 |
import io
|
5 |
+
import base64
|
6 |
+
import time
|
7 |
|
8 |
from model import predict
|
9 |
|
10 |
app = Flask(__name__)
|
11 |
CORS(app)
|
12 |
|
13 |
+
# global variables
|
14 |
threshold = 0.02
|
15 |
diagnosis = ''
|
16 |
pc_source = False
|
|
|
25 |
source = data.get('source', 'pc') if data else 'pc'
|
26 |
|
27 |
if source == "pc":
|
|
|
28 |
global pc_source
|
29 |
pc_source = True
|
30 |
+
|
31 |
if not data:
|
32 |
return jsonify({"error": "No JSON data provided"}), 400
|
33 |
img_data = data.get('image')
|
|
|
35 |
category = data.get('category')
|
36 |
view = data.get('view')
|
37 |
|
|
|
38 |
header, encoded = img_data.split(',', 1)
|
39 |
img_bytes = base64.b64decode(encoded)
|
40 |
img = Image.open(io.BytesIO(img_bytes))
|
|
|
45 |
bbox['x'] + bbox['width'],
|
46 |
bbox['y'] + bbox['height']
|
47 |
))
|
48 |
+
|
49 |
print(f"\nParameters:[Category-{category}, View-{view}, Annotations-{bbox}]\n")
|
50 |
print("Processing...\n")
|
51 |
time.sleep(2)
|
52 |
+
|
53 |
error = predict(cropped, view, category)
|
54 |
label = get_label(error)
|
55 |
confidence = 100 - (100 * float(error))
|
56 |
diagnosis = build_diagnosis(error, confidence)
|
57 |
+
|
58 |
draw = ImageDraw.Draw(img)
|
59 |
draw.rectangle(
|
60 |
[bbox['x'], bbox['y'], bbox['x'] + bbox['width'], bbox['y'] + bbox['height']],
|
61 |
outline="red", width=3
|
62 |
)
|
63 |
|
|
|
64 |
buffered = io.BytesIO()
|
65 |
cropped.save(buffered, format="PNG")
|
66 |
processed_b64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
|
|
|
68 |
|
69 |
print(f"Results: Error-{error}, Comment-{label}, Confidence-{confidence}, Diagnosis-{diagnosis}\n")
|
70 |
print(f"Rendering results to: {source} \n")
|
71 |
+
|
72 |
return jsonify({
|
73 |
"processed_image": processed_data_url,
|
74 |
"category": category,
|
|
|
84 |
view = request.form.get('view')
|
85 |
source_field = request.form.get('source')
|
86 |
image_file = request.files.get('image')
|
87 |
+
|
88 |
if not image_file:
|
89 |
return jsonify({"error": "No image file provided"}), 400
|
90 |
+
|
91 |
if not category or not view:
|
92 |
return jsonify({"error": "Missing category or view"}), 400
|
93 |
|
94 |
try:
|
95 |
img = Image.open(image_file)
|
|
|
96 |
if img.mode != 'RGB':
|
97 |
img = img.convert('RGB')
|
|
|
98 |
except Exception as e:
|
99 |
return jsonify({"error": f"Invalid image file: {str(e)}"}), 400
|
100 |
|
101 |
+
print(f"\nParameters:[Category-{category}, View-{view}, Image size-{img.size}]\n")
|
102 |
print("Processing...\n")
|
103 |
+
|
104 |
error = predict(img, view, category)
|
105 |
label = get_label(error)
|
106 |
confidence = 100 - (100 * float(error))
|
107 |
diagnosis = build_diagnosis(error, confidence)
|
108 |
+
|
|
|
109 |
buffered = io.BytesIO()
|
110 |
img.save(buffered, format="PNG")
|
111 |
processed_b64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
|
|
|
125 |
|
126 |
print(f"Results: Error-{error}, Comment-{label}, Confidence-{confidence}, Diagnosis-{diagnosis}\n")
|
127 |
print(f"Rendering results to: {source} \n")
|
128 |
+
|
129 |
return jsonify(response_data)
|
130 |
+
|
131 |
else:
|
132 |
return jsonify({"error": "Unsupported source"}), 400
|
133 |
|
|
|
136 |
return jsonify({"error": str(e)}), 500
|
137 |
|
138 |
def get_label(error):
|
139 |
+
return "⚠️ Anomaly detected" if error > threshold else "✅ Normal structure"
|
|
|
140 |
|
|
|
141 |
def build_diagnosis(error, confidence):
|
142 |
if confidence < 100 and confidence > 98 and error > threshold:
|
143 |
diagnosis = 'High probability that there is an anomaly in the structure.'
|
144 |
elif confidence < 98 and confidence > 96 and error > threshold:
|
145 |
diagnosis = 'My analysis concludes there could be an anomaly in the structure, but either the structure is not well annotated or the image could be distorted, small, unclear or bad hence the uncertainty.'
|
146 |
elif confidence < 96 and confidence > 92 and error > threshold:
|
147 |
+
diagnosis = 'High possibility that anomaly is false positive and image is greatly distorted or irrelevant. Please check the image or the annotation and try again. If results are same, consult an expert.'
|
148 |
elif confidence < 92 and error > threshold:
|
149 |
diagnosis = 'Please upload a good ultrasound scan to obtain diagnosis. I cannot recognize the image nor the outlined structure.'
|
150 |
elif confidence < 100 and confidence > 98 and error < threshold:
|
151 |
diagnosis = 'Healthy structure detected. Annotation is correct OR model partially detects healthy area.'
|
|
|
|
|
|
|
|
|
|
|
152 |
|
153 |
+
diagnosis += " THIS IS NOT PROFESSIONAL MEDICAL ADVICE. LIASE WITH AN EXPERT"
|
154 |
+
return diagnosis
|