CircleStar commited on
Commit
0e77c57
·
verified ·
1 Parent(s): 1214ca6

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,28 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data/ground_truth.tif filter=lfs diff=lfs merge=lfs -text
37
+ data/knn_result.tif filter=lfs diff=lfs merge=lfs -text
38
+ data/teacher_labels.tif filter=lfs diff=lfs merge=lfs -text
39
+ data/training_polygons.tif filter=lfs diff=lfs merge=lfs -text
40
+ polygon_images/polygon_01.png filter=lfs diff=lfs merge=lfs -text
41
+ polygon_images/polygon_02.png filter=lfs diff=lfs merge=lfs -text
42
+ polygon_images/polygon_03.png filter=lfs diff=lfs merge=lfs -text
43
+ polygon_images/polygon_05.png filter=lfs diff=lfs merge=lfs -text
44
+ polygon_images/polygon_06.png filter=lfs diff=lfs merge=lfs -text
45
+ polygon_images/polygon_07.png filter=lfs diff=lfs merge=lfs -text
46
+ polygon_images/polygon_08.png filter=lfs diff=lfs merge=lfs -text
47
+ polygon_images/polygon_09.png filter=lfs diff=lfs merge=lfs -text
48
+ polygon_images/polygon_10.png filter=lfs diff=lfs merge=lfs -text
49
+ polygon_images/polygon_11.png filter=lfs diff=lfs merge=lfs -text
50
+ polygon_images/polygon_12.png filter=lfs diff=lfs merge=lfs -text
51
+ polygon_images/polygon_13.png filter=lfs diff=lfs merge=lfs -text
52
+ polygon_images/polygon_14.png filter=lfs diff=lfs merge=lfs -text
53
+ polygon_images/polygon_15.png filter=lfs diff=lfs merge=lfs -text
54
+ polygon_images/polygon_16.png filter=lfs diff=lfs merge=lfs -text
55
+ polygon_images/polygon_17.png filter=lfs diff=lfs merge=lfs -text
56
+ polygon_images/polygon_18.png filter=lfs diff=lfs merge=lfs -text
57
+ polygon_images/polygon_19.png filter=lfs diff=lfs merge=lfs -text
58
+ polygon_images/polygon_20.png filter=lfs diff=lfs merge=lfs -text
59
+ polygon_images/polygon_21.png filter=lfs diff=lfs merge=lfs -text
60
+ polygon_images/polygon_23.png filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,421 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import matplotlib
4
+ matplotlib.use('Agg')
5
+ import matplotlib.pyplot as plt
6
+ import matplotlib.patches as mpatches
7
+ import rasterio
8
+ import json
9
+ import os
10
+
11
+ # ─────────────────────────────────────────────────────────────────────────────
12
+ # Constants
13
+ # ─────────────────────────────────────────────────────────────────────────────
14
+ N_POLYGONS = 23
15
+
16
+ CLASSES = {
17
+ 1: "Eau",
18
+ 2: "Vergers",
19
+ 3: "Cultures dans le Delta",
20
+ 4: "Zones bâties",
21
+ 5: "Cultures irriguées dans le désert",
22
+ 6: "Cultures non irriguées en zone sèche",
23
+ 7: "Zones sableuses",
24
+ }
25
+
26
+ CLASS_CHOICES = [f"{k} - {v}" for k, v in CLASSES.items()]
27
+
28
+ # Distinctive color palette per class (index 0 = background)
29
+ COLORS_RGB = np.array([
30
+ [20, 20, 20 ], # 0 background
31
+ [0, 100, 220], # 1 eau
32
+ [0, 160, 60], # 2 vergers
33
+ [120, 220, 100], # 3 cultures delta
34
+ [220, 50, 50], # 4 zones bâties
35
+ [255, 165, 0], # 5 cultures irriguées désert
36
+ [160, 90, 30], # 6 cultures non irriguées
37
+ [240, 230, 140], # 7 zones sableuses
38
+ ], dtype=np.uint8)
39
+
40
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
41
+
42
+ # ─────────────────────────────────────────────────────────────────────────────
43
+ # Data loading (once at startup)
44
+ # ─────────────────────────────────────────────────────────────────────────────
45
+ def load_data():
46
+ def read_tif(name):
47
+ path = os.path.join(BASE_DIR, 'data', name)
48
+ with rasterio.open(path) as src:
49
+ return src.read(1)
50
+
51
+ training_ids = read_tif('training_polygons.tif')
52
+ ground_truth = read_tif('ground_truth.tif')
53
+ knn_result = read_tif('knn_result.tif')
54
+ teacher_lbl = read_tif('teacher_labels.tif')
55
+
56
+ with open(os.path.join(BASE_DIR, 'data', 'polygon_teacher_classes.json')) as f:
57
+ polygon_teacher = {int(k): v for k, v in json.load(f).items()}
58
+
59
+ # Pre-compute KNN confusion matrix (pixels where GT > 0)
60
+ gt_flat = ground_truth.flatten()
61
+ knn_flat = knn_result.flatten()
62
+ valid = gt_flat > 0
63
+ knn_matrix = np.zeros((7, 7), dtype=np.int64)
64
+ np.add.at(knn_matrix, (gt_flat[valid] - 1, knn_flat[valid] - 1), 1)
65
+ knn_oa = knn_matrix.diagonal().sum() / knn_matrix.sum()
66
+
67
+ # Downsample rasters to ~500 px height for display
68
+ from PIL import Image as PILImage
69
+ h, w = training_ids.shape
70
+ new_h, new_w = 500, int(w * 500 / h)
71
+
72
+ def small(arr):
73
+ return np.array(PILImage.fromarray(arr).resize((new_w, new_h), PILImage.NEAREST))
74
+
75
+ return dict(
76
+ training_ids = training_ids,
77
+ ground_truth = ground_truth,
78
+ knn_result = knn_result,
79
+ teacher_lbl = teacher_lbl,
80
+ polygon_teacher= polygon_teacher,
81
+ knn_matrix = knn_matrix,
82
+ knn_oa = knn_oa,
83
+ tr_small = small(training_ids),
84
+ gt_small = small(ground_truth),
85
+ knn_small = small(knn_result),
86
+ )
87
+
88
+ DATA = load_data()
89
+
90
+ # ─────────────────────────────────────────────────────────────────────────────
91
+ # Visualization helpers
92
+ # ─────────────────────────────────────────────────────────────────────────────
93
+ def raster_to_rgb(arr):
94
+ rgb = COLORS_RGB[arr]
95
+ return rgb
96
+
97
+ def legend_patches():
98
+ return [mpatches.Patch(color=COLORS_RGB[i]/255, label=f"{i} – {CLASSES[i]}")
99
+ for i in range(1, 8)]
100
+
101
+ def fig_maps(student_labels):
102
+ fig, axes = plt.subplots(1, 3, figsize=(18, 6))
103
+ fig.patch.set_facecolor('#f5f5f5')
104
+
105
+ student_map = np.zeros_like(DATA['tr_small'])
106
+ for pid, label in enumerate(student_labels, 1):
107
+ if label is not None:
108
+ student_map[DATA['tr_small'] == pid] = label
109
+
110
+ titles = [
111
+ "Votre interprétation\n(polygones d'entraînement)",
112
+ "Classification KNN\n(carte produite par l'IA)",
113
+ "Vérité terrain\n(zones de validation)",
114
+ ]
115
+ rasters = [student_map, DATA['knn_small'], DATA['gt_small']]
116
+ for ax, rast, title in zip(axes, rasters, titles):
117
+ ax.imshow(raster_to_rgb(rast), interpolation='nearest')
118
+ ax.set_title(title, fontsize=11, fontweight='bold', pad=8)
119
+ ax.axis('off')
120
+
121
+ fig.legend(handles=legend_patches(), loc='lower center', ncol=4,
122
+ bbox_to_anchor=(0.5, -0.06), fontsize=9, framealpha=0.9)
123
+ plt.tight_layout()
124
+ return fig
125
+
126
+ def fig_knn_matrix():
127
+ matrix = DATA['knn_matrix']
128
+ oa = DATA['knn_oa']
129
+
130
+ short = ["Eau", "Vergers", "Δ-Cult.", "Bâti", "Irr.-Dés.", "Non-Irr.", "Sable"]
131
+ fig, ax = plt.subplots(figsize=(9, 7))
132
+
133
+ row_tot = matrix.sum(axis=1, keepdims=True)
134
+ pct = np.where(row_tot > 0, matrix / row_tot * 100, 0)
135
+
136
+ im = ax.imshow(pct, cmap='Blues', vmin=0, vmax=100)
137
+ plt.colorbar(im, ax=ax, label="% de la classe réelle", shrink=0.8)
138
+
139
+ ax.set_xticks(range(7)); ax.set_yticks(range(7))
140
+ ax.set_xticklabels([f"C{i+1}\n{short[i]}" for i in range(7)], fontsize=8)
141
+ ax.set_yticklabels([f"C{i+1}\n{short[i]}" for i in range(7)], fontsize=8)
142
+ ax.set_xlabel("Classe prédite (KNN)", fontsize=11, labelpad=8)
143
+ ax.set_ylabel("Classe réelle (vérité terrain)", fontsize=11, labelpad=8)
144
+ ax.set_title(f"Matrice de confusion – KNN vs Vérité terrain\n"
145
+ f"Précision globale = {oa*100:.1f}%",
146
+ fontsize=12, fontweight='bold', pad=12)
147
+
148
+ for r in range(7):
149
+ for c in range(7):
150
+ v, p = matrix[r, c], pct[r, c]
151
+ color = 'white' if p > 50 else 'black'
152
+ ax.text(c, r, f"{v}\n({p:.0f}%)", ha='center', va='center',
153
+ fontsize=7, color=color)
154
+
155
+ plt.tight_layout()
156
+ return fig
157
+
158
+ def fig_student_matrix(student_labels):
159
+ """7×7 confusion matrix: student labels vs teacher labels."""
160
+ matrix = np.zeros((7, 7), dtype=int)
161
+ for pid in range(1, 24):
162
+ s = student_labels[pid - 1]
163
+ t = DATA['polygon_teacher'].get(pid, 0)
164
+ if s is not None and t > 0:
165
+ matrix[t - 1][int(s) - 1] += 1
166
+
167
+ short = ["Eau", "Vergers", "Δ-Cult.", "Bâti", "Irr.-Dés.", "Non-Irr.", "Sable"]
168
+ fig, ax = plt.subplots(figsize=(8, 6))
169
+
170
+ row_tot = matrix.sum(axis=1, keepdims=True)
171
+ pct = np.where(row_tot > 0, matrix / row_tot * 100, 0)
172
+ im = ax.imshow(pct, cmap='Greens', vmin=0, vmax=100)
173
+ plt.colorbar(im, ax=ax, label="% de la classe enseignant", shrink=0.8)
174
+
175
+ ax.set_xticks(range(7)); ax.set_yticks(range(7))
176
+ ax.set_xticklabels([f"C{i+1}\n{short[i]}" for i in range(7)], fontsize=8)
177
+ ax.set_yticklabels([f"C{i+1}\n{short[i]}" for i in range(7)], fontsize=8)
178
+ ax.set_xlabel("Votre réponse", fontsize=11, labelpad=8)
179
+ ax.set_ylabel("Réponse de l'enseignant", fontsize=11, labelpad=8)
180
+ ax.set_title("Votre interprétation vs Réponse de l'enseignant\n(polygones d'entraînement)",
181
+ fontsize=11, fontweight='bold', pad=12)
182
+
183
+ for r in range(7):
184
+ for c in range(7):
185
+ v, p = matrix[r, c], pct[r, c]
186
+ color = 'white' if p > 50 else 'black'
187
+ if v > 0:
188
+ ax.text(c, r, f"{v}\n({p:.0f}%)", ha='center', va='center',
189
+ fontsize=8, color=color)
190
+
191
+ plt.tight_layout()
192
+ return fig
193
+
194
+ # ─────────────────────────────────────────────────────────────────────────────
195
+ # Gradio helpers
196
+ # ─────────────────────────────────────────────────────────────────────────────
197
+ def polygon_image_path(idx):
198
+ return os.path.join(BASE_DIR, 'polygon_images', f'polygon_{idx+1:02d}.png')
199
+
200
+ def count_labeled(labels):
201
+ return sum(1 for l in labels if l is not None)
202
+
203
+ def build_results_table(student_labels):
204
+ rows = []
205
+ for pid in range(1, 24):
206
+ s = student_labels[pid - 1]
207
+ t = DATA['polygon_teacher'].get(pid, 0)
208
+ s_str = f"{s} – {CLASSES.get(int(s), '?')}" if s is not None else "—"
209
+ t_str = f"{t} – {CLASSES.get(t, '?')}"
210
+ match = "✅" if (s is not None and int(s) == t) else ("❌" if s is not None else "—")
211
+ rows.append([pid, s_str, t_str, match])
212
+ return rows
213
+
214
+ # ─────────────────────────────────────────────────────────────────────────────
215
+ # Gradio Interface
216
+ # ─────────────────────────────────────────────────────────────────────────────
217
+ with gr.Blocks(title="Interprétation de polygones – Vallée du Nil") as demo:
218
+
219
+ # ── State ──────────────────────────────────────────────────────────────
220
+ cur_idx = gr.State(value=0)
221
+ labels = gr.State(value=[None] * N_POLYGONS)
222
+
223
+ # ── Header ─────────────────────────────────────────────────────────────
224
+ gr.Markdown("""
225
+ # 🛰️ Interprétation de polygones d'entraînement – Vallée du Nil
226
+
227
+ **Objectif :** Interprétez visuellement chacun des 23 polygones d'entraînement,
228
+ puis soumettez vos réponses pour générer la carte et la matrice de confusion.
229
+
230
+ > Cette application s'inscrit dans un TD sur la classification d'occupation du sol par IA (algorithme KNN).
231
+ """)
232
+
233
+ with gr.Tabs() as tabs:
234
+
235
+ # ── Tab 1: Légende des classes ────────────────────────────────────
236
+ with gr.Tab("📋 Classes d'occupation du sol"):
237
+ gr.Markdown("""
238
+ ## Classes d'occupation du sol
239
+
240
+ | N° | Classe | Couleur |
241
+ |----|--------|---------|
242
+ | 1 | Eau | 🔵 Bleu |
243
+ | 2 | Vergers | 🟢 Vert foncé |
244
+ | 3 | Cultures dans le Delta | 💚 Vert clair |
245
+ | 4 | Zones bâties | 🔴 Rouge |
246
+ | 5 | Cultures irriguées dans le désert | 🟠 Orange |
247
+ | 6 | Cultures non irriguées en zone sèche | 🟤 Marron |
248
+ | 7 | Zones sableuses | 🟡 Jaune clair |
249
+
250
+ ---
251
+ **Conseils d'interprétation :**
252
+ - L'image montre une composition colorée de l'image Landsat
253
+ - Les zones bleues/sombres correspondent à l'eau
254
+ - La végétation dense apparaît en vert (vergers, cultures dans le delta)
255
+ - Les zones bâties apparaissent en teintes rosées ou grises
256
+ - Les zones cultivées irriguées dans le désert forment des parcelles géométriques
257
+ - Les zones sableuses apparaissent en jaune/beige
258
+ """)
259
+
260
+ # ── Tab 2: Interprétation ─────────────────────────────────────────
261
+ with gr.Tab("🖊️ Interprétation des polygones"):
262
+ progress_md = gr.Markdown("**0 / 23 polygones étiquetés**")
263
+
264
+ with gr.Row():
265
+ with gr.Column(scale=3):
266
+ polygon_title = gr.Markdown("### Polygone 1 / 23")
267
+ polygon_img = gr.Image(
268
+ value=polygon_image_path(0),
269
+ label="Image satellite",
270
+ show_label=False,
271
+ height=500,
272
+ )
273
+ with gr.Row():
274
+ btn_prev = gr.Button("◀ Précédent", size="sm", variant="secondary")
275
+ btn_next = gr.Button("Suivant ▶", size="sm", variant="primary")
276
+
277
+ with gr.Column(scale=1):
278
+ gr.Markdown("### Classe du polygone")
279
+ gr.Markdown("*(Cochez la classe qui correspond le mieux à l'occupation du sol visible dans le polygone)*")
280
+ class_radio = gr.Radio(
281
+ choices=CLASS_CHOICES,
282
+ label="Classe",
283
+ value=None,
284
+ )
285
+ gr.Markdown("---")
286
+ progress_bar = gr.Markdown("**Progression : 0 / 23**")
287
+ btn_submit = gr.Button(
288
+ "🚀 Soumettre toutes mes réponses",
289
+ variant="primary",
290
+ visible=False,
291
+ size="lg",
292
+ )
293
+
294
+ # ── Tab 3: Résultats ───────────────────────────────────────────────
295
+ with gr.Tab("📊 Résultats", id="tab_results") as tab_results:
296
+ results_placeholder = gr.Markdown(
297
+ "*(Les résultats apparaîtront ici après soumission)*"
298
+ )
299
+ accuracy_md = gr.Markdown(visible=False)
300
+ results_tbl = gr.Dataframe(
301
+ headers=["Polygone", "Votre réponse", "Réponse enseignant", "Résultat"],
302
+ visible=False,
303
+ wrap=True,
304
+ )
305
+ with gr.Row(visible=False) as row_plots_student:
306
+ student_matrix_plot = gr.Plot(label="Votre interprétation vs Enseignant")
307
+
308
+ maps_plot = gr.Plot(label="Cartes", visible=False)
309
+ knn_plot = gr.Plot(label="Matrice de confusion KNN vs Vérité terrain", visible=False)
310
+
311
+ # ─────────────────────────────────────────────────────────────────────
312
+ # Event handlers
313
+ # ─────────────────────────────────────────────────────────────────────
314
+
315
+ def nav_to(idx, current_labels):
316
+ """Render a polygon slide: image, title, current radio value."""
317
+ img = polygon_image_path(idx)
318
+ title = f"### Polygone {idx + 1} / {N_POLYGONS}"
319
+ saved = current_labels[idx]
320
+ radio_val = None
321
+ if saved is not None:
322
+ radio_val = CLASS_CHOICES[int(saved) - 1]
323
+ n_done = count_labeled(current_labels)
324
+ prog = f"**Progression : {n_done} / {N_POLYGONS}**"
325
+ return img, title, radio_val, prog
326
+
327
+ def on_prev(idx, current_labels):
328
+ new_idx = max(0, idx - 1)
329
+ img, title, radio_val, prog = nav_to(new_idx, current_labels)
330
+ return new_idx, img, title, radio_val, prog
331
+
332
+ def on_next(idx, current_labels):
333
+ new_idx = min(N_POLYGONS - 1, idx + 1)
334
+ img, title, radio_val, prog = nav_to(new_idx, current_labels)
335
+ return new_idx, img, title, radio_val, prog
336
+
337
+ def on_class_select(choice, idx, current_labels):
338
+ """Save selected class for current polygon."""
339
+ if choice is None:
340
+ return current_labels, gr.update(), gr.update(), gr.update()
341
+ cls_num = int(choice.split(" - ")[0])
342
+ new_labels = list(current_labels)
343
+ new_labels[idx] = cls_num
344
+ n_done = count_labeled(new_labels)
345
+ prog = f"**Progression : {n_done} / {N_POLYGONS}**"
346
+ overall= f"**{n_done} / {N_POLYGONS} polygones étiquetés**"
347
+ show_submit = (n_done == N_POLYGONS)
348
+ return (new_labels,
349
+ gr.update(value=prog),
350
+ gr.update(value=overall),
351
+ gr.update(visible=show_submit))
352
+
353
+ def on_submit(current_labels):
354
+ """Compute and display all results."""
355
+ # Accuracy vs teacher
356
+ correct = sum(
357
+ 1 for pid in range(1, 24)
358
+ if current_labels[pid-1] is not None
359
+ and int(current_labels[pid-1]) == DATA['polygon_teacher'].get(pid, 0)
360
+ )
361
+ total = count_labeled(current_labels)
362
+ pct = correct / total * 100 if total > 0 else 0
363
+
364
+ acc_text = (
365
+ f"## 🎯 Résultat de votre interprétation\n\n"
366
+ f"**{correct} / {total} polygones correctement identifiés ({pct:.0f}%)**\n\n"
367
+ f"*(Comparaison avec la légende fournie par l'enseignant)*"
368
+ )
369
+
370
+ table = build_results_table(current_labels)
371
+
372
+ maps_fig = fig_maps(current_labels)
373
+ knn_fig = fig_knn_matrix()
374
+ student_fig = fig_student_matrix(current_labels)
375
+
376
+ return (
377
+ gr.update(value=""), # hide placeholder
378
+ gr.update(value=acc_text, visible=True),
379
+ gr.update(value=table, visible=True),
380
+ gr.update(visible=True),
381
+ gr.update(value=student_fig),
382
+ gr.update(value=maps_fig, visible=True),
383
+ gr.update(value=knn_fig, visible=True),
384
+ )
385
+
386
+ # Wire up navigation
387
+ btn_prev.click(
388
+ on_prev,
389
+ inputs=[cur_idx, labels],
390
+ outputs=[cur_idx, polygon_img, polygon_title, class_radio, progress_bar],
391
+ )
392
+ btn_next.click(
393
+ on_next,
394
+ inputs=[cur_idx, labels],
395
+ outputs=[cur_idx, polygon_img, polygon_title, class_radio, progress_bar],
396
+ )
397
+
398
+ # Wire up class selection
399
+ class_radio.change(
400
+ on_class_select,
401
+ inputs=[class_radio, cur_idx, labels],
402
+ outputs=[labels, progress_bar, progress_md, btn_submit],
403
+ )
404
+
405
+ # Wire up submit
406
+ btn_submit.click(
407
+ on_submit,
408
+ inputs=[labels],
409
+ outputs=[
410
+ results_placeholder,
411
+ accuracy_md,
412
+ results_tbl,
413
+ row_plots_student,
414
+ student_matrix_plot,
415
+ maps_plot,
416
+ knn_plot,
417
+ ],
418
+ )
419
+
420
+ if __name__ == "__main__":
421
+ demo.launch(server_name="0.0.0.0", server_port=7860)
data/ground_truth.tif ADDED

Git LFS Details

  • SHA256: 7711ea9094330662fc6334971f306b4658e73f2383346cbd4788b188038772b7
  • Pointer size: 132 Bytes
  • Size of remote file: 4.61 MB
data/knn_result.tif ADDED

Git LFS Details

  • SHA256: 7a0ac65d0d7e0c59df890e8c0ce145b595a2fe51fb892d6d6714f622a5dd717b
  • Pointer size: 132 Bytes
  • Size of remote file: 4.61 MB
data/polygon_teacher_classes.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "1": 1,
3
+ "2": 2,
4
+ "3": 2,
5
+ "4": 1,
6
+ "5": 1,
7
+ "6": 3,
8
+ "7": 3,
9
+ "8": 3,
10
+ "9": 3,
11
+ "10": 3,
12
+ "11": 3,
13
+ "12": 3,
14
+ "13": 1,
15
+ "14": 4,
16
+ "15": 1,
17
+ "16": 5,
18
+ "17": 6,
19
+ "18": 7,
20
+ "19": 7,
21
+ "20": 7,
22
+ "21": 7,
23
+ "22": 1,
24
+ "23": 1
25
+ }
data/teacher_labels.tif ADDED

Git LFS Details

  • SHA256: cea77dca3e9c2e3b18013e0f4e7e82dc876f9d4b7d8d1dfa93e8b75e263c6170
  • Pointer size: 132 Bytes
  • Size of remote file: 4.61 MB
data/training_polygons.tif ADDED

Git LFS Details

  • SHA256: 34ff1912eaed28feadd26cafda726befd61e3cf524681a3b7f314e205cf81cdc
  • Pointer size: 132 Bytes
  • Size of remote file: 4.61 MB
polygon_images/polygon_01.png ADDED

Git LFS Details

  • SHA256: 483418091f8cdb2d5ff3d532ad28449480098f8cf696f72c274263c18b6cc343
  • Pointer size: 131 Bytes
  • Size of remote file: 145 kB
polygon_images/polygon_02.png ADDED

Git LFS Details

  • SHA256: 4245f8a75d49dcb8b6c7bffe63ac4f5693cb87f571bfe23a5021f710f66a54ca
  • Pointer size: 131 Bytes
  • Size of remote file: 417 kB
polygon_images/polygon_03.png ADDED

Git LFS Details

  • SHA256: e09a8f6bef91b9a8074d9468615007742894cb5744b446cdd8385abde9346ebc
  • Pointer size: 131 Bytes
  • Size of remote file: 278 kB
polygon_images/polygon_04.png ADDED
polygon_images/polygon_05.png ADDED

Git LFS Details

  • SHA256: 68053c03f162d882cabfe1c67ef1c7273466505323df07648a15f95e57080082
  • Pointer size: 131 Bytes
  • Size of remote file: 156 kB
polygon_images/polygon_06.png ADDED

Git LFS Details

  • SHA256: 4829f70e9fa023fcf5d8542aa83899aa71bec15003c935c320fbebbe1e9aae60
  • Pointer size: 132 Bytes
  • Size of remote file: 1.16 MB
polygon_images/polygon_07.png ADDED

Git LFS Details

  • SHA256: 921323bf337eb6a36eac7d1103ab9ff0db1537ad275817e69da9c0ee48bcf983
  • Pointer size: 131 Bytes
  • Size of remote file: 753 kB
polygon_images/polygon_08.png ADDED

Git LFS Details

  • SHA256: 5a1a5a24161d0ae8422c2e3896afd351c458512332148020e7cc4f5a07b40e17
  • Pointer size: 131 Bytes
  • Size of remote file: 758 kB
polygon_images/polygon_09.png ADDED

Git LFS Details

  • SHA256: eb85d1505343a99623439aa13c247eb374690587f963ee3e2b39983151ce9874
  • Pointer size: 131 Bytes
  • Size of remote file: 730 kB
polygon_images/polygon_10.png ADDED

Git LFS Details

  • SHA256: 7b5cb74cdcfbf0ab5e53ac4dff4c5c1a9031820521a9abd5db6888ddf93d88f0
  • Pointer size: 131 Bytes
  • Size of remote file: 730 kB
polygon_images/polygon_11.png ADDED

Git LFS Details

  • SHA256: b950ea6d99e53a07d4fe7703772a05049aa1642a045b5f7e2347613d4874fa4e
  • Pointer size: 131 Bytes
  • Size of remote file: 142 kB
polygon_images/polygon_12.png ADDED

Git LFS Details

  • SHA256: c4b9a61bb25f816a5372ec336b1dbc87ebff0ec7f0c27567daa3edd3c9686bda
  • Pointer size: 131 Bytes
  • Size of remote file: 235 kB
polygon_images/polygon_13.png ADDED

Git LFS Details

  • SHA256: 3a9889b5b2c87c055f9d53c9172fa4bd31d3217368ed1c07d467996cc514e71e
  • Pointer size: 131 Bytes
  • Size of remote file: 190 kB
polygon_images/polygon_14.png ADDED

Git LFS Details

  • SHA256: fdd82efed68bf0c6c09257dd5749b514e83b0af99d39053fe7b4e09f1fa6c07d
  • Pointer size: 131 Bytes
  • Size of remote file: 345 kB
polygon_images/polygon_15.png ADDED

Git LFS Details

  • SHA256: 4749c672da1ea122af388f1f4194b759c3216f6fa3a8124b6ca690223898d112
  • Pointer size: 131 Bytes
  • Size of remote file: 198 kB
polygon_images/polygon_16.png ADDED

Git LFS Details

  • SHA256: 4f8e73ace8c640e1e051825ab167e879e6729e9bddbb904ba2e4b3faa739f28f
  • Pointer size: 131 Bytes
  • Size of remote file: 434 kB
polygon_images/polygon_17.png ADDED

Git LFS Details

  • SHA256: 1d40ec72a85decd800b9b83372dbdf0f6b8b4580b1bd13b3bab85a6446a19385
  • Pointer size: 131 Bytes
  • Size of remote file: 378 kB
polygon_images/polygon_18.png ADDED

Git LFS Details

  • SHA256: 3503d688bde21f53c93ff49efba06f66ebedbd155f1624377ca545ec751a0cf0
  • Pointer size: 131 Bytes
  • Size of remote file: 376 kB
polygon_images/polygon_19.png ADDED

Git LFS Details

  • SHA256: cd8dc6e5e4f42cdf4aa6420f013e8705f68d2b278d989736548ad8f621b0e3af
  • Pointer size: 131 Bytes
  • Size of remote file: 418 kB
polygon_images/polygon_20.png ADDED

Git LFS Details

  • SHA256: 25a6a6ec1959392e28f7877ca6539d58fdb40d108a8d30eb321048fa8953d8cb
  • Pointer size: 131 Bytes
  • Size of remote file: 416 kB
polygon_images/polygon_21.png ADDED

Git LFS Details

  • SHA256: 80bcc53d18917ec9a3e5e4a7798e26993059ba5376deacb5781029772f1250d8
  • Pointer size: 131 Bytes
  • Size of remote file: 387 kB
polygon_images/polygon_22.png ADDED
polygon_images/polygon_23.png ADDED

Git LFS Details

  • SHA256: 484f9976948023554c4ff4c152d5e4de5461dfb5e09c99198d5532ebaa51d370
  • Pointer size: 131 Bytes
  • Size of remote file: 118 kB
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ gradio>=4.0.0
2
+ numpy>=1.24.0
3
+ rasterio>=1.3.0
4
+ matplotlib>=3.7.0
5
+ Pillow>=9.0.0
6
+ scipy>=1.10.0
7
+ scikit-learn>=1.3.0