2

I am trying to generate segments with single trees in a normalized surface model (nDSM). I tried using scipy.ndimage to achieve this, but the segmentation results are not precise. I would like a better segmentation. How could I achive this?

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
import rasterio

from scipy import ndimage as ndi
from skimage.segmentation import watershed
from skimage.feature import peak_local_max
from skimage import filters

src = rasterio.open('nDSM.tif')
img = src.read(1)

img = np.where(img > 5, img, 0)
img = ndi.gaussian_filter(img, sigma=0.5)
distance = ndi.distance_transform_edt(img)
coords = peak_local_max(distance, footprint=np.ones((2, 2)), labels=img)

mask = np.zeros(distance.shape, dtype=bool)
mask[tuple(coords.T)] = True

markers, _ = ndi.label(mask)
labels = watershed(img, markers, mask=mask)

enter image description here

1
  • I would recommend the lidR package in R for this.
    – Aaron
    Commented Dec 4, 2021 at 6:00

1 Answer 1

1

So after some research I came to the conclusion that the detection of the tree peaks (maxima) was not sufficient and therefore the segmentation did not work correctly.

Here is my updated Code:

import numpy as np
from matplotlib import pyplot as plt
import rasterio

from scipy import ndimage as ndi
from scipy.ndimage import binary_erosion, generate_binary_structure
from skimage.segmentation import watershed


def detect_peaks(image):

    neighborhood = generate_binary_structure(2,2)
    local_max = ndi.maximum_filter(image, footprint=neighborhood)==image
    background = (image==0)
    eroded_background = binary_erosion(background, structure=neighborhood, border_value=1)
    detected_peaks = local_max ^ eroded_background

    return detected_peaks

src = rasterio.open('nDSM.tif')
img = src.read(1)
img = ndi.gaussian_filter(img, sigma=0.5)


distance = img
mask  = detect_peaks(distance)

markers, _ = ndi.label(mask)
labels = watershed(-distance, markers, mask=img)

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.