Spaces:
Sleeping
Sleeping
dev-deg commited on
Commit ·
30d1897
1
Parent(s): 5591256
init hf repo
Browse files- app.py +20 -0
- data_analyser.py +20 -0
- habitat_classification.py +64 -0
- habitat_data.csv +15 -0
- inferencing.py +44 -0
- latest.pt +0 -0
- species_data.csv +18 -0
app.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
|
| 3 |
+
def process_image(input_image):
|
| 4 |
+
# Your ML model code goes here. For example:
|
| 5 |
+
# annotated_image = annotate_image(input_image)
|
| 6 |
+
# confidence = get_classification_confidence(input_image)
|
| 7 |
+
annotated_image = None
|
| 8 |
+
confidence = 0
|
| 9 |
+
return annotated_image, f"Classification Confidence: {confidence}%"
|
| 10 |
+
|
| 11 |
+
# Define the Gradio interface
|
| 12 |
+
|
| 13 |
+
if __name__ == '__main__':
|
| 14 |
+
iface = gr.Interface(
|
| 15 |
+
fn=process_image,
|
| 16 |
+
inputs="image",
|
| 17 |
+
outputs=["image", "text"],
|
| 18 |
+
title="AMBULANT Benthic Identification System"
|
| 19 |
+
)
|
| 20 |
+
iface.launch(auth=("admin", "pass1234"), share=True)
|
data_analyser.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from inferencing import process_image
|
| 2 |
+
from habitat_classification import classify_habitat
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def process_images(images):
|
| 6 |
+
processed_images = []
|
| 7 |
+
for image in images:
|
| 8 |
+
processed_images.push(process_image(image.read()))
|
| 9 |
+
return processed_images
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def classify_habitat(species_arr):
|
| 13 |
+
result = classify_habitat(species_arr)
|
| 14 |
+
result_str = []
|
| 15 |
+
result_str.push(f"Predicted Classification: {result[0]}")
|
| 16 |
+
result_str.push(f"Confidence: {result[1]:.2f}")
|
| 17 |
+
result_str.push("Classification Probabilities:")
|
| 18 |
+
for classification, probability in result[2].items():
|
| 19 |
+
result_str.push(f"{classification}: {probability:.2f}")
|
| 20 |
+
return result_str
|
habitat_classification.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
|
| 3 |
+
# Step 1: Read the data
|
| 4 |
+
species_data = pd.read_csv('species_data.csv')
|
| 5 |
+
habitat_data = pd.read_csv('habitat_data.csv')
|
| 6 |
+
|
| 7 |
+
# Normalize the column names
|
| 8 |
+
common_column_names = [
|
| 9 |
+
"Species",
|
| 10 |
+
"Habitat: Hard beds",
|
| 11 |
+
"Habitat: Rocky bottoms",
|
| 12 |
+
"Habitat: Seagrass meadows",
|
| 13 |
+
"Habitat: Coralligenous bottoms",
|
| 14 |
+
"Habitat: Detritic bottoms",
|
| 15 |
+
"Habitat: Sandy bottoms",
|
| 16 |
+
"Habitat: Muddy bottoms",
|
| 17 |
+
"Habitat: Other organisms"
|
| 18 |
+
]
|
| 19 |
+
|
| 20 |
+
species_data.columns = common_column_names
|
| 21 |
+
habitat_data.columns = common_column_names[1:] + ["Final classification"]
|
| 22 |
+
|
| 23 |
+
# Step 2: Convert "Yes"/"No" to 1/0 and normalize the values to calculate weights
|
| 24 |
+
species_data.replace({"Yes": 1, "No": 0}, inplace=True)
|
| 25 |
+
habitat_data.replace({"Yes": 1, "No": 0}, inplace=True)
|
| 26 |
+
|
| 27 |
+
species_weights = species_data.iloc[:, 1:].div(species_data.iloc[:, 1:].sum(axis=1), axis=0)
|
| 28 |
+
habitat_weights = habitat_data.iloc[:, :-1].div(habitat_data.iloc[:, :-1].sum(axis=1), axis=0)
|
| 29 |
+
|
| 30 |
+
# Step 3: Create dictionaries to map species to habitats and habitats to final classifications with weights
|
| 31 |
+
species_to_habitat_weights = species_data.set_index('Species').T.to_dict('series')
|
| 32 |
+
final_classification_series = habitat_data['Final classification']
|
| 33 |
+
#habitat_data.drop(columns=['Final classification'], inplace=True)
|
| 34 |
+
|
| 35 |
+
habitat_to_classification_weights = habitat_data.set_index(final_classification_series).T.to_dict('series')
|
| 36 |
+
|
| 37 |
+
# Step 4: Define the classification function
|
| 38 |
+
def classify_habitat(species_list):
|
| 39 |
+
habitat_votes = {col: 0 for col in species_data.columns[1:]}
|
| 40 |
+
classification_votes = {row['Final classification']: 0 for _, row in habitat_data.iterrows()}
|
| 41 |
+
|
| 42 |
+
# Let each species vote for habitats
|
| 43 |
+
for species in species_list:
|
| 44 |
+
if species in species_to_habitat_weights:
|
| 45 |
+
for i, habitat in enumerate(habitat_votes.keys()):
|
| 46 |
+
habitat_votes[habitat] += species_to_habitat_weights[species][i]
|
| 47 |
+
|
| 48 |
+
# Let habitats vote for the final classification
|
| 49 |
+
for habitat, votes in habitat_votes.items():
|
| 50 |
+
for classification in classification_votes.keys():
|
| 51 |
+
classification_votes[classification] += habitat_to_classification_weights[classification][habitat] * votes
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
# Get the classification with the highest vote
|
| 55 |
+
predicted_classification = max(classification_votes, key=classification_votes.get)
|
| 56 |
+
|
| 57 |
+
# Calculate confidence
|
| 58 |
+
total_votes = sum(classification_votes.values())
|
| 59 |
+
confidence = classification_votes[predicted_classification] / total_votes
|
| 60 |
+
|
| 61 |
+
# Calculate individual classification probabilities
|
| 62 |
+
classification_probabilities = {key: value / total_votes for key, value in classification_votes.items()}
|
| 63 |
+
|
| 64 |
+
return predicted_classification, confidence, classification_probabilities
|
habitat_data.csv
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Habitat: Hard beds,Habitat: Rocky bottoms,Habitat: Seagrass meadows,Habitat: Coralligenous bottoms,Habitat: Detritic bottoms,Habitat: Sandy bottoms,Habitat: Muddy bottoms,Habitat: Other organisms,Final classification
|
| 2 |
+
Yes,Yes,Yes,Yes,No,No,No,Yes,MB151 Biocenosis of Mediterranean infralittoral algae
|
| 3 |
+
Yes,Yes,Yes,Yes,No,No,No,Yes,MB251 Mediterannean biogenic reef assemblages of the infralittoral algae biocenosis
|
| 4 |
+
Yes,Yes,Yes,Yes,No,Yes,No,Yes,MB252 Biocenosis of Posidonia oceanica
|
| 5 |
+
No,Yes,Yes,No,Yes,Yes,No,Yes,MB351 Biocenosis of Mediterranean coarse sands and fine gravels mixed by the waves
|
| 6 |
+
No,Yes,Yes,No,Yes,Yes,No,Yes,MB352 Biocenosis of Mediterranean coarse sands and fine gravels under the influence of bottoms currents
|
| 7 |
+
No,Yes,Yes,No,Yes,No,No,Yes,MB353 Biocenosis of Mediterranean infralittoral pebbles
|
| 8 |
+
No,No,Yes,No,No,Yes,No,Yes,MB551 Biocenosis of Mediterranean fine surface sands
|
| 9 |
+
No,No,Yes,No,No,Yes,No,Yes,MB552 Biocenosis of Mediterranean well sorted fine sands
|
| 10 |
+
No,No,Yes,No,No,Yes,Yes,Yes,MB553 Biocenosis of Mediterranean superficial muddy sands in sheltered waters
|
| 11 |
+
Yes,Yes,Yes,Yes,No,No,No,Yes,MC151 Coralligenous biocenosis
|
| 12 |
+
Yes,Yes,Yes,Yes,No,No,No,Yes,MC251 Coralligenous platforms
|
| 13 |
+
No,Yes,Yes,No,Yes,Yes,No,Yes,MC351 Biocenosis of Mediterranean coastal detritic bottoms (without rodolithes)
|
| 14 |
+
No,Yes,Yes,Yes,Yes,Yes,No,Yes,MC352 Assemblages of Mediterranean coastal detritic bottoms biocenosis with rhodolithes
|
| 15 |
+
No,No,Yes,No,Yes,Yes,No,Yes,MC551 Biocenosis of Mediterranean coarse sands and fine gravels under the influence of bottom currents
|
inferencing.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from models.yolo8.ultralytics.ultralytics import YOLO
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import tempfile
|
| 4 |
+
import torch
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
# Function to display detections and segmentation masks
|
| 8 |
+
def display_detections(frame, results):
|
| 9 |
+
detections = []
|
| 10 |
+
for result in results:
|
| 11 |
+
if result.boxes.data.nelement() != 0:
|
| 12 |
+
for detection in result.boxes.data:
|
| 13 |
+
x1, y1, x2, y2, conf, cls = detection.cpu().numpy()
|
| 14 |
+
class_name = result.names[int(cls)]
|
| 15 |
+
detections.append([class_name, conf, x1, y1, x2, y2])
|
| 16 |
+
outframe = results[0].plot()
|
| 17 |
+
return outframe, detections
|
| 18 |
+
|
| 19 |
+
print("No detections")
|
| 20 |
+
return frame, detections
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def process_image(input_image):
|
| 24 |
+
results = model(input_image)
|
| 25 |
+
processed_frame, detections = display_detections(input_image, results)
|
| 26 |
+
|
| 27 |
+
if not detections: # Check if detections list is empty
|
| 28 |
+
return processed_frame, "No detections found"
|
| 29 |
+
|
| 30 |
+
# Convert detections to a DataFrame and then save to a temporary CSV file
|
| 31 |
+
df = pd.DataFrame(detections, columns=["Class", "Confidence", "X1", "Y1", "X2", "Y2"])
|
| 32 |
+
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.csv')
|
| 33 |
+
df.to_csv(temp_file.name, index=False)
|
| 34 |
+
|
| 35 |
+
return processed_frame, temp_file.name
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
# Load YOLO model
|
| 39 |
+
model = YOLO('../models/segmentation/latest.pt')
|
| 40 |
+
model.conf = 0.2
|
| 41 |
+
|
| 42 |
+
if torch.backends.cuda.is_built():
|
| 43 |
+
print(f"CUDA available: {torch.cuda.is_available()}")
|
| 44 |
+
print(f"Device name: {torch.cuda.get_device_name(0)}")
|
latest.pt
ADDED
|
File without changes
|
species_data.csv
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Species,Habitat: Hard beds,Habitat: Rocky bottoms,Habitat: Seagrass meadows,Habitat: Coralligenous bottoms,Habitat: Detritic bottoms,Habitat: Sandy bottoms,Habitat: Muddy bottoms,Habitat: Other organisms
|
| 2 |
+
Asparagopsis taxiformis,Yes,Yes,No,No,No,No,No,No
|
| 3 |
+
Liagora viscida,No,Yes,No,No,No,No,No,No
|
| 4 |
+
Lophocladia Lallemandii,No,No,Yes,No,No,No,No,Yes
|
| 5 |
+
Codium bursa,Yes,No,No,No,Yes,No,No,No
|
| 6 |
+
Ulva compressa,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes
|
| 7 |
+
Dictyopteris polypodioides,Yes,Yes,No,No,No,No,No,No
|
| 8 |
+
Dictyota dichotoma,Yes,Yes,No,No,No,No,No,No
|
| 9 |
+
Padina pavonica,Yes,Yes,No,Yes,No,No,No,No
|
| 10 |
+
Sargassum vulgare,Yes,Yes,Yes,Yes,Yes,No,No,No
|
| 11 |
+
Cymodocea nodosa,No,No,No,No,No,Yes,No,No
|
| 12 |
+
Halophila stipulacea,No,No,No,No,No,Yes,Yes,No
|
| 13 |
+
Posidonia oceanica,Yes,Yes,No,No,Yes,Yes,Yes,No
|
| 14 |
+
Centrostephanus longispinus,Yes,Yes,No,No,No,No,No,No
|
| 15 |
+
Chondrilla nucula,Yes,Yes,Yes,No,No,No,No,No
|
| 16 |
+
Sarcotragus spinosulus,Yes,Yes,No,No,No,No,No,No
|
| 17 |
+
Scalarispongia scalaris,Yes,Yes,Yes,Yes,Yes,No,No,No
|
| 18 |
+
Hermodice carunculata,Yes,Yes,No,No,Yes,No,No,No
|