Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -7,8 +7,8 @@ from tensorflow import keras
|
|
7 |
from keras.models import load_model
|
8 |
|
9 |
# Load the classification model
|
10 |
-
|
11 |
-
|
12 |
|
13 |
# Load the mineral detection model
|
14 |
mineral_detection_model = tf.keras.models.load_model("mineral_detection_model_Final_4_18_2024.h5")
|
@@ -22,6 +22,7 @@ mineral_facts = {
|
|
22 |
'plagioclase': "Hardness: 6-6.5\nMagnetism: None\nDensity: 2.6-2.8 g/cm³\nColors: White, gray, green\nDescription: A series of feldspar minerals ranging from sodium-rich albite to calcium-rich anorthite.",
|
23 |
'staurolite': "Hardness: 7-7.5\nMagnetism: None\nDensity: 3.6-3.8 g/cm³\nColors: Brown, reddish-brown, black\nDescription: A nesosilicate mineral with a distinctive cruciform twinning habit, commonly found in metamorphic rocks."
|
24 |
}
|
|
|
25 |
# Function to preprocess the image for mineral detection
|
26 |
def preprocess_image_detection(img_array):
|
27 |
if img_array is None:
|
@@ -38,34 +39,30 @@ def preprocess_image_classification(img_array):
|
|
38 |
return None
|
39 |
img = (img_array * 255).astype(np.uint8) # Convert back to uint8
|
40 |
img_array = cv2.resize(img, (224, 224)) # Resize to 224x224
|
41 |
-
img_array
|
42 |
-
img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
|
43 |
return img_array
|
44 |
|
45 |
# Define the function to detect if the input is a mineral
|
46 |
def detect_mineral(image):
|
47 |
if image is not None:
|
48 |
image = Image.fromarray(np.array(image).astype(np.uint8), 'RGB')
|
49 |
-
image =
|
50 |
-
image = Image.fromarray(image.astype(np.uint8), 'RGB')
|
51 |
-
image = image.resize((150, 150)) # Assuming the model expects 150x150 images
|
52 |
image = np.array(image) / 255.0
|
53 |
-
image = np.expand_dims(image, axis=0)
|
54 |
-
|
55 |
# Make prediction
|
56 |
prediction = mineral_detection_model.predict(image)
|
57 |
is_mineral = prediction[0][0] < 0.5 # Assuming binary classification
|
58 |
return is_mineral
|
59 |
else:
|
60 |
-
# Handle the case where no image is provided
|
61 |
return "No image provided."
|
62 |
|
63 |
-
# Define the function to make predictions
|
64 |
def classify_image(image):
|
65 |
# Check if the input is a mineral
|
66 |
is_mineral = detect_mineral(image)
|
67 |
if not is_mineral:
|
68 |
-
return "Input is not a Microscopic mineral thin section
|
69 |
|
70 |
# Preprocess the image for classification
|
71 |
image = preprocess_image_classification(np.array(image))
|
@@ -73,26 +70,18 @@ def classify_image(image):
|
|
73 |
return "Error preprocessing image.", "", ""
|
74 |
|
75 |
# Make prediction
|
76 |
-
prediction =
|
77 |
class_idx = np.argmax(prediction)
|
78 |
-
prediction_scores = prediction[0]
|
79 |
|
80 |
-
|
81 |
prediction_scores_percentages = [f"{score * 100:.2f}%" for score in prediction_scores]
|
82 |
|
83 |
-
# Get the predicted class name and key facts
|
84 |
predicted_class_name = class_labels[class_idx]
|
85 |
predicted_scores = "\n".join([f"{label}: {score}" for label, score in zip(class_labels, prediction_scores_percentages)])
|
86 |
mineral_key_facts = mineral_facts.get(predicted_class_name, "No key facts available for this mineral.")
|
87 |
|
88 |
return predicted_class_name, predicted_scores, mineral_key_facts
|
89 |
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
DESCRIPTION = '''
|
97 |
<div>
|
98 |
<h1 style="text-align: center;">Microscopic Mineral Identification App</h1>
|
@@ -102,11 +91,11 @@ DESCRIPTION = '''
|
|
102 |
</div>
|
103 |
'''
|
104 |
|
105 |
-
|
106 |
-
# Welcome Message
|
107 |
def welcome(name):
|
108 |
return f"Welcome to Gradio, {name}!"
|
109 |
|
|
|
110 |
js = """
|
111 |
function createGradioAnimation() {
|
112 |
var container = document.createElement('div');
|
@@ -115,7 +104,6 @@ function createGradioAnimation() {
|
|
115 |
container.style.fontWeight = 'bold';
|
116 |
container.style.textAlign = 'center';
|
117 |
container.style.marginBottom = '20px';
|
118 |
-
|
119 |
var text = 'Welcome to Gradio!';
|
120 |
for (var i = 0; i < text.length; i++) {
|
121 |
(function(i){
|
@@ -124,50 +112,36 @@ function createGradioAnimation() {
|
|
124 |
letter.style.opacity = '0';
|
125 |
letter.style.transition = 'opacity 0.5s';
|
126 |
letter.innerText = text[i];
|
127 |
-
|
128 |
container.appendChild(letter);
|
129 |
-
|
130 |
setTimeout(function() {
|
131 |
letter.style.opacity = '1';
|
132 |
}, 50);
|
133 |
}, i * 250);
|
134 |
})(i);
|
135 |
}
|
136 |
-
|
137 |
var gradioContainer = document.querySelector('.gradio-container');
|
138 |
gradioContainer.insertBefore(container, gradioContainer.firstChild);
|
139 |
-
|
140 |
return 'Animation created';
|
141 |
}
|
142 |
"""
|
143 |
|
144 |
-
|
145 |
app_title = "Mineral Identification using AI"
|
146 |
app_description = "This application uses advanced machine learning models to accurately identify and classify different types of minerals from images. Simply upload an image, and the system will provide the predicted mineral class along with its key characteristics and properties."
|
147 |
|
148 |
custom_css = """
|
149 |
.gradio-container {display: flex; justify-content: center; align-items: center; height: 100vh;}
|
150 |
-
|
151 |
-
|
152 |
#title-container {
|
153 |
-
display: flex;
|
154 |
-
align-items: center;
|
155 |
-
justify-content: center;
|
156 |
-
margin-bottom: 20px;
|
157 |
}
|
158 |
-
|
159 |
#app-title {
|
160 |
margin-right: 20px; /* Adjust the spacing between the title and logo */
|
161 |
}
|
162 |
-
|
163 |
#logo-img {
|
164 |
-
width: 50px; /* Adjust the logo size
|
165 |
height: 50px;
|
166 |
}
|
167 |
-
|
168 |
"""
|
169 |
|
170 |
-
|
171 |
with gr.Blocks(
|
172 |
title=app_title,
|
173 |
css=custom_css,
|
@@ -176,25 +150,20 @@ with gr.Blocks(
|
|
176 |
) as demo:
|
177 |
gr.Markdown(DESCRIPTION)
|
178 |
|
179 |
-
#
|
180 |
with gr.Row():
|
181 |
image_input = gr.Image(elem_id="image_input", type="pil")
|
182 |
output_components = [
|
183 |
gr.Textbox(label="Mineral Name", elem_id="predicted_class_name"),
|
184 |
gr.Textbox(label="Prediction Scores of Model", elem_id="predicted_scores", lines=5),
|
185 |
-
gr.Textbox(label="Key Facts About Mineral", elem_id="mineral_key_facts", lines=8)
|
186 |
]
|
187 |
image_button = gr.Button("Classify Mineral")
|
188 |
image_button.click(classify_image, inputs=image_input, outputs=output_components)
|
189 |
|
190 |
-
with gr.Row():
|
191 |
-
gr.Textbox(label="Mineral Detection", elem_id="mineral_detection_output", lines=3)
|
192 |
-
gr.Textbox(label="Mineral Classification", elem_id="mineral_classification_output", lines=3)
|
193 |
-
gr.Textbox(label="Mineral Key Facts", elem_id="mineral_key_facts_output", lines=8)
|
194 |
gr.Examples(
|
195 |
-
examples=["Gradio examples/Biotite1.jpg","Gradio examples/Biotite2.jpg","Gradio examples/Olivine1.jpg","Gradio examples/Plagioclase1.jpg"],
|
196 |
inputs=image_input,
|
197 |
-
|
198 |
-
|
199 |
)
|
200 |
-
|
|
|
|
7 |
from keras.models import load_model
|
8 |
|
9 |
# Load the classification model
|
10 |
+
mineral_classification_model = "Hugging_face_model_final.h5"
|
11 |
+
mineral_classification_model = tf.keras.models.load_model(mineral_classification_model)
|
12 |
|
13 |
# Load the mineral detection model
|
14 |
mineral_detection_model = tf.keras.models.load_model("mineral_detection_model_Final_4_18_2024.h5")
|
|
|
22 |
'plagioclase': "Hardness: 6-6.5\nMagnetism: None\nDensity: 2.6-2.8 g/cm³\nColors: White, gray, green\nDescription: A series of feldspar minerals ranging from sodium-rich albite to calcium-rich anorthite.",
|
23 |
'staurolite': "Hardness: 7-7.5\nMagnetism: None\nDensity: 3.6-3.8 g/cm³\nColors: Brown, reddish-brown, black\nDescription: A nesosilicate mineral with a distinctive cruciform twinning habit, commonly found in metamorphic rocks."
|
24 |
}
|
25 |
+
|
26 |
# Function to preprocess the image for mineral detection
|
27 |
def preprocess_image_detection(img_array):
|
28 |
if img_array is None:
|
|
|
39 |
return None
|
40 |
img = (img_array * 255).astype(np.uint8) # Convert back to uint8
|
41 |
img_array = cv2.resize(img, (224, 224)) # Resize to 224x224
|
42 |
+
img_array is expected to be uint8 and with batch dimension
|
|
|
43 |
return img_array
|
44 |
|
45 |
# Define the function to detect if the input is a mineral
|
46 |
def detect_mineral(image):
|
47 |
if image is not None:
|
48 |
image = Image.fromarray(np.array(image).astype(np.uint8), 'RGB')
|
49 |
+
image = image.resize((150, 150)) # Resize to 150x150
|
|
|
|
|
50 |
image = np.array(image) / 255.0
|
51 |
+
image = np.expand_dims(image, axis=0) # Add batch dimension
|
52 |
+
|
53 |
# Make prediction
|
54 |
prediction = mineral_detection_model.predict(image)
|
55 |
is_mineral = prediction[0][0] < 0.5 # Assuming binary classification
|
56 |
return is_mineral
|
57 |
else:
|
|
|
58 |
return "No image provided."
|
59 |
|
60 |
+
# Define the function to make predictions for mineral classification
|
61 |
def classify_image(image):
|
62 |
# Check if the input is a mineral
|
63 |
is_mineral = detect_mineral(image)
|
64 |
if not is_mineral:
|
65 |
+
return "Input is not a Microscopic mineral thin section. Please insert a mineral thin section.", "", ""
|
66 |
|
67 |
# Preprocess the image for classification
|
68 |
image = preprocess_image_classification(np.array(image))
|
|
|
70 |
return "Error preprocessing image.", "", ""
|
71 |
|
72 |
# Make prediction
|
73 |
+
prediction = mineral_classification_model.predict(image)
|
74 |
class_idx = np.argmax(prediction)
|
|
|
75 |
|
76 |
+
prediction_scores = prediction[0]
|
77 |
prediction_scores_percentages = [f"{score * 100:.2f}%" for score in prediction_scores]
|
78 |
|
|
|
79 |
predicted_class_name = class_labels[class_idx]
|
80 |
predicted_scores = "\n".join([f"{label}: {score}" for label, score in zip(class_labels, prediction_scores_percentages)])
|
81 |
mineral_key_facts = mineral_facts.get(predicted_class_name, "No key facts available for this mineral.")
|
82 |
|
83 |
return predicted_class_name, predicted_scores, mineral_key_facts
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
DESCRIPTION = '''
|
86 |
<div>
|
87 |
<h1 style="text-align: center;">Microscopic Mineral Identification App</h1>
|
|
|
91 |
</div>
|
92 |
'''
|
93 |
|
94 |
+
# Welcome Message function
|
|
|
95 |
def welcome(name):
|
96 |
return f"Welcome to Gradio, {name}!"
|
97 |
|
98 |
+
# Custom JavaScript for an animation when opening the app
|
99 |
js = """
|
100 |
function createGradioAnimation() {
|
101 |
var container = document.createElement('div');
|
|
|
104 |
container.style.fontWeight = 'bold';
|
105 |
container.style.textAlign = 'center';
|
106 |
container.style.marginBottom = '20px';
|
|
|
107 |
var text = 'Welcome to Gradio!';
|
108 |
for (var i = 0; i < text.length; i++) {
|
109 |
(function(i){
|
|
|
112 |
letter.style.opacity = '0';
|
113 |
letter.style.transition = 'opacity 0.5s';
|
114 |
letter.innerText = text[i];
|
|
|
115 |
container.appendChild(letter);
|
|
|
116 |
setTimeout(function() {
|
117 |
letter.style.opacity = '1';
|
118 |
}, 50);
|
119 |
}, i * 250);
|
120 |
})(i);
|
121 |
}
|
|
|
122 |
var gradioContainer = document.querySelector('.gradio-container');
|
123 |
gradioContainer.insertBefore(container, gradioContainer.firstChild);
|
|
|
124 |
return 'Animation created';
|
125 |
}
|
126 |
"""
|
127 |
|
|
|
128 |
app_title = "Mineral Identification using AI"
|
129 |
app_description = "This application uses advanced machine learning models to accurately identify and classify different types of minerals from images. Simply upload an image, and the system will provide the predicted mineral class along with its key characteristics and properties."
|
130 |
|
131 |
custom_css = """
|
132 |
.gradio-container {display: flex; justify-content: center; align-items: center; height: 100vh;}
|
|
|
|
|
133 |
#title-container {
|
134 |
+
display: flex; align-items: center; justify-content: center; margin-bottom: 20px;
|
|
|
|
|
|
|
135 |
}
|
|
|
136 |
#app-title {
|
137 |
margin-right: 20px; /* Adjust the spacing between the title and logo */
|
138 |
}
|
|
|
139 |
#logo-img {
|
140 |
+
width: 50px; /* Adjust the logo size */
|
141 |
height: 50px;
|
142 |
}
|
|
|
143 |
"""
|
144 |
|
|
|
145 |
with gr.Blocks(
|
146 |
title=app_title,
|
147 |
css=custom_css,
|
|
|
150 |
) as demo:
|
151 |
gr.Markdown(DESCRIPTION)
|
152 |
|
153 |
+
# Create interface components
|
154 |
with gr.Row():
|
155 |
image_input = gr.Image(elem_id="image_input", type="pil")
|
156 |
output_components = [
|
157 |
gr.Textbox(label="Mineral Name", elem_id="predicted_class_name"),
|
158 |
gr.Textbox(label="Prediction Scores of Model", elem_id="predicted_scores", lines=5),
|
159 |
+
gr.Textbox(label="Key Facts About Mineral", elem_id="mineral_key_facts", lines=8),
|
160 |
]
|
161 |
image_button = gr.Button("Classify Mineral")
|
162 |
image_button.click(classify_image, inputs=image_input, outputs=output_components)
|
163 |
|
|
|
|
|
|
|
|
|
164 |
gr.Examples(
|
165 |
+
examples=["Gradio examples/Biotite1.jpg", "Gradio examples/Biotite2.jpg", "Gradio examples/Olivine1.jpg", "Gradio examples/Plagioclase1.jpg"],
|
166 |
inputs=image_input,
|
|
|
|
|
167 |
)
|
168 |
+
|
169 |
+
demo.launch(auth_message="Welcome to the Mineral Identification App.")
|