左側のピクセルは、ツリーの位置とそれに関連するクラウン半径(つまり、2〜5の範囲のピクセル値)を表します。これらのラスターピクセルをクラウン半径値でバッファリングしたいと思います。右の画像はラスタ処理方法のみを使用して達成したいものです。
近隣設定は固定値ですが、可変サイズのクラウン半径は考慮されませんが、最初はArcGISで円形の焦点和を使用することを考えます。
値でピクセルを「バッファリング」するのに良い方法は何ですか?
左側のピクセルは、ツリーの位置とそれに関連するクラウン半径(つまり、2〜5の範囲のピクセル値)を表します。これらのラスターピクセルをクラウン半径値でバッファリングしたいと思います。右の画像はラスタ処理方法のみを使用して達成したいものです。
近隣設定は固定値ですが、可変サイズのクラウン半径は考慮されませんが、最初はArcGISで円形の焦点和を使用することを考えます。
値でピクセルを「バッファリング」するのに良い方法は何ですか?
回答:
以下はand を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()
入力:
出力:
このタスクは、3つのステップで実行できます。
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を使用して非常に簡単に実装できます。
別のオプションは、各ピクセル値に対して個別のラスタを作成することです。この場合、条件付きで4つのラスタを作成します。次に、ラスターの値に対応するピクセル数でラスターを展開します(値リストを繰り返し処理することにより)。最後に、ラスターを(代数的または空間的に)結合して、樹冠用の1つのバイナリラスターを作成します。
バッファーのサイズを定義するためにピクセルの値を使用する機会がないため、これをラスターで行うのは難しい質問です。したがって、すでに述べたように、各値に対して焦点フィルターを実行する必要があります。
これは3つのフィルター(これより少ないものは見つかりませんでした)でそれを行うための可能な答えです。
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
コマンドは前のものをカバーします。
ピクセル位置がある場合は、半径と中点円アルゴリズム(ブレゼンハムアルゴリズムの変形)が手がかりになります。IMOでは、このアプローチからポリゴンを簡単に作成できます。これをPythonで実装するのは簡単だと思います。この一連のポリゴンを結合すると、カバー領域が得られます。