[英]numpy extract 3d cubes from 3d array
我想從(180x180x197)的布爾3D數組中提取3D多維數據集(3x3x3)。 這類似於scipy.ndimage.measurements.label,但需要固定大小(3x3x3)。 是否有比使用for循環更快速的方法。
在您的特殊情況下,我建議使用ndimage.minimum_filter假設您的數組名為``a''。 下列:
centers = ndimage.minimum_filter(a, 3, mode="constant")
將只包含那些數組中包含True框的數組。然后,您可以使用具有默認結構的scipy.ndimage.measurements.label對該框進行分類,並可能識別連接的框。 要找到它們,您可以使用ndimage.measurements.find_objects
編輯:
通過上面的方法,您將正確獲得數組中所有多維數據集的中心。 明確地說,我認為這是您最初的問題的答案。 結果表明,實際上只需要不重疊的多維數據集。 因此,需要分析minimum_filter的輸出,在這里我可以想象很多方法。
每個群集只能使用以下內容獲取一個多維數據集:
s = ndimage.generate_binary_structure(3,3)
labels, num = ndimage.measurements.label(centers, s)
locations = ndimage.measurements.find_objects(labels)
locations = map(lambda slices: [slices[i].start for i in xrange(3)], locations)
現在出現的問題是丟失了不重疊但共享一個面的多維數據集。 實際上,可以想象到非常復雜的非重疊面共享立方體結構。 當然,可以找到針對此問題的幾種解決方案(一組非重疊的多維數據集)。 因此,從發現的中心中選擇一組多維數據集是一項全新的任務,我認為您將必須找到一個最適合您的多維數據集。
一種方法可能是遍歷所有解決方案並將每個找到的多維數據集設置為False:
get_starting_point = numpy.vectorize(lambda sl: sl.start) #to be applied on slices
s = ndimage.generate_binary_structure(3,3)
result = []
while True:
labels, num = ndimage.measurements.label(centers, s)
if not num:
break
locations = ndimage.measurements.find_objects(labels)
sp = get_starting_point(locations)
result.append(sp)
for p in sp:
centers[p[0]-1:p[0]+2, p[1]-1:p[1]+2, p[2]-1:p[2]+2] = False
numiter = len(results)
results = numpy.vstack(results)
我猜只需要很少的迭代。
我希望這就是你想要的
在dnalow的幫助下的最終解決方案
get_starting_point = numpy.vectorize(lambda sl: sl.start)
s = ndimage.generate_binary_structure(3,3)
result = []
while True:
centers = ndimage.minimum_filter(b, 3, mode="constant")
labels, num = ndimage.measurements.label(centers, s)
if not num:
break
locations = ndimage.measurements.find_objects(labels)
sp = get_starting_point(locations)
for p in sp:
if numpy.all(a[p[0]-1:p[0]+2, p[1]-1:p[1]+2, p[2]-1:p[2]+2]):
result.append(p)
b[p[0]-1:p[0]+2, p[1]-1:p[1]+2, p[2]-1:p[2]+2] = False
numiter = len(result)
results = numpy.vstack(result)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.