EstevezAlvarez
QGIS GeoAI Geoinformation Python

Automatic image classification with GeoAI in QGIS

GeoAI brings deep learning models directly into QGIS. This guide shows how to classify a multispectral satellite image into land-use categories, step by step, without leaving the GIS.

Image Sentinel-2 Landsat, drone Bands RGB, NIR, SWIR, NDVI Model Random Forest CNN / SAM fine-tuned Class map Vegetation Water Urban Analysis area, change, export to PostGIS
Classification workflow: the multispectral image feeds a trained model that produces a land-use class map, ready for quantitative analysis.

What is GeoAI?

GeoAI applies artificial intelligence techniques — classification, object detection and semantic segmentation — to geospatial data: satellite images, orthophotos, LiDAR point clouds or vector layers. Its goal is to automate tasks that previously required manual interpretation, such as mapping land use from a Sentinel-2 image or detecting changes between two dates.

The plugin OpenGeoAI for QGIS (opengeoai.org/qgis_plugin) integrates these models directly into the workspace, without switching to Python or an external notebook.

Install the plugin

  1. Open QGIS and go to Plugins → Manage and Install Plugins.
  2. In the tab All, search for OpenGeoAI.
  3. Click Install Plugin.
  4. Once installed, it appears in the menu Plugins → OpenGeoAI and in the side toolbar.

The plugin requires QGIS 3.22+ and Python 3.9+. Install the Python dependencies from the QGIS console if prompted by the plugin:

# Consola Python de QGIS (Complementos → Consola de Python)
import subprocess, sys
subprocess.run([sys.executable, "-m", "pip", "install",
                "torch", "torchvision", "rasterio", "scikit-learn"])

Prepare the image

Classification quality depends directly on preparation. Before classifying:

Supervised classification Requires: • Training samples (ROIs) • User-defined classes • Validation with independent data Common algorithms: Random Forest · SVM · CNN · SAM → Result: predefined classes Unsupervised classification Requires: • Set the number of clusters (k) • Subsequent class interpretation • Knowledge of the area Common algorithms: K-Means · ISODATA · K-Medoids → Result: spectral groups
Supervised classification uses user-labeled samples and produces predefined classes. Unsupervised classification groups pixels by spectral similarity without prior labels.

Define classes and training samples

For supervised classification, you need to create Regions of Interest (ROIs): polygons representing known examples of each class. More numerous and varied samples help the model generalize.

  1. Create a new polygon vector layer (Layer → Create Layer → New GeoPackage Layer) with a field clase of type text.
  2. Enable editing and draw polygons over homogeneous areas: dense forest, compact urban areas, water and bare soil.
  3. Assign a class label to each polygon.
  4. Recommendation: at least 20–50 polygons per class, distributed across different areas to capture variability.

Run the classification

  1. Open Plugins → OpenGeoAI → Image Classification.
  2. Select the raster image in Input raster.
  3. Select the ROI layer in Training samples and the class field in Class field.
  4. Choose the algorithm (Random Forest is a good starting point: robust and fast).
  5. Set the number of trees (100–300) and the validation percentage (20–30%).
  6. Set the output path and click Run.

The plugin produces the classified map as a raster and displays accuracy metrics: Overall Accuracy, Kappa coefficient and a per-class confusion matrix.

Interpret the results

An Overall Accuracy above 85% is an acceptable result for general land use. The confusion matrix is more informative: it shows where the model confuses classes (e.g. shrubs classified as forest). If a class has low accuracy, you need more training samples in that category or better separation of ROIs.

Automate with PyQGIS

If you need to process multiple images or integrate classification into a pipeline, you can call the algorithm from the QGIS Python console:

from qgis.core import QgsApplication, QgsRasterLayer
import processing

# Cargar imagen
raster = QgsRasterLayer("/datos/imagen_sentinel.tif", "sentinel")

# Ejecutar clasificación supervisada con Random Forest
resultado = processing.run(
    "openGeoAI:randomForestClassification",
    {
        "INPUT_RASTER": "/datos/imagen_sentinel.tif",
        "TRAINING_SAMPLES": "/datos/rois_entrenamiento.gpkg",
        "CLASS_FIELD": "clase",
        "N_ESTIMATORS": 200,
        "TEST_SIZE": 0.25,
        "OUTPUT": "/resultados/clasificacion_uso_suelo.tif",
    }
)

print(f"Overall Accuracy: {resultado['OVERALL_ACCURACY']:.2%}")
print(f"Kappa: {resultado['KAPPA']:.3f}")

Export to PostGIS for territorial analysis

# Convertir raster clasificado a polígonos vectoriales
processing.run("gdal:polygonize", {
    "INPUT":  "/resultados/clasificacion_uso_suelo.tif",
    "BAND":   1,
    "FIELD":  "clase_id",
    "OUTPUT": "/resultados/uso_suelo.gpkg",
})

# Cargar en PostGIS
processing.run("qgis:importintopostgis", {
    "INPUT":      "/resultados/uso_suelo.gpkg|layername=uso_suelo",
    "DATABASE":   "territorial_db",
    "SCHEMA":     "produccion",
    "TABLENAME":  "uso_suelo_clasificado",
    "OVERWRITE":  True,
    "CREATEINDEX": True,
})

With polygons in PostGIS, you can calculate areas by class, analyze temporal change by comparing two dates, intersect them with infrastructure layers or export to standard reporting formats.