pranaya20 commited on
Commit
522e6eb
Β·
verified Β·
1 Parent(s): f646748

update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -77
app.py CHANGED
@@ -1,117 +1,129 @@
1
- # app.py
2
  import gradio as gr
3
  from ultralytics import YOLO
 
4
  import cv2
5
  import numpy as np
6
- import torch
7
  from PIL import Image
8
  import pandas as pd
9
  import os
10
  import uuid
11
  from datetime import datetime
12
- import h3
13
  import folium
14
-
15
- # ========================
16
- # Load Models
17
- # ========================
18
- yolo_model = YOLO("yolov8n.pt")
19
- midas = torch.hub.load("intel-isl/MiDaS", "MiDaS_small", trust_repo=True)
20
- midas.to("cpu").eval()
21
- midas_transforms = torch.hub.load("intel-isl/MiDaS", "transforms", trust_repo=True).small_transform
22
-
23
- # ========================
24
- # CSV Initialization
25
- # ========================
 
 
 
 
 
26
  csv_file = "tree_measurements.csv"
27
  if not os.path.exists(csv_file):
28
- pd.DataFrame(columns=["Timestamp", "Estimated_Height", "Species", "Lat", "Lon", "H3_Index", "Image_File"]).to_csv(csv_file, index=False)
29
 
30
- # Dummy Tree Classifier (replace with a real model or API later)
31
- def classify_species(image):
32
- return "Unknown Species"
 
33
 
34
- # ========================
35
- # Tree Processing Function
36
- # ========================
37
- def process_tree(image, lat, lon):
38
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
39
- img_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
 
40
 
41
- # Run YOLOv8 detection
42
- results = yolo_model(img_cv)
43
  detections = results[0].boxes.data.cpu().numpy()
 
44
  if len(detections) == 0:
45
- return "No tree detected.", None, None
46
 
47
- # Crop first detected tree
48
  x1, y1, x2, y2, conf, cls = detections[0]
49
- tree_crop = img_cv[int(y1):int(y2), int(x1):int(x2)]
50
-
51
- # Estimate height from depth
52
- input_tensor = midas_transforms(Image.fromarray(cv2.cvtColor(tree_crop, cv2.COLOR_BGR2RGB))).unsqueeze(0)
53
- with torch.no_grad():
54
- depth = midas(input_tensor).squeeze().cpu().numpy()
55
- approx_height = round(np.max(depth) - np.min(depth), 2)
56
-
57
- # Species classification
58
- species = classify_species(image)
59
-
60
- # Location and H3
61
- h3_index = h3.geo_to_h3(lat, lon, 9)
 
 
 
 
 
 
 
62
 
63
  # Save image
64
  image_id = f"tree_{uuid.uuid4().hex[:8]}.png"
65
- image.save(image_id)
66
 
67
- # Save to CSV
68
- new_entry = pd.DataFrame([{
69
  "Timestamp": timestamp,
70
- "Estimated_Height": approx_height,
71
- "Species": species,
72
- "Lat": lat,
73
- "Lon": lon,
74
  "H3_Index": h3_index,
 
 
75
  "Image_File": image_id
76
- }])
77
- new_entry.to_csv(csv_file, mode='a', header=False, index=False)
78
 
79
- return f"Height: {approx_height} meters\nSpecies: {species}", Image.fromarray(tree_crop), generate_map()
80
 
81
- # ========================
82
- # Folium Map from CSV
83
- # ========================
84
  def generate_map():
 
 
 
85
  df = pd.read_csv(csv_file)
86
- fmap = folium.Map(location=[20, 78], zoom_start=5)
 
 
 
 
87
  for _, row in df.iterrows():
88
  folium.Marker(
89
- location=[row["Lat"], row["Lon"]],
90
- popup=f"{row['Timestamp']}\n{row['Species']}\n{row['Estimated_Height']} m"
91
  ).add_to(fmap)
92
  fmap.save("map.html")
93
- return "map.html"
 
94
 
95
- # ========================
96
  # Gradio UI
97
- # ========================
98
  with gr.Blocks() as demo:
99
- gr.Markdown("## 🌳 Tree Height & Species Estimator")
 
100
  with gr.Row():
101
- image_input = gr.Image(type="pil", label="Capture/Upload Tree Photo")
102
- lat_input = gr.Number(label="Latitude")
103
- lon_input = gr.Number(label="Longitude")
104
- submit_btn = gr.Button("Estimate Height & Species")
105
- output_text = gr.Textbox(label="Result")
106
- output_image = gr.Image(label="Detected Tree")
107
- output_map = gr.HTML(label="Tree Map")
108
-
109
- submit_btn.click(
110
- fn=process_tree,
111
- inputs=[image_input, lat_input, lon_input],
112
- outputs=[output_text, output_image, output_map]
113
- )
114
-
115
- # ========================
116
- demo.launch()
117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  from ultralytics import YOLO
3
+ import torch
4
  import cv2
5
  import numpy as np
 
6
  from PIL import Image
7
  import pandas as pd
8
  import os
9
  import uuid
10
  from datetime import datetime
 
11
  import folium
12
+ from h3 import h3
13
+ import base64
14
+
15
+ # Load YOLO model for tree detection
16
+ model = YOLO("yolov8n.pt")
17
+
18
+ # Try loading MiDaS depth model
19
+ try:
20
+ midas = torch.hub.load("intel-isl/MiDaS", "MiDaS_small", trust_repo=True)
21
+ midas.to("cpu").eval()
22
+ midas_transforms = torch.hub.load("intel-isl/MiDaS", "transforms", trust_repo=True).small_transform
23
+ use_depth = True
24
+ except Exception as e:
25
+ print(f"Depth model load failed: {e}")
26
+ use_depth = False
27
+
28
+ # CSV file setup
29
  csv_file = "tree_measurements.csv"
30
  if not os.path.exists(csv_file):
31
+ pd.DataFrame(columns=["Timestamp", "Latitude", "Longitude", "H3_Index", "Height", "Species", "Image_File"]).to_csv(csv_file, index=False)
32
 
33
+ # Dummy classifier
34
+ def classify_tree_species(image):
35
+ # Placeholder - returns fixed label
36
+ return "Generic Tree"
37
 
38
+ # Process function
39
+ def analyze_tree(image, latitude, longitude):
 
 
40
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
41
+ image_np = np.array(image)
42
+ img_cv = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
43
 
44
+ results = model(img_cv)
 
45
  detections = results[0].boxes.data.cpu().numpy()
46
+
47
  if len(detections) == 0:
48
+ return "No tree detected", image, "N/A", generate_map()
49
 
50
+ # First detected tree
51
  x1, y1, x2, y2, conf, cls = detections[0]
52
+ crop = img_cv[int(y1):int(y2), int(x1):int(x2)]
53
+ tree_crop = Image.fromarray(cv2.cvtColor(crop, cv2.COLOR_BGR2RGB))
54
+
55
+ # Depth estimation
56
+ if use_depth:
57
+ try:
58
+ input_tensor = midas_transforms(tree_crop).unsqueeze(0)
59
+ with torch.no_grad():
60
+ depth = midas(input_tensor).squeeze().cpu().numpy()
61
+ approx_height = round(np.max(depth) - np.min(depth), 2)
62
+ except Exception:
63
+ approx_height = "Unavailable"
64
+ else:
65
+ approx_height = "Unavailable"
66
+
67
+ # Geolocation + H3 index
68
+ h3_index = h3.geo_to_h3(float(latitude), float(longitude), 9)
69
+
70
+ # Species
71
+ species = classify_tree_species(tree_crop)
72
 
73
  # Save image
74
  image_id = f"tree_{uuid.uuid4().hex[:8]}.png"
75
+ tree_crop.save(image_id)
76
 
77
+ # Append to CSV
78
+ pd.DataFrame([{
79
  "Timestamp": timestamp,
80
+ "Latitude": latitude,
81
+ "Longitude": longitude,
 
 
82
  "H3_Index": h3_index,
83
+ "Height": approx_height,
84
+ "Species": species,
85
  "Image_File": image_id
86
+ }]).to_csv(csv_file, mode='a', header=False, index=False)
 
87
 
88
+ return f"Height: {approx_height} units\nSpecies: {species}", tree_crop, species, generate_map()
89
 
90
+ # Render map
 
 
91
  def generate_map():
92
+ if not os.path.exists(csv_file):
93
+ return "No map yet."
94
+
95
  df = pd.read_csv(csv_file)
96
+ if df.empty:
97
+ return "No map data."
98
+
99
+ lat, lon = df.iloc[-1][["Latitude", "Longitude"]]
100
+ fmap = folium.Map(location=[lat, lon], zoom_start=14)
101
  for _, row in df.iterrows():
102
  folium.Marker(
103
+ location=[row["Latitude"], row["Longitude"]],
104
+ popup=f"{row['Species']} ({row['Height']} units)"
105
  ).add_to(fmap)
106
  fmap.save("map.html")
107
+ with open("map.html", "r", encoding="utf-8") as f:
108
+ return f.read()
109
 
 
110
  # Gradio UI
 
111
  with gr.Blocks() as demo:
112
+ gr.Markdown("## 🌳 Tree Height & Species Estimator with Map & Logger")
113
+
114
  with gr.Row():
115
+ image_input = gr.Image(type="pil", label="πŸ“Έ Tree Image")
116
+ lat_input = gr.Textbox(label="🌍 Latitude", placeholder="e.g., 12.9716")
117
+ lon_input = gr.Textbox(label="🌍 Longitude", placeholder="e.g., 77.5946")
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
+ btn = gr.Button("Analyze Tree")
120
+
121
+ output_text = gr.Textbox(label="πŸ“ Results")
122
+ output_crop = gr.Image(label="🌲 Detected Tree")
123
+ output_species = gr.Textbox(label="🌳 Species")
124
+ map_html = gr.HTML(label="πŸ—ΊοΈ Tree Map")
125
+
126
+ btn.click(analyze_tree, inputs=[image_input, lat_input, lon_input],
127
+ outputs=[output_text, output_crop, output_species, map_html])
128
+
129
+ demo.launch()