File size: 3,144 Bytes
8ae2ea0
 
 
 
7f0ac64
8ae2ea0
 
7f0ac64
 
 
 
 
 
 
 
8ae2ea0
 
8b2b3e8
8ae2ea0
7f0ac64
 
 
 
 
 
 
8ae2ea0
7f0ac64
 
 
8ae2ea0
7f0ac64
 
 
 
8ae2ea0
7f0ac64
 
 
8ae2ea0
7f0ac64
 
 
 
 
 
8ae2ea0
 
7f0ac64
8ae2ea0
7f0ac64
 
8b2b3e8
7f0ac64
 
8ae2ea0
7f0ac64
8ae2ea0
7f0ac64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8ae2ea0
7f0ac64
 
8ae2ea0
7f0ac64
 
8ae2ea0
68d7ab1
7f0ac64
8ae2ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import gradio as gr
from ultralytics import YOLO
import cv2
import numpy as np
import torch
import wikipedia
from PIL import Image
import pandas as pd
import os
import uuid
from datetime import datetime
from h3 import h3

# Initialize models
model = YOLO("yolov8n.pt")  # You can change this to a fine-tuned model
midas = torch.hub.load("intel-isl/MiDaS", "MiDaS_small")
midas.to("cpu").eval()
midas_transforms = torch.hub.load("intel-isl/MiDaS", "transforms").small_transform

# CSV path
csv_file = "tree_measurements.csv"
if not os.path.exists(csv_file):
    pd.DataFrame(columns=[
        "Timestamp", "Latitude", "Longitude", "H3_Index", 
        "Estimated_Height", "Species", "Image_File"
    ]).to_csv(csv_file, index=False)

# Convert lat/lon to H3 index
def latlon_to_h3(lat, lon, resolution=9):
    return h3.geo_to_h3(lat, lon, resolution)

# Main processing function
def process_tree_image(image, latitude, longitude):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    img_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)

    # Object detection
    results = model(img_cv)
    detections = results[0].boxes.data.cpu().numpy()

    if len(detections) == 0:
        return "No tree detected", image

    # Crop the first detected tree
    x1, y1, x2, y2, conf, cls = detections[0]
    tree_crop = img_cv[int(y1):int(y2), int(x1):int(x2)]

    # Depth estimation
    input_tensor = midas_transforms(Image.fromarray(cv2.cvtColor(tree_crop, cv2.COLOR_BGR2RGB))).unsqueeze(0)
    with torch.no_grad():
        depth = midas(input_tensor).squeeze().cpu().numpy()
    approx_height = round(np.max(depth) - np.min(depth), 2)

    # Get H3 location index
    h3_index = latlon_to_h3(latitude, longitude)

    # Wikipedia species info
    try:
        species_guess = wikipedia.summary("tree", sentences=1)
    except:
        species_guess = "Could not retrieve species info"

    # Save image with unique name
    image_id = f"tree_{uuid.uuid4().hex[:8]}.png"
    image.save(image_id)

    # Append to CSV
    new_data = pd.DataFrame([{
        "Timestamp": timestamp,
        "Latitude": latitude,
        "Longitude": longitude,
        "H3_Index": h3_index,
        "Estimated_Height": approx_height,
        "Species": species_guess,
        "Image_File": image_id
    }])
    new_data.to_csv(csv_file, mode='a', index=False, header=False)

    return (
        f"πŸ“ Estimated Tree Height: {approx_height} meters\n"
        f"🌍 H3 Location Index: {h3_index}\n"
        f"🌿 Species Info: {species_guess}",
        image
    )

# Gradio UI
interface = gr.Interface(
    fn=process_tree_image,
    inputs=[
        gr.Image(type="pil", label="πŸ“Έ Capture Tree Image"),
        gr.Number(label="🌐 Latitude"),
        gr.Number(label="🌐 Longitude")
    ],
    outputs=[
        gr.Textbox(label="πŸ“Š Tree Info"),
        gr.Image(label="πŸ–ΌοΈ Captured Image")
    ],
    title="🌳 Tree Height & Species Estimator",
    description="Use your webcam or upload an image of a tree. Enter your GPS location to get height, species info, and H3 geolocation. All data is saved to CSV."
)

interface.launch()