methestrikerx100's picture
Update app.py
9f7a8df verified
raw
history blame
7.74 kB
import tensorflow as tf
from PIL import Image
import numpy as np
import cv2
import gradio as gr
from tensorflow import keras
from keras.models import load_model
import folium
import re
# Load the CNN feature extractor model
from tensorflow.keras.models import load_model
loaded_feature_extractor = load_model("feature_extractor_model")
# Load the SVM model
import pickle
with open("svm_model_probablity.pkl", 'rb') as file:
loaded_svm_model = pickle.load(file)
# Load the mineral detection model
mineral_detection_model = tf.keras.models.load_model("mineral_detection_model_Final_4_18_2024.h5")
# Define the class labels
class_labels = ['biotite', 'granite', 'olivine', 'plagioclase', 'staurolite']
mineral_facts = {
'biotite': "Hardness: 2.5-3\nMagnetism: None\nDensity: 2.7-3.3 g/cm³\nColors: Black, brown, green\nDescription: A phyllosilicate mineral of the mica group with a distinctive platy structure.",
'granite': "Hardness: 6-7\nMagnetism: None\nDensity: 2.6-2.7 g/cm³\nColors: Gray, pink, white\nDescription: An intrusive igneous rock composed mainly of quartz, feldspar, and mica.",
'olivine': "Hardness: 6.5-7\nMagnetism: None\nDensity: 3.2-3.4 g/cm³\nColors: Green, yellow-green, brown\nDescription: A nesosilicate mineral with a green, glassy appearance, commonly found in mafic and ultramafic rocks.",
'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.",
'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."
}
# Function to preprocess the image for mineral detection
def preprocess_image_detection(img_array):
if img_array is None:
return None
img = (img_array * 255).astype(np.uint8) # Convert back to uint8
img_array = cv2.resize(img, (150, 150)) # Resize to 150x150
img_array = img_array.astype(np.uint8)
img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
return img_array
# Function to preprocess the image for classification
def preprocess_image_classification(img_array):
if img_array is None:
return None
img = (img_array * 255).astype(np.uint8) # Convert back to uint8
img_array = cv2.resize(img, (224, 224)) # Resize to 224x224
img_array = img_array.astype(np.uint8)
img_array = np.expand_dims(img_array, axis=0) # Add batch dimension
return img_array
# Define the function to detect if the input is a mineral
def detect_mineral(image):
if image is not None:
image = Image.fromarray(np.array(image).astype(np.uint8), 'RGB')
image = np.array(image)
image = Image.fromarray(image.astype(np.uint8), 'RGB')
image = image.resize((150, 150)) # Assuming the model expects 150x150 images
image = np.array(image) / 255.0
image = np.expand_dims(image, axis=0)
# Make prediction
prediction = mineral_detection_model.predict(image)
is_mineral = prediction[0][0] < 0.5 # Assuming binary classification
return is_mineral
else:
# Handle the case where no image is provided
return "No image provided."
# Define the function to make predictions
def classify_image(image):
# Check if the input is a mineral
is_mineral = detect_mineral(image)
if not is_mineral:
return "Input is not a Microscopic mineral thin section, Please Insert a thin section.", "", ""
# Preprocess the image for classification
image = preprocess_image_classification(np.array(image))
if image is None:
return "Error preprocessing image.", "", ""
# Extract features using the loaded CNN feature extractor
image_features = loaded_feature_extractor.predict(image)
# Make prediction using the loaded SVM model
predicted_label = loaded_svm_model.predict(image_features)
class_idx = predicted_label[0]
predicted_class_name = class_labels[class_idx]
# Get probabilities for all classes
probabilities = loaded_svm_model.predict_proba(image_features)[0]
# Convert prediction scores to percentages
prediction_scores_percentages = [f"{score * 100:.2f}%" for score in probabilities]
predicted_scores = "\n".join([f"{label}: {score}" for label, score in zip(class_labels, prediction_scores_percentages)])
# Get key facts about the predicted mineral
mineral_key_facts = mineral_facts.get(predicted_class_name, "No key facts available for this mineral.")
return predicted_class_name, predicted_scores, mineral_key_facts
DESCRIPTION = '''
<div>
<h1 style="text-align: center;">Microscopic Mineral Identification App</h1>
<p>Welcome to our interactive space dedicated to identifying minerals through microscopic imagery. This platform showcases various microscopic images that reveal the intricate patterns and characteristics of different minerals. To get started, you can explore our collection of mineral images or use your own to identify key features such as crystal structure, color variations, and inclusions.</p>
<p>🔎 For a deeper understanding of mineral identification techniques and how to analyze microscopic mineral images, visit our comprehensive <a href="https://example.com/mineral-guide">mineral guide</a>. It provides insights into common mineralogical features and how to recognize them.</p>
<p>🧪 Interested in more advanced mineralogy? Check Mindat which can provide more details about the mineral identified <a href="https://www.mindat.org/"><b>Mindat.org</b></a> section, where we dive into more complex mineral structures and analytical methods.</p>
</div>
'''
# Welcome Message
def welcome(name):
return f"Welcome to Gradio, {name}!"
app_title = "Mineral Identification using AI"
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."
custom_css = """
.gradio-container {display: flex; justify-content: center; align-items: center; height: 100vh;background-color: #f0f0f0;}
#title-container {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
#app-title {
margin-right: 20px; /* Adjust the spacing between the title and logo */
}
#logo-img {
width: 50px; /* Adjust the logo size as needed */
height: 50px;
}
"""
# Gradio Blocks interface
with gr.Blocks(
title=app_title,
css=custom_css,
theme=gr.themes.Monochrome(),
) as demo:
gr.Markdown(DESCRIPTION)
# Create interface components
with gr.Row():
image_input = gr.Image(elem_id="image_input", type="pil")
output_components = [
gr.Textbox(label="Mineral Name", elem_id="predicted_class_name"),
gr.Textbox(label="Prediction Scores of Model", elem_id="predicted_scores", lines=5),
gr.Textbox(label="Key Facts About Mineral", elem_id="mineral_key_facts", lines=8),
]
image_button = gr.Button("Classify Mineral")
image_button.click(
classify_image,
inputs=image_input,
outputs=output_components
)
gr.Examples(
examples=["Gradio examples/Biotite1.jpg", "Gradio examples/Biotite2.jpg", "Gradio examples/Olivine1.jpg", "Gradio examples/Plagioclase1.jpg"],
inputs=image_input,
)
demo.launch(auth_message="Welcome to the Mineral Identification App.")