File size: 6,884 Bytes
c82f030
6d70836
c82f030
 
 
6d70836
9372a94
 
 
4529d11
 
 
c82f030
6d70836
3f65192
 
 
 
6d70836
 
3e64c5e
3f65192
 
 
 
 
 
4529d11
6d70836
3f65192
6d70836
c82f030
6d70836
 
 
 
3f65192
c82f030
6d70836
 
 
 
 
 
3f65192
 
 
 
 
 
 
41ca88f
 
 
3f65192
 
 
 
 
 
 
 
 
 
6d70836
bc19b2d
9372a94
 
 
 
 
fdb6f4b
bc19b2d
3f65192
 
 
 
 
bc19b2d
3f65192
 
 
9372a94
bc19b2d
 
6d70836
3f65192
bc19b2d
6d70836
9372a94
fdb6f4b
bc19b2d
9372a94
bc19b2d
6d70836
9372a94
6d70836
3f65192
 
9372a94
6d70836
9372a94
 
3f65192
9372a94
 
 
4529d11
9372a94
 
6d70836
4529d11
9372a94
 
3f65192
 
 
9372a94
83c3d9c
bc19b2d
9372a94
bc19b2d
9372a94
4529d11
 
 
9372a94
 
 
4529d11
9372a94
 
4529d11
9372a94
4529d11
 
9372a94
4529d11
 
9372a94
4529d11
 
 
 
9372a94
4529d11
 
 
9372a94
4529d11
 
 
 
 
 
 
9372a94
4529d11
 
 
 
 
 
 
 
 
9372a94
4529d11
 
 
 
 
 
9372a94
4529d11
9372a94
 
 
bc19b2d
 
 
3f65192
bc19b2d
4529d11
 
3e97108
9372a94
 
 
 
 
 
 
 
 
 
4529d11
 
 
 
8c9554e
4529d11
 
7212915
bc19b2d
6d70836
4529d11
 
9372a94
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
from detectree2model.predictions.predict import run_detectree2
from polygons_processing.postpprocess_detectree2 import postprocess
from generate_tree_images.generate_tree_images import generate_tree_images
from classification.classification_predict import classify
import os
import json
import gradio as gr
import rasterio
import geopandas as gpd
import plotly.graph_objects as go
import numpy as np
import ast

def row_to_feature(row):
    if (row['geometry'].geom_type == 'Polygon'):
        coordinates = row['geometry'].exterior.coords.xy
        coordinate_list = [[x, y] for x, y in zip(coordinates[0], coordinates[1])]
        feature = {
        "id": row["id"],
        "type": "Feature",
        "properties": {"Confidence_score": row["Confidence_score"], "species": row['species']},
        "geometry": {"type": "Polygon", "coordinates": [coordinate_list]},
        }
        return feature

 
   

def export_geojson(df, filename):
    
    features = [row_to_feature(row) for idx, row in df.iterrows()]

    feature_collection = {
        "type": "FeatureCollection",
        "crs": {"type": "name", "properties": {"name": "urn:ogc:def:crs:EPSG::32720"}},
        "features": features,
    } 

    output_geojson = json.dumps(feature_collection)

    with open(f"{filename}.geojson", "w") as f:
        f.write(output_geojson)

    print(f"GeoJSON data exported to '{filename}.geojson' file.")
    
def delete_files_in_directory(directory_path: str) -> None:
    """
    Delete all files in the given directory.

    :param directory_path: Path to the directory
    """
    if not os.path.exists(directory_path):
        return

    if not os.path.isdir(directory_path):
        raise ValueError(f"The provided path '{directory_path}' is not a valid directory.")

    for filename in os.listdir(directory_path):
        file_path = os.path.join(directory_path, filename)
        if os.path.isfile(file_path):
            os.remove(file_path)
            print(f"Deleted file: {file_path}")
        else:
            print(f"Skipped non-file: {file_path}")

def process_image(image_path: str, progress: gr.Progress):
    current_directory = os.getcwd()

    output_directory = os.path.join(current_directory, "outputs")
    if not os.path.exists(output_directory):
        os.makedirs(output_directory)

    progress(0, desc="Deleting files")
    delete_files_in_directory("tiles")
    delete_files_in_directory("tiles/predictions")
    delete_files_in_directory("tiles/predictions_geo")
    delete_files_in_directory("tree_images")
    delete_files_in_directory("detected_trees")
    progress(0.01, desc="Running detectree2")



    run_detectree2(image_path, store_path=output_directory)
    progress(0.2, desc="Ran detectree2")


    processed_output_df = postprocess(output_directory + '/detectree2_delin.geojson', output_directory + '/processed_delin.geojson')
    progress(0.4, desc="Post processed")

    processed_geojson = output_directory + '/processed_delin.geojson'

    progress(0.6, desc="Generating tree images")
    generate_tree_images(processed_geojson, image_path)
    progress(0.7, desc="Generated tree images")

    output_folder = './tree_images'

    processed_output_df = gpd.read_file(processed_geojson)

    all_top_3_list = []  # Initialize an empty list to accumulate all top_3 lists

    for file_name in os.listdir(output_folder):
        file_path = os.path.join(output_folder, file_name)

        probs = classify(file_path)
        top_3 = probs.head(3)
        top_3_list = [[cls, prob] for cls, prob in top_3.items()]

        # Accumulate the top_3_list for each file
        all_top_3_list.append(top_3_list)

    # Assign the accumulated top_3_list to the 'species' column of the dataframe
    processed_output_df['species'] = all_top_3_list

    print(processed_output_df.head())
    print(processed_output_df.columns)

    final_output_path = 'result'

    progress(0.8, desc="Exporting geojson")
    export_geojson(processed_output_df, final_output_path)
    progress(0.9, desc="Exported geojson")

    return final_output_path, image_path

def plot_results(geojson_path, image_path):
    with rasterio.open(image_path) as src:
        tif_image = src.read([1, 2, 3])  # Read the first three bands (RGB)
        tif_transform = src.transform
        height, width = tif_image.shape[1], tif_image.shape[2]

    # Read the GeoJSON file
    geojson_data = gpd.read_file(geojson_path + '.geojson')

    # Create Plotly figure
    fig = go.Figure()

    # Add image to the figure
    fig.add_trace(go.Image(z=tif_image.transpose((1, 2, 0)), hoverinfo = 'none'))

    # Add polygons to the plot
    for idx, row in geojson_data.iterrows():
        coordinates = row['geometry'].exterior.coords.xy
        x, y = list(coordinates[0]), list(coordinates[1])  # Convert to list

        # Transform coordinates to match image pixel space
        x_transformed = [(xi - tif_transform.c) / tif_transform.a for xi in x]
        y_transformed = [(yi - tif_transform.f) / tif_transform.e for yi in y]

        species_info_str = row['species']
        species_info = ast.literal_eval(species_info_str)
        first_array = species_info[0]
        second_array = species_info[1]
        third_array = species_info[2]
        confidence_score = row['Confidence_score']
        hovertemplate = f"Polygon:<br>{idx}<br><br>Species and Probability:<br>{first_array}<br>{second_array}<br>{third_array}<br><br>Confidence:<br>{confidence_score}"

        fig.add_trace(go.Scatter(
            x=x_transformed, 
            y=y_transformed, 
            mode='lines',  
            name = '',
            line=dict(color='red'),
            hovertemplate=hovertemplate,
            hoverinfo='text'
        ))

    fig.update_layout(
        title='TIF Image with Tree Crowns Overlay', 
        xaxis_title='X',
        yaxis_title='Y',
        showlegend=False, # Hide the legend
    )

    return fig



def greet(image_path: str, progress=gr.Progress()):
    geojson_path, image_path = process_image(image_path, progress)
    progress(0.0, desc="Plotting results")
    fig = plot_results (geojson_path, image_path)
    progress(1, desc="Plotted results")
    
    return fig
    
#tif_file_name = "TreeCrownVectorDataset_761588_9673769_20_20_32720.tif"
#tif_input = "/Users/jonathanseele/ETH/Hackathons/EcoHackathon/WeCanopy/test/" + tif_file_name

# File paths
#tif_file_path = '/Users/taekim/ecohackathon/WeCanopy/test/TreeCrownVectorDataset_761588_9673769_20_20_32720.tif'
#geojson_file_path = '/Users/taekim/ecohackathon/WeCanopy/test/result.geojson'

# Read the TIF file


def main():
    demo = gr.Interface(
        fn=greet,
        inputs=gr.File(type='filepath'),
        outputs=gr.Plot(label="Tree Crowns"),
    )

    demo.queue()
    demo.launch(server_name='0.0.0.0', debug=True, show_error=True)

if __name__ == "__main__":
    main()