roboflow/supervision · error · ValueError
InferenceSlicer requires a projected coordinate reference sy
Error message
InferenceSlicer requires a projected coordinate reference system for pixel-space tiled inference on a raster dataset. The provided dataset uses a geographic CRS ({crs}). Reproject it to a projected CRS (e.g. with `gdalwarp`) before slicing. What it means
Raised by InferenceSlicer._get_resolution_wh when the input is a windowed raster dataset whose CRS is geographic (latitude/longitude degrees, e.g. EPSG:4326). The slicer works purely in pixel space; the guard exists because downstream georeferencing math (converting pixel offsets to world coordinates) is only meaningful when map units are linear, so the dataset must use a projected CRS (metres/feet).
Source
Thrown at src/supervision/detection/tools/inference_slicer.py:445
with ThreadPoolExecutor(max_workers=self.thread_workers) as executor:
futures = [
executor.submit(self._run_callback, image, offset)
for offset in remaining_offsets
]
for future in as_completed(futures):
detections_list.append(future.result())
merged = Detections.merge(detections_list=detections_list)
return self._apply_overlap_filter(merged)
def _get_resolution_wh(
self, image: ImageType | WindowedRasterDataset
) -> tuple[int, int]:
"""Return ``(width, height)`` for the image, validating CRS for rasters."""
if _is_windowed_raster(image):
crs = image.crs
if crs is not None and not getattr(crs, "is_projected", True):
raise ValueError(
"InferenceSlicer requires a projected coordinate reference "
"system for pixel-space tiled inference on a raster dataset. "
f"The provided dataset uses a geographic CRS ({crs}). Reproject "
"it to a projected CRS (e.g. with `gdalwarp`) before slicing."
)
return (image.width, image.height)
return get_image_resolution_wh(image)
def _apply_overlap_filter(self, merged: Detections) -> Detections:
"""Apply the configured overlap filter strategy to merged detections."""
if self.overlap_filter == OverlapFilter.NONE:
return merged
if self.overlap_filter == OverlapFilter.NON_MAX_SUPPRESSION:
return merged.with_nms(
threshold=self.iou_threshold,
overlap_metric=self.overlap_metric,
)
if self.overlap_filter == OverlapFilter.NON_MAX_MERGE:View on GitHub (pinned to 7f254d9784)
Solutions
- Reproject the raster to a projected CRS before slicing, e.g. gdalwarp -t_srs EPSG:32633 input.tif output.tif, or rasterio.warp.reproject.
- Pick a sensible local/UTM zone so pixel sizes stay approximately uniform.
- If georeferencing accuracy does not matter, convert the raster to a plain image array and slice that instead.
Example fix
# before
with rasterio.open('wgs84.tif') as src:
detections = slicer(src) # ValueError: geographic CRS
# after
# shell: gdalwarp -t_srs EPSG:32633 wgs84.tif utm.tif
with rasterio.open('utm.tif') as src:
detections = slicer(src) Defensive patterns
Strategy: validation
Validate before calling
def ensure_projected_crs(dataset, default_epsg=None):
crs = dataset.crs
if crs is not None and not getattr(crs, 'is_projected', True):
raise ValueError(
f'Geographic CRS {crs} not supported; reproject e.g. with '
f'gdalwarp -t_srs EPSG:{default_epsg or 32633}'
)
return dataset
with rasterio.open(path) as src:
ensure_projected_crs(src)
detections = slicer(src) Type guard
def is_projected_dataset(dataset) -> bool:
crs = dataset.crs
return crs is None or bool(getattr(crs, 'is_projected', True)) Try / catch
try:
detections = slicer(raster)
except ValueError as err:
if 'projected' in str(err) and 'CRS' in str(err):
raise RuntimeError(f'reproject the raster first: {err}') from err
raise Prevention
- Standardize the ingestion pipeline on a projected CRS (UTM zone of the area of interest).
- Check dataset.crs.is_projected during data validation, before inference starts.
When it happens
Trigger: Calling slicer(raster_dataset) where raster_dataset is a rasterio-style windowed dataset with dataset.crs.is_projected == False, e.g. a standard WGS84 GeoTIFF (EPSG:4326).
Common situations: Slicing satellite/drone imagery delivered in WGS84; forgetting to reproject newly acquired tiles; pipelines that worked with UTM datasets failing on web-mercator-vs-WGS84 mixed data.
Related errors
- `slice_wh` must be an int or a tuple of two positive integer
- `overlap_wh` must be an int or a tuple of two non negative i
- Resolution width and height are required for moving segmenta
- `thread_workers` must be a positive integer. Received: {thre
- `batch_size` must be a positive integer. Received: {batch_si
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/95fd0584ca90bf29.
Report an issue: GitHub.