-
Notifications
You must be signed in to change notification settings - Fork 0
/
udf_sobel_felzenszwalb.py
50 lines (40 loc) · 1.61 KB
/
udf_sobel_felzenszwalb.py
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
import numpy as np
import xarray
from openeo.udf import XarrayDataCube
from skimage import segmentation
from skimage.filters import sobel
from skimage import graph
def apply_datacube(cube: XarrayDataCube, context: dict) -> XarrayDataCube:
# get the underlying numpy array
inarray = cube.get_array().squeeze("t", drop=True).squeeze("bands", drop=True)
inimage = inarray.values
# compute edges
edges = sobel(inimage)
# Perform felzenszwalb segmentation
segment = np.array(
segmentation.felzenszwalb(inimage, scale=120, sigma=0.0, min_size=30, channel_axis=None)
).astype(np.int32)
# Perform the rag boundary analysis and merge the segments
bgraph = graph.rag_boundary(segment, edges)
# merging segments
mergedsegment = graph.cut_threshold(segment, bgraph, 0.15, in_place=False)
# create random numbers for the segments
unique_classes = np.unique(mergedsegment)
random_numbers = np.random.randint(0, 1000000, size=len(np.unique(mergedsegment)))
counter = 0
for unique_class in unique_classes:
if unique_class == 0:
continue
mergedsegment[mergedsegment == unique_class] = random_numbers[counter]
counter += 1
mergedsegment = mergedsegment.astype(float)
mergedsegment[inimage < 0.3] = np.nan
mergedsegment[mergedsegment < 0] = 0
outarr = xarray.DataArray(
mergedsegment.reshape(cube.get_array().shape),
dims=cube.get_array().dims,
coords=cube.get_array().coords,
)
outarr = outarr.astype(np.float64)
outarr = outarr.where(outarr != 0, np.nan)
return XarrayDataCube(outarr)