Skip to content
AI Segmentation
QGIS
Tutorial

Detect Swimming Pools in QGIS: 5 Methods

Three panels of the same suburban block from the air: bare imagery, a colour threshold lighting up the pools and a blue roof alike, and a segmentation result with only the pools outlined.

To detect swimming pools in , check OpenStreetMap first: Vector > QuickOSM > QuickOSM…, key leisure, value swimming_pool. Where the map is thin, threshold the blue in the raster calculator or run a segmentation model. Ground resolution decides which.

Where the web gets this wrong

Three answers get repeated on forums and in tutorials, and each one costs you a day.

"Run NDWI on Sentinel-2 and count the pools." Green and NIR come at 10 m and SWIR at 20 m, while a new inground pool is 29 to 30 m². That is a third of a pixel. MNDWI over a suburb returns the reservoir at the edge of town and nothing in the gardens.

"Threshold the blue and you have your pools." A colour rule reads colour and nothing else. A blue metal roof and a tarpaulin over a woodpile pass it, a dark-liner pool and an algae-green pool fail it, and a covered pool is not in the image at all.

"The detection is the list." The French tax administration ran this on IGN photography and still sent a letter to every owner. A detection is a candidate, and joining it to a parcel and a name makes it personal data.

The short answer

Your inputMethodWhat it costs
Any area with active OSM mappersMethod 1, QuickOSM on leisure=swimming_poolFree, one query
RGB orthophoto at 5 to 30 cmMethod 2, colour threshold in the raster calculatorFree, in core QGIS
Imagery with a near-infrared or SWIR bandMethod 3, a water index, then a thresholdFree, blind to garden pools on satellite
Multispectral imagery and an afternoonMethod 4, SCP or dzetsakaFree plugins, your time drawing training areas
RGB orthophoto and hundreds of poolsMethod 5, a segmentation modelFree plugins want your own model or a GPU. Cloud plugins have free tiers, then a subscription

How I compared them

Five criteria: input, whether imagery leaves your machine, how much output you hand-check, cost, install effort. Every version, price and menu path was read on 3 September 2026 against the QGIS 3.44 manual and each tool's docs. I ran the free methods on a French suburban orthophoto and a Sentinel-2 scene of the same block.

We build one of the five, and it is Method 5. For a sweep where somebody signs off a published accuracy figure, use Mapflow instead. It ships a dedicated Swimming pools model, on request, with an F1 above 0.95 next to it. We publish no figure for pools.

Before you start

Work in a projected CRS, since three steps below filter on area in layer units. Then check resolution. The French pool federation puts a new inground pool at 29 to 30 m², 3,000 pixels on a 10 cm orthophoto and a third of one pixel on a 10 m Sentinel-2 band.

The French tax administration runs this on IGN aerial photography. Its Foncier innovant pilot taxed 20,356 pools across nine departments for 2022, worth 9.8 million euros, and the 2023 national pass found 150,000 taxable pools missing from the roll. Each one still went through a letter to the owner.

Method 1: Pull the pools somebody already mapped

OpenStreetMap carries 3,036,801 objects tagged leisure=swimming_pool, 2,731,704 of them ways with real geometry, on taginfo on 3 September 2026.

Open QuickOSM and query

Vector > QuickOSM > QuickOSM…, which queries the Overpass API. Key leisure, value swimming_pool, on the canvas extent or a named administrative area.

Keep polygons, filter to gardens

A pool mapped as a node has no area, so take the polygon layer. 1,808,809 of these pools also carry access=private, the filter for backyard pools.

leisure=swimming_area is a different object: a designated place to swim in a lake or the sea.

A suburban block on satellite imagery with OSM swimming pool polygons in blue over three pools, and seven other visible pools with no polygon at all.
Three pools mapped, seven not. Mappers draw public and hotel pools. Private garden pools are the ones nobody bothers with, and the ones a tax office is looking for.

Use it when: you need public and commercial pools.

Skip it when: the job is finding what nobody declared.

Method 2: Threshold the blue in the raster calculator

The closest core QGIS gets. Open Raster > Raster Calculator…, where bands are layer_name@band_number. On an RGB orthophoto this keeps bright, saturated blue:

("ortho@3" > 90) AND ("ortho@3" - "ortho@1" > 25) AND ("ortho@3" - "ortho@2" > 10)

Those numbers are mine, from a 20 cm orthophoto. Sample twenty pool pixels and twenty roof pixels, then move them.

Polygonize with Raster > Conversion > Polygonize (Raster to Vector), then filter with native:extractbyexpression: $area > 6 AND $area < 400 for size, and my own ratio 4 * pi() * $area / ($perimeter ^ 2) > 0.5 for shape, since QGIS ships no compactness function.

A suburban orthophoto with a red mask from the raster calculator covering every swimming pool, a blue metal roof, and a blue tarpaulin over a woodpile.
The rule above, over 20 cm imagery. It finds every open pool. It also finds a blue metal roof and a tarpaulin.

RGB values slide with sun angle and exposure, so a threshold tuned on one flight line breaks on the next. Hue and saturation hold up better, via the Processing Toolbox module i.rgb.his, which "transforms raster maps from RGB (Red-Green-Blue) color space to HIS (Hue-Intensity-Saturation) color space".

Neither rule knows what the blue thing is.

  • Shadow. Shaded roof slopes read dark blue. Raise the floor and you lose pools under trees.
  • Blue roofs and tarpaulins. Bright, blue, often the right shape.
  • Dark-bottom and green pools. A black liner reads as asphalt, algae as lawn. My rule missed both.
  • Covered pools. Not in the image at all.
Four tight crops side by side: a blue tarpaulin, a shaded roof slope, a dark-bottom pool and a pool under a grey winter cover, with the threshold mask overlaid on the first two only.
The tarp and the shadow pass the rule and should not. The dark-bottom pool and the covered pool fail it and should not.

Use it when: one consistent orthophoto you'll check by hand.

Skip it when: a mosaic of several flights.

Method 3: A water index, on imagery that has the bands

Water absorbs near-infrared almost completely, so it goes black in NIR while a blue roof stays bright.

  • NDWI, McFeeters 1996: (Green - NIR) / (Green + NIR). On Sentinel-2, (B3 - B8) / (B3 + B8).
  • MNDWI, Xu 2006: (Green - SWIR) / (Green + SWIR). On Sentinel-2, (B3 - B11) / (B3 + B11). Swapping NIR for SWIR suppresses built-up land, the point over a suburb.

Threshold above zero, polygonize, filter as in Method 2. Rodríguez-Cuenca and Alonso tuned a Normalized Difference Swimming Pools Index for this job in 2014.

Sentinel-2 delivers B3 and B8 at 10 m and B11 at 20 m, so a 30 m² pool never separates from the garden. MNDWI over a residential block returns the reservoir at the edge of town and nothing else.

Two panels of the same suburb: a 20 cm orthophoto with eleven visible pools, and the Sentinel-2 MNDWI of the same extent showing a uniform grey with no pool visible.
Eleven pools on the left, none on the right. Same extent, same week. A 30 m² pool never reaches a 10 m sensor as an object.

Use it when: your orthophoto has a NIR band at 50 cm or finer. It beats colour outright.

Skip it when: three-band RGB, or Sentinel-2 and you want garden pools.

Method 4: Train a classifier on your own imagery

A classifier learns your pool pixels from examples you draw, so it survives a mosaic that breaks a fixed threshold.

Semi-Automatic Classification Plugin by Luca Congedo is the usual choice. Create a training input (.scpx) in the SCP dock, draw ROIs, then run SCP > Band processing > Classification in the main window. Six algorithms, from Minimum Distance to Random Forest. Version 9.0.4 shipped 11 July 2026 but declares a QGIS minimum of 3.99, so QGIS 3.x still installs 8.5.0.

dzetsaka 5.0.11, by Nicolas Karasiak, is lighter: eleven classifiers, and its Gaussian Mixture Model runs without scikit-learn.

Draw a blue-roof class and a shadow class too. A classifier only rejects what you showed it.

The SCP dock in QGIS with a training input listing pool, roof, shadow and vegetation classes, and the classified raster behind it with pool pixels in cyan.
Three classes and a Random Forest over the same 20 cm orthophoto. The blue-roof class does more work than the pool class.

Use it when: several flights or seasons, and you'll reuse the workflow.

Skip it when: one orthophoto, one pass. Both classify pixels, not objects, so you still polygonize and filter.

Method 5: A segmentation model

A segmentation model reads shape and context, which is how it tells a pool from a tarpaulin of the same colour. We build one of these, AI Segmentation. This section is about our own tool.

Install and sign in

Plugin manager, QGIS 3.22 or later. No GPU, no model weights. An account, a free allowance, then 39 euros a month excluding VAT.

Draw a zone, type the word, filter

Type swimming pool and run. Polygons come back in the project CRS with area, perimeter and a confidence score. Sort, then delete what is wrong.

Two numbers from our tuning table, read at runtime. A pool run asks for roughly 0.13 m per pixel in tiles of at most 300 m, because a pool blurs into its terrace at anything coarser. The review opens at 0.20 confidence for swimming pool against 0.30 for building, since pool masks score lower than roofs.

A residential block on aerial imagery in QGIS, every backyard swimming pool filled with its own colour, roofs and gardens untouched.
One zone, one word, over 20 cm imagery. Each pool is its own polygon with an area, editable like any vector feature.

One limit: a covered pool never reaches the model, so it comes back missed. Both cloud modes send imagery to our servers in the European Union.

Two neighbouring gardens: the open pool on the left outlined in the detection layer, the pool under a grey winter cover on the right with no polygon.
Left, detected. Right, a pool under a cover. Nothing in the image says it is there, and no method on this page finds it.

Four others do this job, read 3 September 2026.

ToolWhat you installGPUAccountImagery leaves your machinePool supportCost
DeepnessPlugin manager, its Python packages, an ONNX modelOptional, CPU worksNoNoWhatever model you supplyFree
Geo-SAMPlugin manager, dependencies, model weightsOptionalNoNoOne object per click or boxFree
samgeoA Python package, no QGIS panelRecommendedNoNoScriptable, no pool classFree
MapflowPlugin managerNoYesYesA Swimming pools model, on requestCredits, paid
AI Segmentation (ours)Plugin managerNoYesYes in both cloud modes, no for the local modelType swimming poolFree allowance, then 39 euros a month excluding VAT

Use it when: more pools than you would outline by hand.

Skip it when: the imagery cannot leave your machine. Use Deepness or Geo-SAM.

The five methods side by side

What you haveMethod
A well-mapped town, public pools are enoughMethod 1, QuickOSM
One RGB orthophoto finer than 30 cmMethod 2, colour threshold, then filter
An orthophoto with a NIR bandMethod 3, NDWI
Sentinel-2 or anything at 10 mNone of them for garden pools. Get finer imagery
Several flights, a workflow you'll repeatMethod 4, SCP or dzetsaka
Hundreds of pools and no patience for false positivesMethod 5, a segmentation model

What to remember

Resolution decides first, then the bands, then how much hand-checking you can absorb.

A 30 m² pool never separates from its garden at 10 m, so Sentinel-2 is the wrong sensor for backyard pools whatever index you run.

A colour threshold returns every blue thing on the block, so filter on area and compactness before you look at the result.

A covered pool is missing from the imagery, so no method on this page finds it and no price changes that.

A detection is a candidate. Whatever you run, open the ten lowest-confidence polygons before anyone acts on the layer.

Try it free in QGIS, no card needed

Questions people ask

Can QGIS detect swimming pools on its own?

Not as a feature. Core QGIS gives you the raster calculator, polygonize and the vector filters, which is Method 2. Recognising a pool as an object needs a plugin.

Can I find backyard pools in Sentinel-2 imagery?

No. Green and NIR are 10 m bands and SWIR is 20 m, so a 30 m² pool is a third of a pixel. Use aerial imagery at 30 cm or better.

Why do blue roofs keep coming back as pools?

A painted metal roof is brighter and bluer than pool water, and a colour rule only reads colour. Filter on area and compactness, move to NDWI, or use a model.

Join a detection to a parcel and an owner's name and it becomes personal data, which in the EU needs a lawful basis under the GDPR. A tax administration has one written into law. A private company usually does not, so ask your data protection officer before the join, and never let a model's output be the last step before a bill.

What accuracy should I expect?

One number would be false, since it moves with your imagery and the season. Open pools at 20 cm come back well, covered pools are missed by everything here, and blue roofs are what you delete by hand.

For the filtering step in full, read detecting building footprints in QGIS. For the cleanup behind any mask, raster to vector in QGIS. The QGIS AI hub has the rest.