Cắt raster bằng rasterio và geopandas


8

Tôi đang cắt một bộ ảnh trên không lịch sử. Những bức ảnh này có các vùng màu đen lớn ở các cạnh (giá trị 0). Tuy nhiên, cũng có dữ liệu hợp lệ với giá trị 0. Quy trình công việc tôi đang sử dụng là:

  1. Tải raster với rasterio
  2. Đa giác hóa raster với rasterio.features.shapes ()
  3. Xác định đa giác trong đó value = 0 và kích thước> 5000 mét vuông
  4. Mặt nạ hình ảnh gốc với đa giác, thực hiện mặt nạ đảo ngược

Đây là mã hiện tại của tôi để che giấu một hình ảnh duy nhất:

import rasterio
from rasterio import features
from rasterio import mask
import json
import geopandas as gpd

results = []
final_results = []

with rasterio.open(r"C:\1927_oahu\tif\_Line1_6to8_0.tif") as src:
    src_meta = src.meta
    src_affine = src_meta.get("transform")

    band = src.read(1)

    for geometry, raster_value in features.shapes(band, transform=src_affine):
        if raster_value == 0:
        result = {'properties': {'raster_value': raster_value}, 'geometry': geometry}
        results.append(result)

gpd_results = gpd.GeoDataFrame.from_features(results)

gpd_results["area"] = gpd_results["geometry"].area

gpd_results_filtered = gpd_results[gpd_results["area"] > 5000]

gpd_filtered_json_str = gpd_results_filtered.to_json()

gpd_filtered_json_dict = json.loads(gpd_filtered_json_str)

for k, v in gpd_filtered_json_dict.iteritems():
    if k == "features":
        for items in v:
            #final_results = {"coordinates": (items.get("geometry").get("coordinates"))}
            final_results = {"geometry": (items.get("geometry").get("coordinates"))}

masked_band, masked_transform = mask.mask(src, final_results, invert=True)

src_meta.update(dtype=rasterio.uint8, nodata=0)
with rasterio.open(os.path.join(r"C:\1927_oahu_output", "out.tif"), 'w', **src_meta) as dst:
    dst.write_band(1, masked_band.astype(rasterio.uint8))

Khi tôi chạy mã này, tôi nhận được lỗi sau: AttributeError: 'str' object has no attribute 'get'

Các tài liệu cho rasterio.mask trạng thái: Đa giác là GeoJSON giống như dicts xác định ranh giới của các tính năng trong raster được lưu giữ. Tất cả dữ liệu bên ngoài đa giác được chỉ định sẽ được đặt thành gật đầu.

Tôi giả sử rằng tôi đang cho rasterio.mask loại sai của "chính tả giống như GeoJSON". Tôi đã cố gắng định dạng lại chính tả một số cách mà không thành công. Có ai biết cách chính xác để chuyển đổi GeoJSON thành một "chính tả giống như GeoJSON" không?

Hoặc bất cứ ai cũng có thể cung cấp định dạng chính xác của một "chính tả giống như GeoJSON"?

Tôi mới đến rasterio và geopandas.

Câu trả lời:


6

Vấn đề được giải quyết. Vấn đề là tôi đã đọc sai tài liệu. Trong lần đọc thứ hai, tài liệu rasterio.mask nói rõ rằng đa giác phải là một danh sách các ký tự giống như GeoJSON. Tôi đã tìm thấy đoạn mã sau đây để tạo các danh sách đó từ câu trả lời này :

geoms = [feature["geometry"] for feature in shapefile]

Đây là mã đầy đủ đang hoạt động:

import rasterio
from rasterio import features
from rasterio import mask
import json
import geopandas as gpd
import os

results = []
final_results = []

with rasterio.open(r"C:\1927_oahu\tif\_Line1_6to8_0.tif") as src:
    src_meta = src.meta.copy()
    src_affine = src_meta.get("transform")

    band = src.read(1)

    for geometry, raster_value in features.shapes(band, transform=src_affine):
        if raster_value == 1:
            result = {'properties': {'raster_value': raster_value}, 'geometry': geometry}
            results.append(result)

        gpd_results = gpd.GeoDataFrame.from_features(results)

        gpd_results["area"] = gpd_results["geometry"].area

        gpd_results_filtered = gpd_results[gpd_results["area"] > 5000]

        gpd_filtered_json_str = gpd_results_filtered.to_json()

        gpd_filtered_json_dict = json.loads(gpd_filtered_json_str)

        final_results = [feature["geometry"] for feature in gpd_filtered_json_dict["features"]]

        masked_band, masked_transform = mask.mask(src, final_results, invert=True)

        masked_band[masked_band > 255] = 0

        src_meta.update(dtype=rasterio.uint8, height=int(masked_band.shape[1]), width=int(masked_band.shape[2]), nodata=0, transform=masked_transform, compress='lzw')

        with rasterio.open(r"C:\1927_oahu\output\_Line1_6to8_0.tif"), 'w', **src_meta) as dst:
                dst.write(masked_band.astype(rasterio.uint8))   
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.