Des versions de la BdOrtho sont accessibles en TMS via https://data.geopf.fr/tms/1.0.0/
Il y a aussi des version à télécharger sur https://geoservices.ign.fr/telechargement-api/BDORTHO
P'tit script Python pour découper les JP2 en JPG 640 pixels pour Yolo:
""" Installation: pip install rasterio pillow numpy tqdm """ import rasterio import os import glob import shutil from rasterio.windows import Window from PIL import Image import numpy as np from tqdm import tqdm from concurrent.futures import ThreadPoolExecutor, as_completed import argparse import sys def decouper_fichier_jp2(fichier, dossier_sortie, taille=640): nom_base = os.path.splitext(os.path.basename(fichier))[0] sous_dossier = os.path.join(dossier_sortie, nom_base) os.makedirs(sous_dossier, exist_ok=True) # Copie du fichier .tab fichier_tab = fichier.replace('.jp2', '.tab') if os.path.exists(fichier_tab): shutil.copy(fichier_tab, os.path.join(sous_dossier, f"{nom_base}.tab")) # Découpe le fichier JP2 en tuiles JPG with rasterio.open(fichier) as src: h, w = src.shape nb_tuiles_h = h // taille nb_tuiles_w = w // taille total_tuiles = nb_tuiles_h * nb_tuiles_w # réserve un buffer pour limiter une allocation à chaque tuile. buffer = np.empty((src.count, taille, taille), dtype=np.uint8) with tqdm(total=total_tuiles, desc=f"Traitement de {nom_base}") as pbar: for y in range(0, h, taille): for x in range(0, w, taille): window = Window(x, y, taille, taille) if y + taille <= h and x + taille <= w: tile = src.read(window=window, out=buffer) tile_rgb = np.moveaxis(tile, 0, -1).astype(np.uint8) img = Image.fromarray(tile_rgb) img.save(f"{sous_dossier}/{nom_base}_x{x}_y{y}.jpg") pbar.update(1) def decouper_jp2_en_tuiles_parallele(dossier_entree, dossier_sortie, taille=640, nb_threads=4): os.makedirs(dossier_sortie, exist_ok=True) fichiers = glob.glob(os.path.join(dossier_entree, "*.jp2")) #fichiers = glob.glob(os.path.join(dossier_entree, "37-2025-0505-6715-LA93-0M20-E080.jp2")) with ThreadPoolExecutor(max_workers=nb_threads) as executor: futures = [executor.submit(decouper_fichier_jp2, fichier, dossier_sortie, taille) for fichier in fichiers] for future in as_completed(futures): future.result() # Attend la fin de chaque tâche if __name__ == "__main__": parser = argparse.ArgumentParser(description="Découp les images BDOrtho IGN en tuiles de 640 pixels.") parser.add_argument("folder_in", help="Dossier des images à traiter (obligatoire)") parser.add_argument("folder_out", help="Dossier de sorties pour les tuiles découpées (obligatoire)") parser.add_argument("--threads", type=int, default=4, help="Combien de threads pour la découpe(défaut: 4).") args = parser.parse_args() if not os.path.isdir(args.folder_in): print(f"Error: Folder '{args.folder_in}' not found.") sys.exit(1) decouper_jp2_en_tuiles_parallele( #"/media/cyrille/Seagate Backup Plus Drive/BDORTHO_2-0_RVB-0M20_JP2-E080_LAMB93_D032_2025-01-01/ORTHOHR/1_DONNEES_LIVRAISON_2025-10-00030/OHR_RVB_0M20_JP2-E080_LAMB93_D32-2025/", #"/mnt/nas/IGN_BDOrtho/BDORTHO_2-0_RVB-0M20_JP2-E080_LAMB93_D005_2025-01-01/ORTHOHR/1_DONNEES_LIVRAISON_2026-01-00129/OHR_RVB_0M20_JP2-E080_LAMB93_D05-2025/", args.folder_in, #"/mnt/nas/IGN_BDOrtho/BDORTHO_tuiles-640_05/", args.folder_out, nb_threads=args.threads, )