Spaces:
Runtime error
Runtime error
File size: 6,427 Bytes
86becbd 13966f4 86becbd 13966f4 86becbd |
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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
from flask import Flask, request, jsonify
from flask_cors import CORS
from PIL import Image, ImageDraw
import io
import base64,time
from model import predict
app = Flask(__name__)
CORS(app)
#global variables
threshold = 0.02
diagnosis = ''
pc_source = False
@app.route('/api/process-annotation', methods=['POST'])
def process_annotation():
try:
if request.content_type and request.content_type.startswith('multipart/form-data'):
source = request.form.get('source', 'telegram')
else:
data = request.get_json()
source = data.get('source', 'pc') if data else 'pc'
if source == "pc":
global pc_source
pc_source = True
if not data:
return jsonify({"error": "No JSON data provided"}), 400
img_data = data.get('image')
bbox = data.get('coordinates')
category = data.get('category')
view = data.get('view')
#Decode base64 image
header, encoded = img_data.split(',', 1)
img_bytes = base64.b64decode(encoded)
img = Image.open(io.BytesIO(img_bytes))
cropped = img.crop((
bbox['x'],
bbox['y'],
bbox['x'] + bbox['width'],
bbox['y'] + bbox['height']
))
print(f"\nParameters:[Category-{category}, View-{view}, Annotations-{bbox}]\n")
print("Processing...\n")
time.sleep(2)
error = predict(cropped, view, category)
label = get_label(error)
confidence = 100 - (100 * float(error))
diagnosis = build_diagnosis(error, confidence)
draw = ImageDraw.Draw(img)
draw.rectangle(
[bbox['x'], bbox['y'], bbox['x'] + bbox['width'], bbox['y'] + bbox['height']],
outline="red", width=3
)
# Re-encode processed images to base64
buffered = io.BytesIO()
cropped.save(buffered, format="PNG")
processed_b64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
processed_data_url = f"data:image/png;base64,{processed_b64}"
print(f"Results: Error-{error}, Comment-{label}, Confidence-{confidence}, Diagnosis-{diagnosis}\n")
print(f"Rendering results to: {source} \n")
return jsonify({
"processed_image": processed_data_url,
"category": category,
"comment": label,
"error": error,
"confidence": confidence,
"threshold": threshold,
"diagnosis": diagnosis
})
elif source == "telegram":
category = request.form.get('category')
view = request.form.get('view')
source_field = request.form.get('source')
image_file = request.files.get('image')
if not image_file:
return jsonify({"error": "No image file provided"}), 400
if not category or not view:
return jsonify({"error": "Missing category or view"}), 400
try:
img = Image.open(image_file)
if img.mode != 'RGB':
img = img.convert('RGB')
except Exception as e:
return jsonify({"error": f"Invalid image file: {str(e)}"}), 400
print(f"\nParameters:[Category-{category}, View-{view}, Image size-{img.size}\n")
print("Processing...\n")
error = predict(img, view, category)
label = get_label(error)
confidence = 100 - (100 * float(error))
diagnosis = build_diagnosis(error, confidence)
# Convert image back to base64 for response
buffered = io.BytesIO()
img.save(buffered, format="PNG")
processed_b64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
processed_data_url = f"data:image/png;base64,{processed_b64}"
response_data = {
"processed_image": processed_data_url,
"category": category,
"view": view,
"comment": label,
"error": error,
"confidence": confidence,
"threshold": threshold,
"diagnosis": diagnosis,
"source": "telegram"
}
print(f"Results: Error-{error}, Comment-{label}, Confidence-{confidence}, Diagnosis-{diagnosis}\n")
print(f"Rendering results to: {source} \n")
return jsonify(response_data)
else:
return jsonify({"error": "Unsupported source"}), 400
except Exception as e:
print(f"Unexpected error: {e}")
return jsonify({"error": str(e)}), 500
def get_label(error):
label = "⚠️ Anomaly detected" if error > threshold else "✅ Normal structure"
return label
#RUBRIC
def build_diagnosis(error, confidence):
if confidence < 100 and confidence > 98 and error > threshold:
diagnosis = 'High probability that there is an anomaly in the structure.'
elif confidence < 98 and confidence > 96 and error > threshold:
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.'
elif confidence < 96 and confidence > 92 and error > threshold:
diagnosis = 'High possibility that anomaly is false psoitive and image is greatly distorted or irrelevant. Please check the image or the annotation and try again. If results are same, consult an expert.'
elif confidence < 92 and error > threshold:
diagnosis = 'Please upload a good ultrasound scan to obtain diagnosis. I cannot recognize the image nor the outlined structure.'
elif confidence < 100 and confidence > 98 and error < threshold:
diagnosis = 'Healthy structure detected. Annotation is correct OR model partially detects healthy area.'
diagnosis += " THIS IS NOT PROFESSIONAL MEDICAL ADVICE. LIAS WITH AN EXPERT"
return diagnosis
if __name__ == '__main__':
app.run(debug=True, port=5000) |