aryn25 commited on
Commit
cb3c56d
·
verified ·
1 Parent(s): b7ec651

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -0
app.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import BlipProcessor, BlipForConditionalGeneration
2
+ from sentence_transformers import SentenceTransformer
3
+ import gradio as gr
4
+ from PIL import Image
5
+ import torch
6
+ import requests
7
+ from bs4 import BeautifulSoup
8
+
9
+ # Load BLIP Model
10
+ blip_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
11
+ blip_model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
12
+
13
+ # Map common fish names to FishBase scientific names
14
+ name_map = {
15
+ "pufferfish": "Tetraodon",
16
+ "stonefish": "Synanceia",
17
+ "lionfish": "Pterois",
18
+ "tuna": "Thunnus",
19
+ "salmon": "Salmo-salar",
20
+ "catfish": "Ictalurus",
21
+ "tilapia": "Oreochromis"
22
+ }
23
+
24
+ # Poisonous species (scientific names)
25
+ poisonous_species = ["Tetraodon", "Synanceia", "Pterois"]
26
+
27
+ # FishBase scraping function
28
+ def get_fishbase_summary(scientific_name):
29
+ search_url = f"https://www.fishbase.se/summary/{scientific_name}.html"
30
+ try:
31
+ response = requests.get(search_url, timeout=10)
32
+ if response.status_code != 200:
33
+ return f"FishBase entry not found for: {scientific_name}"
34
+
35
+ soup = BeautifulSoup(response.text, "html.parser")
36
+ summary_section = soup.find("div", {"id": "ssummary"})
37
+ if summary_section:
38
+ paragraphs = summary_section.find_all("p")
39
+ text = "\n\n".join(p.get_text(strip=True) for p in paragraphs if p.get_text(strip=True))
40
+ return text or f"No summary available for {scientific_name}"
41
+ else:
42
+ return f"No detailed summary found for {scientific_name}"
43
+
44
+ except Exception as e:
45
+ return f"Error fetching FishBase data for {scientific_name}: {str(e)}"
46
+
47
+ # Fish identification function
48
+ def identify_fish(image):
49
+ # Step 1: Generate caption from image
50
+ inputs = blip_processor(image, return_tensors="pt")
51
+ out = blip_model.generate(**inputs)
52
+ caption = blip_processor.decode(out[0], skip_special_tokens=True)
53
+
54
+ # Step 2: Extract fish name from caption
55
+ fish_name = None
56
+ for name in name_map:
57
+ if name in caption.lower():
58
+ fish_name = name
59
+ break
60
+
61
+ if not fish_name:
62
+ return f"❌ Could not identify a known fish species in the image caption: '{caption}'"
63
+
64
+ # Step 3: Lookup in FishBase
65
+ scientific_name = name_map[fish_name]
66
+ summary = get_fishbase_summary(scientific_name)
67
+
68
+ # Step 4: Check toxicity
69
+ is_poisonous = "Yes 🧪" if scientific_name in poisonous_species else "No ✅"
70
+
71
+ # Step 5: Final Output
72
+ return f"**Image Caption:** {caption}\n\n**Detected Fish:** {fish_name.title()}\n**Scientific Name:** {scientific_name}\n**Poisonous:** {is_poisonous}\n\n**📚 FishBase Info:**\n{summary}"
73
+
74
+ # Gradio UI
75
+ demo = gr.Interface(
76
+ fn=identify_fish,
77
+ inputs=gr.Image(type="pil"),
78
+ outputs="markdown",
79
+ title="🐟 Smart Fish Identifier (BLIP + FishBase)",
80
+ description="Upload a fish image. We use BLIP to describe the fish, match it with known species, then fetch info from FishBase to check if it's poisonous."
81
+ )
82
+
83
+ if __name__ == '__main__':
84
+ demo.launch()