2025-11-18

QGIS Raster to Vector use Python console step1

處理步驟
1.從顏色分類的 RGB 影像中取得所有像素

2. 過濾白色背景區域

3. 使用 K-Means RGB Centroid 進行色彩匹配

4. 將像素映射為指定的 數值分類值

5. 產生可用於 QGIS、ArcGIS、Python 的 GeoTIFF 數值影像

6. 完整設定 NoData、座標系、像元大小



 import numpy as np

from osgeo import gdal, gdalconst


# ---------------------------------------------------

# 1. 路徑設定

# ---------------------------------------------------

input_path = r"D:\download\87ad4ea7-158c-4f27-9911-57fa9c1ebb472_modified.tif"

output_path = r"D:\download\value.tif"


# ---------------------------------------------------

# 2. 讀取 RGB 影像

# ---------------------------------------------------

ds = gdal.Open(input_path, gdalconst.GA_ReadOnly)

if ds is None:

    raise Exception("❌ 無法開啟輸入 TIFF")


R = ds.GetRasterBand(1).ReadAsArray().astype(np.float32)

G = ds.GetRasterBand(2).ReadAsArray().astype(np.float32)

B = ds.GetRasterBand(3).ReadAsArray().astype(np.float32)


rows, cols = R.shape

pixels = np.stack([R.flatten(), G.flatten(), B.flatten()], axis=1)


# ---------------------------------------------------

# 3. 白色背景過濾(非常重要)

# ---------------------------------------------------

# 白底 = RGB 皆 > 225

bg_mask = (pixels[:,0] > 225) & (pixels[:,1] > 225) & (pixels[:,2] > 225)


# 非背景像素

non_bg_pixels = pixels[~bg_mask]


print("原始像素:", len(pixels))

print("非背景像素(有效區域):", len(non_bg_pixels))


# ---------------------------------------------------

# 4. 使用 K-Means 得到的 RGB centroid

# ---------------------------------------------------

centroids = np.array([

    [117, 249,  20],   # 群 0 → 32.5

    [237,  28,  64],   # 群 1 → 45

    [148, 202, 235],   # 群 2 → 10

    [231, 224,  30],   # 群 3 → 37.5

    [ 19,  24,  20],   # 群 4 → NoData

    [ 56, 245, 161],   # 群 5 → 27.5

    [102,  97, 227],   # 群 6 → 22.5

], dtype=np.float32)


mapping = {

    0: 32.5,

    1: 45,

    2: 10,

    3: 37.5,

    4: -9999,

    5: 27.5,

    6: 22.5

}


# ---------------------------------------------------

# 5. 計算 pixel → 最近 centroid

# ---------------------------------------------------

dist = ((pixels[:, None, :] - centroids[None, :, :]) ** 2).sum(axis=2)

cluster_idx = np.argmin(dist, axis=1)


# ---------------------------------------------------

# 6. 對背景像素直接指定為 -9999

# ---------------------------------------------------

value_arr = np.vectorize(mapping.get)(cluster_idx)

value_arr[bg_mask] = -9999


value_arr = value_arr.reshape(rows, cols).astype(np.float32)


# ---------------------------------------------------

# 7. 輸出 GeoTIFF

# ---------------------------------------------------

driver = gdal.GetDriverByName("GTiff")

out_ds = driver.Create(output_path, cols, rows, 1, gdalconst.GDT_Float32)


out_ds.SetGeoTransform(ds.GetGeoTransform())

out_ds.SetProjection(ds.GetProjection())


band = out_ds.GetRasterBand(1)

band.WriteArray(value_arr)

band.SetNoDataValue(-9999)

band.FlushCache()


del out_ds

print("🎉 已完成:輸出數值影像 →", output_path)

沒有留言:

張貼留言

QGIS Raster to Vector use Python console step2

資料處理步驟: 1.讀取 Raster 並計算 25 等級等值線級距 2.用 GDAL 產生等值線(Contour Lines) 3.Polygonize:Raster 轉等值面多邊形 4.將多邊形圖層載入 QGIS 5.為每個 polygon 計算其 VALUE 所屬級距(LE...