import rastereasy

Kmeans

1) read image

name_im='./data/demo/sentinel.tif'
Image=rastereasy.Geoimage(name_im)
help(Image.kmeans)
Help on method kmeans in module rastereasy.rastereasy:

kmeans(
    n_clusters=4,
    bands=None,
    random_state=None,
    dest_name=None,
    standardization=True,
    nb_points=1000
) method of rastereasy.rastereasy.Geoimage instance
    Perform K-means clustering on the image data.

    This method performs an unsupervised classification using K-means clustering,
    which groups pixels with similar spectral characteristics into a specified
    number of clusters.

    Parameters
    ----------
    n_clusters : int, optional
        Number of clusters (classes) to create.
        Default is 4.
    bands : list of str or None, optional
        List of bands to use for clustering. If None, all bands are used.
        Default is None.
    random_state : int or None, optional
        Random seed for reproducible results. If None, results may vary between runs.
        Default is RANDOM_STATE (defined globally).
    dest_name : str, optional
        Path to save the clustered image. If None, the image is not saved.
        Default is None.
    standardization : bool, optional
        Whether to standardize bands before clustering (recommended).
        Default is True.
    nb_points : int or None, optional
        Number of random points to sample for training the model. If None,
        all valid pixels are used (may be slow for large images).
        Default is 1000.

    Returns
    -------
    Geoimage
        A new Geoimage containing the cluster IDs (0 to n_clusters-1)
    tuple
        A tuple containing (kmeans_model, scaler) for reusing the model on other images

    Examples
    --------
    >>> # Basic K-means clustering with 5 clusters
    >>> classified, model = image.kmeans(n_clusters=5)
    >>> classified.visu(colorbar=True, cmap='viridis')
    >>>
    >>> # Cluster using only specific bands and save result
    >>> classified, model = image.kmeans(
    >>>      n_clusters=3, bands=["NIR", "Red", "Green"],
    >>>      dest_name="clusters.tif")
    >>>
    >>> # Apply same model to another image
    >>> other_classified = other_image.apply_ML_model(model)

    Notes
    -----
    - Standardization is recommended, especially when bands have different ranges
    - The returned model can be used with apply_ML_model() on other images

2) kmeans with all bands with 4 clusters

classif_all_bands,kmeans_model=Image.kmeans(n_clusters=4,random_state=None,nb_points=None)
classif_all_bands.visu()
<Figure size 640x480 with 0 Axes>
../_images/207aa95efa74982d643734fe587513d78b1b7a753df3dca236d2c0d3b8d57073.png

2) kmeans with all bands with 10 clusters

classif_all_bands_nostd,_=Image.kmeans(n_clusters=10,random_state=2,standardization=False,dest_name='./data/results/ML/KMeans/classif.tif')
classif_all_bands_nostd.visu()
<Figure size 640x480 with 0 Axes>
../_images/db62ad5abaee7255010117006a2b6c7b299258918344743116b0c9b2e44fa423.png

3) kmeans with all bands with 5 clusters and 4 bands

classif_all_bands_std,_=Image.kmeans(n_clusters=5,random_state=2,bands=["8",3,1,2],standardization=False)
classif_all_bands_std.visu()
<Figure size 640x480 with 0 Axes>
../_images/88618584d81136cb820f9dca1bb35d8d8b82917ba08baf12f9b8cdfec476e7a3.png

Learn a kmean on half on the image and apply it to the other part

1) Learn the kmean

classif_half1,model=Image.crop(0,1000,0,500).kmeans(n_clusters=4,nb_points=None)
classif_half1.visu()
classif_half1.info()
<Figure size 640x480 with 0 Axes>
../_images/c773dbe6cad82696194673af1333f648b28ce7fdab1e3e1f9a0aa6cbd506a1fa.png
- Size of the image:
   - Rows (height): 1000
   - Cols (width): 500
   - Bands: 1
- Spatial resolution: 10.0  meters / degree (depending on projection system)
- Central point latitude - longitude coordinates: (7.04096778, 38.36795533)
- Driver: GTiff
- Data type: int32
- Projection system: EPSG:32637
- Nodata: -32768.0

- Given names for spectral bands: 
   {'1': 1}

2) Apply the kmean

help(Image.apply_ML_model)
Help on method apply_ML_model in module rastereasy.rastereasy:

apply_ML_model(model, bands=None) method of rastereasy.rastereasy.Geoimage instance
    Apply a pre-trained machine learning model to the image.

    This method applies a machine learning model (such as one created by kmeans())
    to the image data, creating a new classified or transformed image.

    Parameters
    ----------
    model : tuple
        A tuple containing (ml_model, scaler) where:
        - ml_model: A trained scikit-learn model with a predict() method
        - scaler: The scaler used for standardization (or None if not used)
    bands : list of str or None, optional
        List of bands to use as input for the model. If None, all bands are used.
        Default is None.

    Returns
    -------
    Geoimage
        A new Geoimage containing the model output

    Examples
    --------
    >>> # Train a model on one image and apply to another
    >>> classified, model = reference_image.kmeans(n_clusters=5)
    >>> new_classified = target_image.apply_ML_model(model)
    >>> new_classified.visu(colorbar=True, cmap='viridis')
    >>>
    >>> # Train on specific bands and apply to the same bands
    >>> _, model = image.kmeans(bands=["NIR", "Red"], n_clusters=3)
    >>> result = image.apply_ML_model(model, bands=["NIR", "Red"])
    >>> result.save("classified.tif")

    Notes
    -----
    - The model must have been trained on data with the same structure as what it's being applied to (e.g., same number of bands)
    - If a scaler was used during training, it will be applied before prediction
    - This method is useful for:
    - Applying a classification model to new images
    - Ensuring consistent classification across multiple scenes
    - Time-series analysis with consistent classification
classif_half2=Image.crop(0,1000,500,1000).apply_ML_model(model)
classif_half2.visu()
classif_half2.info()
<Figure size 640x480 with 0 Axes>
../_images/a93faa4822b95145bcfce0176e471b0bd8111fce02b5fc760c328a0d122c890f.png
- Size of the image:
   - Rows (height): 1000
   - Cols (width): 500
   - Bands: 1
- Spatial resolution: 10.0  meters / degree (depending on projection system)
- Central point latitude - longitude coordinates: (7.04102677, 38.41322566)
- Driver: GTiff
- Data type: int32
- Projection system: EPSG:32637
- Nodata: -32768.0

- Given names for spectral bands: 
   {'1': 1}

3) Merge images

1) Adjust size of images

classif1 ,classif2=rastereasy.extend_common_areas(classif_half1,classif_half2)
classif1.info()
classif2.info()
classif1.visu(title='Clustering 1st part')
classif2.visu(title='Application of clustering 2nd part')  
- Size of the image:
   - Rows (height): 1000
   - Cols (width): 1000
   - Bands: 1
- Spatial resolution: 10.0  meters / degree (depending on projection system)
- Central point latitude - longitude coordinates: (7.04099599, 38.39058840)
- Driver: GTiff
- Data type: int32
- Projection system: EPSG:32637
- Nodata: 0

- Given names for spectral bands: 
   {'1': 1}


- Size of the image:
   - Rows (height): 1000
   - Cols (width): 1000
   - Bands: 1
- Spatial resolution: 10.0  meters / degree (depending on projection system)
- Central point latitude - longitude coordinates: (7.04099599, 38.39058840)
- Driver: GTiff
- Data type: int32
- Projection system: EPSG:32637
- Nodata: 0

- Given names for spectral bands: 
   {'1': 1}
<Figure size 640x480 with 0 Axes>
../_images/b98454283971c421c764e6f06e341f94699c820a5f95eb201f847c0485de52fc.png
<Figure size 640x480 with 0 Axes>
../_images/a5c1366d678fdf98411af3ed56b1a0aec3e49b33b74f642d642b967972416e27.png

2) Merge images

classif_all=classif1+classif2
classif_all.info()
classif_all.save('./data/results/ML/KMeans/cluster_all.tif')
classif_all.visu(title='Global image')
- Size of the image:
   - Rows (height): 1000
   - Cols (width): 1000
   - Bands: 1
- Spatial resolution: 10.0  meters / degree (depending on projection system)
- Central point latitude - longitude coordinates: (7.04099599, 38.39058840)
- Driver: GTiff
- Data type: int32
- Projection system: EPSG:32637
- Nodata: 0

- Given names for spectral bands: 
   {'1': 1}
<Figure size 640x480 with 0 Axes>
../_images/96ab7ef3cb3a57c7e57527e8b6d7bb8574c7a14504dc0e7c3522ce9f80129ff8.png