dask trim_internal не восстанавливает размер после map_overlap - PullRequest
0 голосов
/ 22 апреля 2020

Моя цель - применить фильтр к массиву x_in, чтобы получить массив x_out, используя map_overlap и передав фильтр. Кажется, это работает хорошо, и у меня есть куски, которые вытянуты на границах Однако, когда я пытаюсь обрезать границы выходного массива dask, форма отличается от исходного массива. Следуя инструкциям в https://docs.dask.org/en/latest/array-overlap.html#trim -excess с надписью

После сопоставления заблокированной функции, вы можете обрезать границы каждого блока на ту же величину, на которую они были расширены. Функция trim_internal полезна здесь и принимает тот же аргумент глубины, который задан для перекрытия

, но с той же глубиной я получаю гораздо меньший массив, и если я пытаюсь использовать меньшие глубины, массив никогда не будет соответствовать исходной форме.

Чтобы воспроизвести мой тест:

import dask.array as da
from dask_image import ndfilters
from scipy.signal import convolve2d

N = 10
# Initialize an array with zeros and manually add a few 1's
arr = np.zeros((N,N))
arr[2:5,2:5] = 1
# Convert to dask array
x_in = da.from_array(arr, chunks=(5, 5))
# Define filter to apply
n = 2
filt = np.ones((n, n))

x_filtered = x_in.map_overlap(convolve2d, in2=filt, depth={0: n, 1: n},
                              boundary={0: 'periodic', 1: 'periodic'})
x_out = da.overlap.trim_internal(x_filtered,
                                 axes={0: n, 1: n},  
                                 boundary={0: 'periodic', 1: 'periodic'})


print('Input:\n', np.array(x_in),  np.array(x_in).shape)
print('Filtered:\n', np.array(x_filtered),  np.array(x_filtered).shape)
print('Output:\n', np.array(x_out),  np.array(x_out.shape))

, который дает следующие размеры для входных, отфильтрованных и выходных массивов:

Input:
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]] (10, 10)
Filtered:
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 2. 2. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 2. 4. 4. 2. 2. 0. 0. 0. 0. 0.]
 [0. 0. 2. 4. 4. 2. 2. 0. 0. 0. 0. 0.]
 [0. 0. 1. 2. 2. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 2. 2. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]] (12, 12)
Output:
[[1. 2. 0. 0.]
 [2. 4. 0. 0.]
 [0. 0. 0. 0.]
 [0. 0. 0. 0.]] [2 2]

Я также пробовал другие комбинации с map_blocks.

Мой вопрос, в частности, как мне обрезать x_filtered, чтобы выход x_out имел такой же размер, как и вход x_in?

Ожидаемое поведение, непосредственно с numpy scipy

import numpy as np
from scipy.signal import convolve2d

N = 10
n = 2
x_in = np.zeros((N,N))
x_in[2:5,2:5] = 1
print('Input:\n',x_in, x_in.shape)
x_out = convolve2d(x_in, np.ones((n, n)), mode='same', boundary='wrap') 
print('Output:\n',x_out, x_out.shape)

В результате этого ввода и вывода:

Input:
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 1. 1. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]] (10, 10)
Output:
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 2. 2. 1. 0. 0. 0. 0.]
 [0. 0. 2. 4. 4. 2. 0. 0. 0. 0.]
 [0. 0. 2. 4. 4. 2. 0. 0. 0. 0.]
 [0. 0. 1. 2. 2. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]] (10, 10)
...