File size: 4,466 Bytes
fbff24a
 
 
 
 
4d9f978
ad7bb38
 
fbff24a
 
 
b361621
fbff24a
4d9f978
 
 
 
 
fbff24a
 
4d9f978
fbff24a
4d9f978
fbff24a
 
 
4d9f978
fbff24a
 
4d9f978
 
 
fbff24a
4d9f978
fbff24a
09423f1
 
 
 
 
 
ad7bb38
09423f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ad7bb38
09423f1
 
 
 
 
fbff24a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
09423f1
 
fbff24a
 
 
 
 
 
09423f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fbff24a
 
bca7ef4
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
import gradio as gr
from tensorflow import keras
import numpy as np
from PIL import Image
import cv2
import tensorflow as tf
import base64
import io

model = keras.models.load_model('my_model (2).h5')

CLASS_NAMES = ['Non-Tumor', 'Non-Viable-Tumor', 'Viable', 'viable: non-viable']

def make_gradcam_heatmap(img_array, model):
    last_conv_layer = model.get_layer('last_conv_layer')
    grad_model = tf.keras.models.Model(
        [model.inputs],
        [last_conv_layer.output, model.output]
    )
    
    with tf.GradientTape() as tape:
        conv_outputs, predictions = grad_model(img_array)
        pred_index = tf.argmax(predictions[0])
        class_channel = predictions[:, pred_index]
    
    grads = tape.gradient(class_channel, conv_outputs)
    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
    
    conv_outputs = conv_outputs[0]
    heatmap = conv_outputs @ pooled_grads[..., tf.newaxis]
    heatmap = tf.squeeze(heatmap)
    heatmap = tf.maximum(heatmap, 0) / (tf.math.reduce_max(heatmap) + 1e-8)
    
    return heatmap.numpy()

def predict_from_base64(base64_string):
    try:
        if ',' in base64_string:
            base64_string = base64_string.split(',')[1]
        
        image_bytes = base64.b64decode(base64_string)
        img = Image.open(io.BytesIO(image_bytes)).convert('RGB')
        
        img = img.resize((224, 224))
        img_array = np.array(img) / 255.0
        img_array = np.expand_dims(img_array, axis=0)
        
        predictions = model.predict(img_array)
        pred_class = CLASS_NAMES[np.argmax(predictions[0])]
        confidence = float(np.max(predictions[0])) * 100
        
        result_text = f"Prediction: {pred_class}\nConfidence: {confidence:.2f}%\n\n"
        result_text += "All Probabilities:\n"
        for i, name in enumerate(CLASS_NAMES):
            result_text += f"  {name}: {predictions[0][i]*100:.2f}%\n"
        
        try:
            heatmap = make_gradcam_heatmap(img_array, model)
            heatmap = cv2.resize(heatmap, (224, 224))
            heatmap = np.uint8(255 * heatmap)
            heatmap_colored = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
            original = np.array(img)
            superimposed = cv2.addWeighted(original, 0.6, heatmap_colored, 0.4, 0)
            output_image = superimposed
        except Exception as e:
            output_image = np.array(img)
            result_text += f"\n(Grad-CAM unavailable: {str(e)})"
        
        return output_image, result_text
    
    except Exception as e:
        return None, f"Error: {str(e)}"

def predict_from_image(input_image):
    img = Image.fromarray(input_image).convert('RGB')
    img = img.resize((224, 224))
    img_array = np.array(img) / 255.0
    img_array = np.expand_dims(img_array, axis=0)
    
    predictions = model.predict(img_array)
    pred_class = CLASS_NAMES[np.argmax(predictions[0])]
    confidence = float(np.max(predictions[0])) * 100
    
    result_text = f"Prediction: {pred_class}\nConfidence: {confidence:.2f}%\n\n"
    result_text += "All Probabilities:\n"
    for i, name in enumerate(CLASS_NAMES):
        result_text += f"  {name}: {predictions[0][i]*100:.2f}%\n"
    
    try:
        heatmap = make_gradcam_heatmap(img_array, model)
        heatmap = cv2.resize(heatmap, (224, 224))
        heatmap = np.uint8(255 * heatmap)
        heatmap_colored = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)
        original = np.array(img)
        superimposed = cv2.addWeighted(original, 0.6, heatmap_colored, 0.4, 0)
        output_image = superimposed
    except Exception as e:
        output_image = np.array(img)
        result_text += f"\n(Grad-CAM unavailable: {str(e)})"
    
    return output_image, result_text

image_interface = gr.Interface(
    fn=predict_from_image,
    inputs=gr.Image(label="Upload Histopathology Image"),
    outputs=[
        gr.Image(label="Grad-CAM Visualization"),
        gr.Textbox(label="Classification Result")
    ],
    title="Bone Cancer Detection (Osteosarcoma)",
    description="Upload an H&E stained histopathology image."
)

api_interface = gr.Interface(
    fn=predict_from_base64,
    inputs=gr.Textbox(label="Base64 Image String"),
    outputs=[
        gr.Image(label="Grad-CAM Visualization"),
        gr.Textbox(label="Classification Result")
    ],
    api_name="predict_base64"
)

demo = gr.TabbedInterface(
    [image_interface, api_interface],
    ["Upload Image", "API (Base64)"]
)

demo.launch()