Skip to content

Commit cd02787

Browse files
committed
feat: refactored vegetationmask for complexity
1 parent 41c03ab commit cd02787

1 file changed

Lines changed: 106 additions & 86 deletions

File tree

slurp/masks/vegetationmask.py

Lines changed: 106 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -241,73 +241,8 @@ def apply_clustering(
241241
if params["debug"]:
242242
logger.debug(f"K-Means on radiometric indices ({nb_polys} elements")
243243

244-
kmeans_rad_indices = KMeans(
245-
n_clusters=NB_CLUSTERS,
246-
init="k-means++",
247-
n_init=5,
248-
verbose=0,
249-
random_state=712,
250-
)
251-
pred_veg = kmeans_rad_indices.fit_predict(
252-
np.stack((stats[0:nb_polys], stats[nb_polys : 2 * nb_polys]), axis=1)
253-
)
254-
if params["debug"]:
255-
logger.debug(f"{np.sort(kmeans_rad_indices.cluster_centers_,axis=0)=}")
256-
257-
list_clusters = pd.DataFrame.from_records(
258-
kmeans_rad_indices.cluster_centers_, columns=["ndvi", "ndwi"]
259-
)
260-
list_clusters_by_ndvi = list_clusters.sort_values(
261-
by="ndvi", ascending=True
262-
).index
263-
264-
map_centroid = []
265-
266-
nb_clusters_no_veg = 0
267-
nb_clusters_veg = 0
268-
if params["min_ndvi_veg"]:
269-
# Attribute veg class by threshold
270-
for t in range(kmeans_rad_indices.n_clusters):
271-
if list_clusters.iloc[t]["ndvi"] > float(params["min_ndvi_veg"]):
272-
map_centroid.append(VEG_CODE)
273-
nb_clusters_veg += 1
274-
elif list_clusters.iloc[t]["ndvi"] < float(
275-
params["max_ndvi_noveg"]
276-
):
277-
if params["non_veg_clusters"]:
278-
l_ndvi = list(list_clusters_by_ndvi)
279-
v = l_ndvi.index(t)
280-
map_centroid.append(v)
281-
else:
282-
map_centroid.append(NO_VEG_CODE) # 0
283-
nb_clusters_no_veg += 1
284-
else:
285-
map_centroid.append(UNDEFINED_VEG)
286-
287-
else:
288-
# Attribute class by thirds
289-
nb_clusters_no_veg = int(kmeans_rad_indices.n_clusters / 3)
290-
if params["nb_clusters_veg"] >= 7:
291-
nb_clusters_no_veg = NB_CLUSTERS - params["nb_clusters_veg"]
292-
nb_clusters_veg = params["nb_clusters_veg"]
293-
294-
for t in range(kmeans_rad_indices.n_clusters):
295-
if t in list_clusters_by_ndvi[:nb_clusters_no_veg]:
296-
if params["non_veg_clusters"]:
297-
l_ndvi = list(list_clusters_by_ndvi)
298-
v = l_ndvi.index(t)
299-
map_centroid.append(v)
300-
else:
301-
map_centroid.append(NO_VEG_CODE) # 0
302-
elif (
303-
t
304-
in list_clusters_by_ndvi[
305-
nb_clusters_no_veg : NB_CLUSTERS - params["nb_clusters_veg"]
306-
]
307-
):
308-
map_centroid.append(UNDEFINED_VEG) # 10
309-
else:
310-
map_centroid.append(VEG_CODE) # 20
244+
kmeans_rad_indices, list_clusters, pred_veg = cluster_on_radiometry(nb_polys, params, stats)
245+
map_centroid, nb_clusters_no_veg, nb_clusters_veg = classify_veg_indices(kmeans_rad_indices, list_clusters, params)
311246

312247
clustering = apply_map(pred_veg, map_centroid)
313248

@@ -335,25 +270,7 @@ def apply_clustering(
335270
logger.debug("threshold_texture_max", threshold_max)
336271

337272
# Save histograms
338-
if params["texture_mode"] == "debug" or params["save_mode"] == "debug":
339-
values, bins, _ = plt.hist(texture_values, bins=75)
340-
plt.clf()
341-
bins_center = (bins[:-1] + bins[1:]) / 2
342-
plt.plot(bins_center, values, color="blue")
343-
plt.savefig(
344-
path.splitext(params["vegetationmask"])[0]
345-
+ "_histogram_texture.png"
346-
)
347-
plt.close()
348-
index_max = np.argmax(bins_center > threshold_max) + 1
349-
plt.plot(bins_center[:index_max], values[:index_max], color="blue")
350-
plt.savefig(
351-
path.splitext(params["vegetationmask"])[0]
352-
+ "_histogram_texture_cut"
353-
+ str(params["filter_texture"])
354-
+ ".png"
355-
)
356-
plt.close()
273+
save_histograms(params, texture_values, threshold_max)
357274

358275
# Clustering
359276
data_textures = np.transpose(texture_values)
@@ -455,6 +372,109 @@ def apply_clustering(
455372
return clustering
456373

457374

375+
def save_histograms(params, texture_values, threshold_max):
376+
'''
377+
Save histograms of texture values if in debug mode
378+
'''
379+
if params["texture_mode"] == "debug" or params["save_mode"] == "debug":
380+
values, bins, _ = plt.hist(texture_values, bins=75)
381+
plt.clf()
382+
bins_center = (bins[:-1] + bins[1:]) / 2
383+
plt.plot(bins_center, values, color="blue")
384+
plt.savefig(
385+
path.splitext(params["vegetationmask"])[0]
386+
+ "_histogram_texture.png"
387+
)
388+
plt.close()
389+
index_max = np.argmax(bins_center > threshold_max) + 1
390+
plt.plot(bins_center[:index_max], values[:index_max], color="blue")
391+
plt.savefig(
392+
path.splitext(params["vegetationmask"])[0]
393+
+ "_histogram_texture_cut"
394+
+ str(params["filter_texture"])
395+
+ ".png"
396+
)
397+
plt.close()
398+
399+
400+
def classify_veg_indices(kmeans_rad_indices, list_clusters, params):
401+
'''
402+
Assign vegetation class codes to each cluster based on NDVI thresholds or proportions.
403+
'''
404+
list_clusters_by_ndvi = list_clusters.sort_values(
405+
by="ndvi", ascending=True
406+
).index
407+
map_centroid = []
408+
nb_clusters_no_veg = 0
409+
nb_clusters_veg = 0
410+
if params["min_ndvi_veg"]:
411+
# Attribute veg class by threshold
412+
for t in range(kmeans_rad_indices.n_clusters):
413+
if list_clusters.iloc[t]["ndvi"] > float(params["min_ndvi_veg"]):
414+
map_centroid.append(VEG_CODE)
415+
nb_clusters_veg += 1
416+
elif list_clusters.iloc[t]["ndvi"] < float(
417+
params["max_ndvi_noveg"]
418+
):
419+
if params["non_veg_clusters"]:
420+
l_ndvi = list(list_clusters_by_ndvi)
421+
v = l_ndvi.index(t)
422+
map_centroid.append(v)
423+
else:
424+
map_centroid.append(NO_VEG_CODE) # 0
425+
nb_clusters_no_veg += 1
426+
else:
427+
map_centroid.append(UNDEFINED_VEG)
428+
429+
else:
430+
# Attribute class by thirds
431+
nb_clusters_no_veg = int(kmeans_rad_indices.n_clusters / 3)
432+
if params["nb_clusters_veg"] >= 7:
433+
nb_clusters_no_veg = NB_CLUSTERS - params["nb_clusters_veg"]
434+
nb_clusters_veg = params["nb_clusters_veg"]
435+
436+
for t in range(kmeans_rad_indices.n_clusters):
437+
if t in list_clusters_by_ndvi[:nb_clusters_no_veg]:
438+
if params["non_veg_clusters"]:
439+
l_ndvi = list(list_clusters_by_ndvi)
440+
v = l_ndvi.index(t)
441+
map_centroid.append(v)
442+
else:
443+
map_centroid.append(NO_VEG_CODE) # 0
444+
elif (
445+
t
446+
in list_clusters_by_ndvi[
447+
nb_clusters_no_veg: NB_CLUSTERS - params["nb_clusters_veg"]
448+
]
449+
):
450+
map_centroid.append(UNDEFINED_VEG) # 10
451+
else:
452+
map_centroid.append(VEG_CODE) # 20
453+
return map_centroid, nb_clusters_no_veg, nb_clusters_veg
454+
455+
456+
def cluster_on_radiometry(nb_polys, params, stats):
457+
'''
458+
K-means clustering on NDVI and NDWI indices
459+
'''
460+
kmeans_rad_indices = KMeans(
461+
n_clusters=NB_CLUSTERS,
462+
init="k-means++",
463+
n_init=5,
464+
verbose=0,
465+
random_state=712,
466+
)
467+
pred_veg = kmeans_rad_indices.fit_predict(
468+
np.stack((stats[0:nb_polys], stats[nb_polys: 2 * nb_polys]), axis=1)
469+
)
470+
if params["debug"]:
471+
logger.debug(f"{np.sort(kmeans_rad_indices.cluster_centers_,axis=0)=}")
472+
list_clusters = pd.DataFrame.from_records(
473+
kmeans_rad_indices.cluster_centers_, columns=["ndvi", "ndwi"]
474+
)
475+
return kmeans_rad_indices, list_clusters, pred_veg
476+
477+
458478
# Finalize #
459479

460480

0 commit comments

Comments
 (0)