Tôi đã hack cùng một giải pháp cho việc này và đã viết một bài viết trên blog về một chủ đề rất giống nhau, mà tôi sẽ tóm tắt ở đây. Kịch bản nhằm trích xuất một dòng sông từ hình ảnh NAIP 4 băng tần bằng cách sử dụng phương pháp phân loại và phân loại hình ảnh.
- Chuyển đổi hình ảnh thành một mảng numpy
- Thực hiện phân đoạn dịch chuyển nhanh (Hình 2)
- Chuyển đổi phân đoạn sang định dạng raster
- Tính toán NDVI
- Thực hiện thống kê khu vực trung bình bằng cách sử dụng các phân đoạn và NDVI để chuyển các giá trị NDVI sang các phân đoạn (Hình 3)
- Phân loại phân khúc dựa trên giá trị NDVI
- Đánh giá kết quả (Hình 4)
Ví dụ này phân đoạn một hình ảnh bằng cách sử dụng phân cụm quickshift trong không gian màu (x, y) với 4 dải (đỏ, lục, lam, NIR) thay vì sử dụng phân cụm K-nghĩa. Phân đoạn hình ảnh được thực hiện bằng cách sử dụng gói hình ảnh scikit . Chi tiết hơn về một loạt các thuật toán phân đoạn hình ảnh trong hình ảnh scikit ở đây . Để thuận tiện, tôi đã từng arcpy
thực hiện nhiều công việc của GIS, mặc dù điều này khá dễ dàng để chuyển sang GDAL.
from __future__ import print_function
import arcpy
arcpy.CheckOutExtension("Spatial")
import matplotlib.pyplot as plt
import numpy as np
from skimage import io
from skimage.segmentation import quickshift
# The input 4-band NAIP image
river = r'C:\path\to\naip_image.tif'
# Convert image to numpy array
img = io.imread(river)
# Run the quick shift segmentation
segments = quickshift(img, kernel_size=3, convert2lab=False, max_dist=6, ratio=0.5)
print("Quickshift number of segments: %d" % len(np.unique(segments)))
# View the segments via Python
plt.imshow(segments)
# Get raster metrics for coordinate info
myRaster = arcpy.sa.Raster(river)
# Lower left coordinate of block (in map units)
mx = myRaster.extent.XMin
my = myRaster.extent.YMin
sr = myRaster.spatialReference
# Note the use of arcpy to convert numpy array to raster
seg = arcpy.NumPyArrayToRaster(segments, arcpy.Point(mx, my),
myRaster.meanCellWidth,
myRaster.meanCellHeight)
outRaster = r'C:\path\to\segments.tif'
seg_temp = seg.save(outRaster)
arcpy.DefineProjection_management(outRaster, sr)
# Calculate NDVI from bands 4 and 3
b4 = arcpy.sa.Raster(r'C:\path\to\naip_image.tif\Band_4')
b3 = arcpy.sa.Raster(r'C:\path\to\naip_image.tif\Band_3')
ndvi = arcpy.sa.Float(b4-b3) / arcpy.sa.Float(b4+b3)
# Extract NDVI values based on image object boundaries
zones = arcpy.sa.ZonalStatistics(outRaster, "VALUE", ndvi, "MEAN")
zones.save(r'C:\path\to\zones.tif')
# Classify the segments based on NDVI values
binary = arcpy.sa.Con(zones < 20, 1, 0)
binary.save(r'C:\path\to\classified_image_objects.tif')