# Import the libraries import numpy as np import pandas as pd from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.image import load_img, img_to_array from tensorflow.keras.applications.convnext import preprocess_input import gradio as gr # Load the model model = load_model('models/ConvNeXtBase_80_tresh_spp.tf') # Load the taxonomy .csv taxo_df = pd.read_csv('taxonomy/taxonomy_mapping.csv') taxo_df['species'] = taxo_df['species'].str.replace('_', ' ') # Available taxonomic levels taxonomic_levels = ['species', 'genus', 'family', 'order', 'class'] # Function to map predicted class index to class name at the selected taxonomic level def get_class_name(predicted_class, taxonomic_level): unique_labels = sorted(taxo_df[taxonomic_level].unique()) return unique_labels[predicted_class] # Function to aggregate predictions to a higher taxonomic level def aggregate_predictions(predicted_probs, taxonomic_level, class_names): unique_labels = sorted(taxo_df[taxonomic_level].unique()) aggregated_predictions = np.zeros((predicted_probs.shape[0], len(unique_labels))) for idx, row in taxo_df.iterrows(): species = row['species'] higher_level = row[taxonomic_level] species_index = class_names.index(species) # Index of the species in the prediction array higher_level_index = unique_labels.index(higher_level) aggregated_predictions[:, higher_level_index] += predicted_probs[:, species_index] return aggregated_predictions, unique_labels # Function to load and preprocess the image def load_and_preprocess_image(image, target_size=(224, 224)): # Resize the image img_array = img_to_array(image.resize(target_size)) # Expand the dimensions to match model input img_array = np.expand_dims(img_array, axis=0) # Preprocess the image img_array = preprocess_input(img_array) return img_array # Function to make predictions def make_prediction(image, taxonomic_level): # Preprocess the image img_array = load_and_preprocess_image(image) # Get the class names from the 'species' column class_names = sorted(taxo_df['species'].unique()) # Add this line to define class_names # Make a prediction prediction = model.predict(img_array) # Aggregate predictions based on the selected taxonomic level aggregated_predictions, aggregated_class_labels = aggregate_predictions(prediction, taxonomic_level, class_names) # Get the top 5 predictions top_indices = np.argsort(aggregated_predictions[0])[-5:][::-1] # Get predicted class for the top prediction predicted_class_index = np.argmax(aggregated_predictions) predicted_class_name = aggregated_class_labels[predicted_class_index] # Check if common name should be displayed (only at species level) if taxonomic_level == "species": predicted_common_name = taxo_df[taxo_df[taxonomic_level] == predicted_class_name]['common_name'].values[0] output_text = f"