2D-свертка и корреляция на основе БПФ в Python - PullRequest
21 голосов
/ 08 июля 2009

Есть ли в Scipy (или другой популярной библиотеке) встроенная в БПФ 2D-функция взаимной корреляции или свертки?

Есть такие функции:

  • scipy.signal.correlate2d - "прямой метод, реализованный convolveND, будет медленно для больших данных "
  • scipy.ndimage.correlate - "Массив коррелируется с данным ядром, используя точный расчет (т. е. не БПФ). "
  • scipy.fftpack.convolve.convolve, что я не совсем понимаю, но, похоже, неправильно

у numarray была функция correlate2d() с переключателем fft=True , но я думаю, что numarray был свернут в NumPy, и я не могу найти, если эта функция была включена.

Ответы [ 5 ]

20 голосов
/ 20 ноября 2009

Я нашел scipy.signal.fftconvolve, , на что также указал магнус , но в то время не осознавал, что он n -мерен. Поскольку он встроен и выдает правильные значения, он кажется идеальным решением.

С Пример 2D свертки :

In [1]: a = asarray([[ 1, 2, 3],
   ...:              [ 4, 5, 6],
   ...:              [ 7, 8, 9]])

In [2]: b = asarray([[-1,-2,-1],
   ...:              [ 0, 0, 0],
   ...:              [ 1, 2, 1]])

In [3]: scipy.signal.fftconvolve(a, b, mode = 'same')
Out[3]: 
array([[-13., -20., -17.],
       [-18., -24., -18.],
       [ 13.,  20.,  17.]])

Правильно! Версия STSCI, с другой стороны, требует дополнительной работы, чтобы сделать границы правильными?

In [4]: stsci.convolve2d(a, b, fft = True)
Out[4]: 
array([[-12., -12., -12.],
       [-24., -24., -24.],
       [-12., -12., -12.]])

(Метод STSCI также требует компиляции, с которой у меня не получилось (я только что закомментировал части, не относящиеся к Python), есть некоторые ошибки вроде this и изменение входных данных ([1, 2] становится [[1, 2]]) и т. Д. Поэтому я изменил свой принятый ответ на встроенную функцию fftconvolve().)

Корреляция, конечно, то же самое, что свертка, но с одним обратным входом:

In [5]: a
Out[5]: 
array([[3, 0, 0],
       [2, 0, 0],
       [1, 0, 0]])

In [6]: b
Out[6]: 
array([[3, 2, 1],
       [0, 0, 0],
       [0, 0, 0]])

In [7]: scipy.signal.fftconvolve(a, b[::-1, ::-1])
Out[7]: 
array([[ 0., -0.,  0.,  0.,  0.],
       [ 0., -0.,  0.,  0.,  0.],
       [ 3.,  6.,  9.,  0.,  0.],
       [ 2.,  4.,  6.,  0.,  0.],
       [ 1.,  2.,  3.,  0.,  0.]])

In [8]: scipy.signal.correlate2d(a, b)
Out[8]: 
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [3, 6, 9, 0, 0],
       [2, 4, 6, 0, 0],
       [1, 2, 3, 0, 0]])

и последняя версия была ускорена благодаря внутреннему использованию размеров двух степеней (а затем я увеличил ее на , используя реальное БПФ для реального ввода и использование 5-гладких длин вместо степеней 2 : D).

6 голосов
/ 25 сентября 2009

посмотрите на scipy.signal.fftconvolve, signal.convolve и signal.correlate (есть сигнал.correlate2d, но, похоже, он возвращает смещенный массив, не центрированный).

4 голосов
/ 09 июля 2009

Я думаю, вам нужен пакет scipy.stsci:

http://docs.scipy.org/doc/scipy/reference/stsci.html

In [30]: scipy.__version__
Out[30]: '0.7.0'

In [31]: from scipy.stsci.convolve import convolve2d, correlate2d
2 голосов
/ 10 декабря 2011

Я написал оболочку для перекрестной корреляции / свертки, которая заботится о padding & nans и включает в себя простую гладкую оболочку здесь . Это не популярный пакет, но он также не имеет зависимостей, кроме numpy (или fftw для более быстрых ffts).

Я также реализовал код тестирования скорости FFT здесь на случай, если кому-то будет интересно. Удивительно, но это говорит о том, что БПФ numpy быстрее, чем у Сципи, по крайней мере, на моей машине.

РЕДАКТИРОВАТЬ: перемещенный код в N-мерную версию здесь

2 голосов
/ 09 июля 2009

В scipy я потерял статус этого пакета, но я знаю, что для удобства пользователей мы включили ndimage в пакет выпуска stsci_python:

http://www.stsci.edu/resources/software_hardware/pyraf/stsci_python/current/download

или вы можете извлечь его из хранилища, если предпочитаете:

https://www.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/ndimage/

...