左侧的像素表示树的位置及其关联的树冠半径(即像素值范围为2-5)。我想通过它们的冠状半径值来缓冲这些栅格像素。右边的图像是我希望仅使用栅格处理方法来完成的图像。
我最初会考虑在ArcGIS中使用圆形焦点总和,尽管邻域设置是一个固定值,但不会考虑可变大小的冠状半径。
用像素值“缓冲”像素的好方法是什么?
左侧的像素表示树的位置及其关联的树冠半径(即像素值范围为2-5)。我想通过它们的冠状半径值来缓冲这些栅格像素。右边的图像是我希望仅使用栅格处理方法来完成的图像。
我最初会考虑在ArcGIS中使用圆形焦点总和,尽管邻域设置是一个固定值,但不会考虑可变大小的冠状半径。
用像素值“缓冲”像素的好方法是什么?
Answers:
这是Python 2.7
使用numpy
和的纯栅格解决方案scipy
:
import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
#create tree location matrix with values indicating crown radius
A = np.zeros((120,320))
A[60,40] = 1
A[60,80] = 2
A[60,120] = 3
A[60,160] = 4
A[60,200] = 5
A[60,240] = 6
A[60,280] = 7
#plot tree locations
fig = plt.figure()
plt.imshow(A, interpolation='none')
plt.colorbar()
#find unique values
unique_vals = np.unique(A)
unique_vals = unique_vals[unique_vals > 0]
# create circular kernel
def createKernel(radius):
kernel = np.zeros((2*radius+1, 2*radius+1))
y,x = np.ogrid[-radius:radius+1, -radius:radius+1]
mask = x**2 + y**2 <= radius**2
kernel[mask] = 1
return kernel
#apply binary dilation sequentially to each unique crown radius value
C = np.zeros(A.shape).astype(bool)
for k, radius in enumerate(unique_vals):
B = ndimage.morphology.binary_dilation(A == unique_vals[k], structure=createKernel(radius))
C = C | B #combine masks
#plot resulting mask
fig = plt.figure()
plt.imshow(C, interpolation='none')
plt.show()
输入:
输出:
此任务可以通过三个步骤完成:
Raster To Point
;Buffer
(使用该VALUE
字段作为缓冲区字段);Feature To Raster
。注意:使用缓冲区字段可避免为每个冠部半径值计算缓冲区。
避免基于向量的解决方案,此问题建议使用一种基于最近邻的元胞自动机。假设所有黑色像素均为零,则将像素平方并且其大小等于1(或者适当缩放),采用的规则非常简单:
VALUE
)大于1,则其值变为VALUE-1
,然后考虑其周围的像素。如果它们的值是小于VALUE-1
,这些像素出生或成长,其价值变得VALUE-1
。否则,这些像素将保留下来并保持不变。VALUE<=1
,则不执行任何操作(像素已耗尽!)。这些规则必须被应用,直到所有像素都死了,即它们的值等于0或1,那么N-1
次,其中N
是您在输入栅格成为最高值。使用一些Python和numpy可以很容易地实现这种方法。
在栅格中执行此操作是一个具有挑战性的问题,因为您没有机会使用像素值来定义缓冲区的大小。因此,正如您已经说过的,您将需要对每个值进行焦点过滤。
这是仅使用3个过滤器(我找不到的过滤器)来实现的可能答案,但并不完全如Whuber所言:当树木彼此靠近时,您的缓冲区将被截断。
1)编辑:欧几里得分配(这不能完全解决问题,因为它在较小的树附近削减了缓冲区,但比我的第一个解决方案要好得多)。
2)每个像素周围的欧几里得距离
3)带有条件语句的栅格计算器(地图代数)
Con("allocation_result" > ("distance_result" / pixel_size) , 1 , 0)
请注意,您可以根据需要调整半径(带或不带中心像素)的条件
想知道为什么不使用ArcGIS的扩展工具?
import arcpy
from arcpy.sa import *
raster_in = r'c:\test.tif'
raster_out = r'c:\test_out.tif'
outExpand1 = Expand(raster_in, 2, 2)
outExpand2 = Expand(outExpand1, 3, 3)
outExpand3 = Expand(outExpand3, 4, 4)
outExpand4 = Expand(outExpand4, 5, 5)
outExpand4.save(raster_out)
如果有重叠:最新的expand
命令将覆盖先前的命令。
如果您有像素位置,则可以使用半径和中点圆算法(Bresenham Alg。的一种)来提供线索。IMO很容易通过这种方法创建多边形,而我认为在Python中实现这一点很容易。这一组多边形的并集为您提供覆盖区域。