File size: 5,215 Bytes
57b4d6e
9643386
133fb5d
 
313728a
133fb5d
313728a
133fb5d
3d80884
bb32dda
 
 
 
 
93e8de0
133fb5d
3d80884
 
1bd92fa
fc38a48
9643386
313728a
 
 
fc38a48
313728a
 
 
 
 
 
fc38a48
313728a
 
fc38a48
313728a
 
fc38a48
313728a
 
fc38a48
313728a
 
 
 
 
 
 
 
 
 
 
 
9643386
313728a
 
9643386
313728a
 
 
 
 
 
 
57b4d6e
9643386
 
 
 
313728a
 
 
 
 
 
 
 
9643386
 
133fb5d
1bd92fa
133fb5d
3d80884
1bd92fa
 
3d80884
133fb5d
3d80884
133fb5d
 
bb32dda
594af3a
fc38a48
6f3e953
 
 
fc38a48
7b18cbe
 
 
 
fc38a48
 
 
bb32dda
 
fc38a48
 
 
 
 
 
883ce52
fc38a48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bb32dda
ccc2bbb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import pandas as pd
import numpy as np
import joblib
from skimage.measure import shannon_entropy
from skimage.color import rgb2hsv
from scipy.ndimage import generic_filter
import cv2
from PIL import Image
from sklearn.preprocessing import LabelEncoder

# Initialize LabelEncoder for gender encoding
gender_encoder = LabelEncoder()
gender_encoder.fit(['Female', 'Male'])  # Ensure that the labels are ordered

# Function to extract features from the image
def extract_features(image):
    # Convert PIL image to NumPy array
    image = np.array(image) 

    # Extract RGB means
    meanr = np.mean(image[:, :, 0])  # Red channel
    meang = np.mean(image[:, :, 1])  # Green channel
    meanb = np.mean(image[:, :, 2])  # Blue channel

    # Convert to HSI and compute HHR
    hsv_image = rgb2hsv(image)
    hue = hsv_image[:, :, 0]
    high_hue_pixels = np.sum(hue > 0.95)
    total_pixels = hue.size
    HHR = high_hue_pixels / total_pixels

    # Convert to Grayscale
    gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

    # Compute Entropy
    Ent = shannon_entropy(gray_image)

    # Compute Brightness
    B = np.mean(gray_image)

    # Sliding window for gray-level features
    def g1_filter(window):
        return window[4] - np.min(window)

    def g2_filter(window):
        return np.max(window) - window[4]

    def g3_filter(window):
        return window[4] - np.mean(window)

    def g4_filter(window):
        return np.std(window)

    def g5_filter(window):
        return window[4]

    # Apply filters with 3x3 window
    g1 = generic_filter(gray_image, g1_filter, size=3).mean()
    g2 = generic_filter(gray_image, g2_filter, size=3).mean()
    g3 = generic_filter(gray_image, g3_filter, size=3).mean()
    g4 = generic_filter(gray_image, g4_filter, size=3).mean()
    g5 = generic_filter(gray_image, g5_filter, size=3).mean()

    # Return features
    return {
        "meanr": meanr,
        "meang": meang,
        "meanb": meanb,
        "HHR": HHR,
        "Ent": Ent,
        "B": B,
        "g1": g1,
        "g2": g2,
        "g3": g3,
        "g4": g4,
        "g5": g5,
    }

# Function to check if the image is a valid file format
def check_image_format(filepath):
    try:
        # Try opening the image using PIL
        with Image.open(filepath) as img:
            img.verify()  # Verify if it's a valid image file
        return True
    except Exception as e:
        print(f"Error opening image: {e}")
        return False

# Function to predict hemoglobin value with label encoding for gender
def predict_hemoglobin(age, gender, image):
    try:
        # Ensure the image is not None
        if image is None:
            return "Error: No image uploaded. Please upload an image."

        # Check if the image is valid
        if not isinstance(image, Image.Image):
            return "Error: Invalid image format. Please upload a valid image file."

        # Extract features from the image
        features = extract_features(image)

        # Use LabelEncoder to convert gender to numerical value
        features['Gender'] = gender_encoder.transform([gender])[0]
        features['Age'] = age

        # Create a DataFrame for features (do not include Hgb, as it's the predicted value)
        features_df = pd.DataFrame([features])

        # Load the trained model, scaler, and label encoder
        svr_model = joblib.load('svr_model (1).pkl')  # Replace with the actual path to your model file
        scaler = joblib.load('minmax_scaler.pkl')     # Replace with the actual path to your scaler file

        # Ensure that features_df matches the expected training feature set (without 'Hgb')
        expected_columns = ['meanr', 'meang', 'meanb', 'HHR', 'Ent', 'B', 'g1', 'g2', 'g3', 'g4', 'g5', 'Age', 'Gender']

        for col in expected_columns:
            if col not in features_df:
                features_df[col] = 0  # Or some default value to match the expected columns.

        features_df = features_df[expected_columns]  # Ensure the correct order of columns

        # Apply scaling (do not include 'Hgb' as it is the target)
        features_df_scaled = scaler.transform(features_df)

        # Predict hemoglobin using the trained SVR model
        hemoglobin = svr_model.predict(features_df_scaled)[0]

        return f"Predicted Hemoglobin Value: {hemoglobin:.2f}"

    except Exception as e:
        print(f"An error occurred during prediction: {e}")
        return "An error occurred during prediction. Please try again."

# Gradio interface
with gr.Blocks() as anemia_detection_app:
    gr.Markdown("# Hemoglobin Prediction App")
    
    with gr.Row():
        age_input = gr.Number(label="Age", value=25)
        gender_input = gr.Radio(label="Gender", choices=["Male", "Female"], value="Male")
    
    image_input = gr.Image(label="Upload Retinal Image", type="pil")
    output_text = gr.Textbox(label="Predicted Hemoglobin Value")
    
    predict_button = gr.Button("Predict")
    
    predict_button.click(
        fn=predict_hemoglobin,
        inputs=[age_input, gender_input, image_input],
        outputs=output_text
    )

# Run the app
if __name__ == "__main__":
    anemia_detection_app.launch()