影像(images)
-
✅ 文件总数
-
✅ 每个
.tif的:-
宽 × 高
-
通道数(Band 数)
-
数据类型(uint16 / float32 / ...)
-
像素最小 / 最大值
-
-
✅ 是否存在尺寸不一致
-
✅ 是否存在通道数不一致
📌 标注(masks)
-
✅ 文件是否与 image 一一对应
-
✅ mask 的:
-
宽 × 高
-
通道数
-
唯一像素值(自动判断几类)
-
-
✅ 是否存在:
-
非单通道 mask
-
非整数 mask
-
image / mask 尺寸不匹
-
python
import os
import numpy as np
from osgeo import gdal
from collections import Counter
def read_tif_basic(path):
ds = gdal.Open(path)
if ds is None:
raise FileNotFoundError(f"无法打开: {path}")
w = ds.RasterXSize
h = ds.RasterYSize
bands = ds.RasterCount
dtype = ds.GetRasterBand(1).DataType
dtype_name = gdal.GetDataTypeName(dtype)
arr = ds.ReadAsArray()
return w, h, bands, dtype_name, arr
def check_split(root, split):
print(f"\n{'='*60}")
print(f"📂 检查 split: {split}")
print(f"{'='*60}")
img_dir = os.path.join(root, "images", split)
mask_dir = os.path.join(root, "masks", split)
img_files = sorted([f for f in os.listdir(img_dir) if f.endswith(".tif")])
mask_files = sorted([f for f in os.listdir(mask_dir) if f.endswith(".tif")])
print(f"Image 数量: {len(img_files)}")
print(f"Mask 数量: {len(mask_files)}")
# === 一一对应检查 ===
missing_masks = set(img_files) - set(mask_files)
missing_images = set(mask_files) - set(img_files)
if missing_masks:
print(f"❌ 缺失 mask 文件: {list(missing_masks)[:5]}")
if missing_images:
print(f"❌ 多余 mask 文件: {list(missing_images)[:5]}")
if not missing_masks and not missing_images:
print("✅ Image / Mask 文件名完全对应")
img_shapes = []
img_bands = set()
mask_shapes = []
mask_bands = set()
mask_values = Counter()
for i, name in enumerate(img_files[:20]): # 只抽查前 20 个
img_path = os.path.join(img_dir, name)
mask_path = os.path.join(mask_dir, name)
iw, ih, ib, idtype, img = read_tif_basic(img_path)
mw, mh, mb, mdtype, mask = read_tif_basic(mask_path)
img_shapes.append((iw, ih))
img_bands.add(ib)
mask_shapes.append((mw, mh))
mask_bands.add(mb)
if mask.ndim == 3:
mask = mask[0]
unique_vals = np.unique(mask)
mask_values.update(unique_vals.tolist())
print(f"\n[{i+1}] {name}")
print(f" Image : {iw}×{ih}, bands={ib}, dtype={idtype}, "
f"min={img.min():.1f}, max={img.max():.1f}")
print(f" Mask : {mw}×{mh}, bands={mb}, dtype={mdtype}, "
f"unique={unique_vals[:10]}")
if (iw, ih) != (mw, mh):
print(" ❌ Image / Mask 尺寸不一致")
print("\n📊 统计汇总")
print(f"Image 尺寸集合: {set(img_shapes)}")
print(f"Image 通道数集合: {img_bands}")
print(f"Mask 尺寸集合: {set(mask_shapes)}")
print(f"Mask 通道数集合: {mask_bands}")
print(f"Mask 像素值统计(前 20 个): {mask_values.most_common(20)}")
if __name__ == "__main__":
ROOT = r"D:\MengChenCode20251215\AI4Boundaries\sentinel2\orthos"
for split in ["train", "val", "test"]:
check_split(ROOT, split)