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)