Ga naar inhoud

Niet-gesuperviseerde classificatie

Niet-gesuperviseerde classificatie is de procedure waarbij pixels in spectraal gelijkende klassen worden ingedeeld door het algoritme, zonder dat hierbij een trainingsdataset aan de pas komt. Het is vervolgens aan de gebruiker om de resulterende klassen te interpreteren en te labelen, of om de output te gebruiken bij het opstellen van een samplingprotocol.

Er bestaan verschillende niet-gesuperviseerde algoritmen, maar de meest gekende groep is deze van de clustering. In een clusteranalyse worden pixels met gelijkende spectrale kenmerken tot dezelfde klasse gerekend.

K-Means Clustering

Een van de meest gebruikte clustering-algoritmen is K-means clustering. Hierbij geeft de gebruiker vooraf het aantal clusters op, waarna het algoritme deze clusters willekeurig in de multidimensionale ruimte initialiseert. Elke pixel wordt in de eerste stap toegewezen aan de cluster waarvan het centrum het dichtst bij de pixel ligt. Na deze eerste toewijzing worden de clustercentra opnieuw berekend, waarbij het algoritme de interne variantie binnen elke cluster minimaliseert. Vervolgens worden de pixels opnieuw aan de meest geschikte cluster toegewezen. Deze procedure herhaalt zich iteratief totdat de clustercentra nauwelijks nog verschuiven en de variantie binnen elke cluster niet langer significant afneemt.


Principe van de K-means clustering in een 2-dimensionaal vlak. (Bron: dashee87.github.io)

Classificatie van de Surinaamse kustzone

We starten met het aanmaken van een Sentinel-2 beeld;

  • Maak een nieuw script aan: P3_UnsupervisedClass.

  • Maak een wolkenvrij beeld aan, waarmee je een classificatie kunt uitvoeren. Focus in dit voorbeeld op de kustlijn van Suriname, ter hoogte van de hoofdstad: Paramaribo. We focussen hierbij op maanden binnen de grote droge tijd (Augustus - November), aangezien de wolkbedekking dan beperkter zou moeten zijn in vergelijking met de natte tijden.

Maak hiervoor eerst een polygoon aan met de locatie van Paramaribo. Eventueel kun je hiervoor onderstaande code gebruiken:

var Paramaribo = 
    /* color: #d63000 */
    /* shown: false */
    /* displayProperties: [
      {
        "type": "rectangle"
      }
    ] */
    ee.Geometry.Polygon(
        [[[-55.31615692285674, 6.000339363352038],
          [-55.31615692285674, 5.8043169248564865],
          [-54.91446930078643, 5.8043169248564865],
          [-54.91446930078643, 6.000339363352038]]], null, false);

Start daarna met het aanmaken van het S2-beeld. Maak een wolkenvrij beeld aan voor de periode Augustus t.e.m. Oktober 2025.

// --------------------------------------------------------------------  
// STAP 1 - Inladen en klaarzetten van S2-beeld. Mét csPlus wolkbedekking
// -------------------------------------------------------------------

// Aanmaken van treshold + maskfunctie + Herschalingsfunctie
var CLEAR_THRESHOLD = 0.6
var applyCloudMask = function(img){
    return img.updateMask(img.select('cs').gte(CLEAR_THRESHOLD))
                .multiply(0.0001) // 
                .copyProperties(img, ["system:time_start"]);
}

//Aanmaken van een Sentinel-2 ImageCollection ter hoogte van de kustlijn met mangroves en de hoofdstad Paramaribo, Suriname
var S2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED');
var csPlus = ee.ImageCollection('GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED');

var S2_coll = S2
        .linkCollection(csPlus, ['cs'])
        .filterDate('2025-08-01','2025-10-30')// Filteren voor het jaar 2025, droge tijd
        .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',50)) //Voorselectie obv wolken
        .map(applyCloudMask) //toepassen van de cloudmaskfunctie
        .filterBounds(Paramaribo); //collectie filteren obv de Kustzonegeometrie

//Omzetten collectie naar een Image, door de .median()-reducer toe te passen. Hierna clippen obv de ROI (Paramaribo)
var S2_im = S2_coll.median()
                     .clip(Paramaribo) //Bekijk de .clip-eigenschappen in de Docs

Vervolgens maak je een visualisatie van de Healthy Vegetation Composite (RGB = NIR, SWIR1, Blue).

Healthy Vegetation Composite
// Visualisatieparameters Healthy Vegetation Composite
// (Hierbij paste ik per band individuele min - max waarden toe om het contrast van mangrove nog te vergroten)
var HVC_vis = {bands : ['B8','B11','B2'], min: [0.1,0.06,0.03], max: [0.3,0.2,0.1]}


// Visualiseren
Map.addLayer(S2_im, HVC_vis, 'Healthy Vegetation Composite')
De .clip() functie

De .clip()-functie wordt toegepast om het resulterende beeld bij te snijden naar de exacte grenzen van de aangemaakte polygoon (ROI). .clip() is enkel toepasbaar op beelden van het image-type, maar kan niet worden toegepast op een ``ÌmageCollection, gezien dit een te grote rekencapaciteit zou vergen. Daarom wordt de functie.FilterBounds()```gebruikt, waarbij enkel gefilterd wordt op basis van een spatiaal feature (punt, lijn of polygoon) maar geen beelden worden bijgesneden.

Toepassen van de Clustering

In Earth Engine zit de clustering vervat in ee.Clusterer bibliotheek. We maken in volgend voorbeeld gebruik van de "Weka K-means cluster".

  • Standaard worden alle banden van een beeld gebruikt. Aangezien er naast de spectrale banden ook nog 'metadata'-banden aanwezig zijn, dienen we eerst een selectie te maken van de te gebruiken banden. dit kan met de .select() functie. Selecteer enkel de bruikbare spectrale banden (['B2','B3','B4','B5','B6','B7','B8','B8A','B11','B12']).

  • De Earth Engine clusterer volgt het algoritme van [Weka](https://developers.google.com/earth-engine/apidocs/ee-clusterer-wekakmeans. In dit algoritme worden eerst pixels uit het beeld gesampled, waarop het K-means-algoritme wordt toegepast. Eenmaal het algoritme op punt staat, wordt het toegepast op de rest van het beeld. Met andere woorden: er wordt een niet-gesuperviseerd model getraind op een willekeurige steekproef van pixels die representatief worden geacht voor het volledige beeld. Het aantal te sampelen pixels moet dus voldoende groot zijn, maar niet te groot: anders krijg je de foutmelding geven: clusters: Layer error: Computed value is too large. De maximale capaciteit van Earth Engine ligt rond 1 miljoen pixels.

// Aanmaken"training" dataset.
var training = S2_im.sample({
  region: Paramaribo,
  scale: 10,
  numPixels: 5000
});
  • Eenmaal de pixels geselecteerd zijn die gebruikt gaan worden voor het aanmaken van de k clusters, kan het 'K-means cluster-algoritme' worden getraind. Deze bevat enkele parameters die de gebruiker nog kan instellen:

    1. nClusters: het eerste en het enige verplicht aan te geven argument dat het aantal gewenste clusters aangeeft.

    2. init: hoe de initiële clustercentra worden gekozen. De default-waarde plaatst willekeurig de startpunten.

    3. distanceFunction: welke afstandsberekening moet worden toegepast: Euclidisch of Manhattan. De euclidische afstand is default.

    4. maxIterations: het maximale aantal iteraties, indien opgegeven. De clusteranalyse stopt na dit aantal iteraties.

// Clusterer opstellen en trainen (7 klassen)
var Kmeans_cl = ee.Clusterer.wekaKMeans({nClusters : 7, init: 0}).train(training);

// Cluster toepassen op het volledige beeld
var classified = S2_im.cluster(Kmeans_cl);
  • Finaal visualiseren we ook het resultaat. We geven de klassen willekeurige kleuren met de .randomVisualizer().
// Visualiseren van het geclassificeerd beeld met willekeurige kleuren
Map.addLayer(classified.randomVisualizer(), {}, 'clusters');


Voorbeeldresultaat van de K-means clustering.

Opdrachten

  1. Interpreteer de bekomen klassen en tracht ze te linken aan landbedekkingsklassen. Gebruik hiervoor ook een Normale Kleuren, Valse Kleuren en 'Healthy Vegetation' (RGB = B8,B11,B2) composiet.

  2. Herhaal bovenstaande clustering enkele keren, met onderstaande parameters. Vergelijk de resultaten ook steeds met elkaar:

    • Je het aantal clusters verhoogt naar 10.

    • Je de parameter maxIterationsbinen de ee.ClustererwekaKMeans() functie toevoegd. Test de waarden 1, 10 en 30

    • Je de factor numPixels vergroot (naar bv 10000).