Ответ 1
Существует несколько способов сделать это с помощью scipy
, но 2D свертка напрямую не включена в numpy
. (Это также легко реализовать с помощью fft, используя только numpy, если вам нужно избегать скудной зависимости.)
scipy.signal.convolve2d
, scipy.signal.convolve
, scipy.signal.fftconvolve
и scipy.ndimage.convolve
будут обрабатывать 2D-свертку (последние три - N-d) по-разному.
scipy.signal.fftconvolve
выполняется свертка в fft-области (где это простое умножение). Это намного быстрее во многих случаях, но может привести к очень небольшим различиям в краевых эффектах, чем к дискретному случаю, и ваши данные будут принудительно введены в плавающие точки с этой конкретной реализацией. Кроме того, ненужное использование памяти при свертывании небольшого массива с гораздо большим массивом. В целом, методы на основе fft могут быть значительно быстрее, но существуют некоторые распространенные случаи использования, когда scipy.signal.fftconvolve
не является идеальным решением.
scipy.signal.convolve2d
, scipy.signal.convolve
и scipy.ndimage.convolve
все используют дискретную свертку, реализованную на C, однако они реализуют ее по-разному.
scipy.ndimage.convolve
сохраняет один и тот же тип данных и дает вам контроль над местоположением вывода для минимизации использования памяти. Если вы свертываете uint8
(например, данные изображения), это часто лучший вариант. Выход всегда будет иметь ту же форму, что и первый входной массив, что имеет смысл для изображений, но, возможно, не для более общей свертки. ndimage.convolve
дает вам большой контроль над обработкой краевых эффектов с помощью mode
kwarg (который работает совершенно иначе, чем scipy.signal
mode
kwarg).
Избегайте scipy.signal.convolve
, если вы работаете с массивами 2d. Он работает для случая N-d, но он субоптимален для 2d-массивов, а scipy.signal.convolve2d
существует, чтобы сделать то же самое более эффективно. Функции свертки в scipy.signal
дают вам контроль над формой вывода с помощью mode
kwarg. (По умолчанию они будут вести себя точно так же, как matlab conv2
.) Это полезно для общей математической свертки, но менее полезно для обработки изображений. Однако scipy.signal.convolve2d
обычно медленнее, чем scipy.ndimage.convolve
.
Есть много разных вариантов, частично из-за дублирования в разных подмодулях scipy
и отчасти потому, что существуют различные способы реализации свертки, которые имеют разные компромиссы производительности.
Если вы можете немного подробнее рассказать о своем прецеденте, мы можем рекомендовать лучшее решение. Если вы свертываете два массива примерно того же размера, и они уже плавают, fftconvolve
- отличный выбор. В противном случае scipy.ndimage.convolve
может побить его.