2009-03-24 16 views
5

Próbuję zaimplementować algorytm wizji, który obejmuje etap wstępnego filtrowania z filtrem 9x9 Laplacian of Gaussian. Czy możesz wskazać dokument wyjaśniający krótko implementacje szybkiego filtra? Myślę, że powinienem użyć FFT do najskuteczniejszego filtrowania.Szybki sposób implementacji splotów 2D w C

Odpowiedz

10

Czy na pewno chcesz użyć FFT? To będzie transformacja w całej tablicy, która będzie kosztowna. Jeśli już zdecydowałeś się na filtr splotu 9x9, nie potrzebujesz żadnego FFT.

Ogólnie rzecz biorąc, najtańszym sposobem wykonania splotu w C jest utworzenie pętli, która przesuwa wskaźnik nad tablicą, sumując sparowane wartości w każdym punkcie i zapisując dane do nowej tablicy. Pętla ta może następnie zostać sparaliżowana za pomocą Twojej ulubionej metody (wektoryzacja kompilacji, biblioteki MPI, OpenMP itd.).

Odnośnie granic:

  • Jeśli założyć, że wartości się 0 poza granicami, a następnie dodać obramowanie 4 elementu wynosi 0 do 2d tablicy punktów. Pozwoli to uniknąć konieczności używania instrukcji `if` do obsługi granic, które są kosztowne.
  • Jeśli twoje dane są zawijane na granicach (tj. Są okresowe), użyj modulo lub dodaj 4-elementową granicę, która kopiuje przeciwną stronę siatki (abcdefg -> fgabcdefgab za 2 punkty). ** Uwaga: to jest to, co domyślnie zakładasz przy jakiejkolwiek transformacji Fouriera, w tym FFT **. Jeśli tak nie jest, musisz to uwzględnić przed wykonaniem FFT.

4 punkty są, ponieważ maksymalne nakładanie się krawędzi jądra 9x9 to 4 punkty poza główną siatką. Tak więc, n punktów granicy potrzebnych do jądra 2n + 1 x 2n + 1.

Jeśli potrzebujesz splotu, aby był naprawdę szybki i/lub twoja siatka jest duża, rozważ podzielenie go na mniejsze części, które mogą być przechowywane w pamięci podręcznej procesora, a tym samym obliczane znacznie szybciej. Dotyczy to również wszelkich wyładowań GPU, które możesz chcieć wykonać (są one idealne do tego typu obliczeń zmiennoprzecinkowych).

+0

Użycie granicy zera zakłada, że ​​dane są dość białe i zerowe. Za pomocą filtru rozmycia na niezerowe średnie dane z granicą zerową mogą spowodować niepożądane zniekształcenia na krawędziach. –

+0

To prawda. Używanie FFT zakłada, że ​​dane są zawijane na granicach, co może być również błędne. Zera miały usunąć drogie ifs. Dodam coś o granicach. –

+0

Jukka zawsze cierpi z powodu granicy.Musisz coś zrobić, żeby to wyjaśnić, a Phil wymienia parę tradycyjnych metod. Jedynym sposobem, aby nie cierpieć z powodu granicy, jest wykonanie splotu 2d, a następnie przycięcie o 4 piksele na wszystkich bokach obrazu. –

2

Oto link teoria http://hebb.mit.edu/courses/9.29/2002/readings/c13-1.pdf

A tu jest link do FFTW, który jest całkiem dobre biblioteki FFT, które użyłem w przeszłości (licencji upewnij się, że jest odpowiednia) http://www.fftw.org/

Wszystko co robisz to FFT twój obraz i jądro (matryca 9x9). Pomnóż razem, a następnie z powrotem przekształć.

Jednak z matrycą 9x9 możesz nadal robić to lepiej w rzeczywistych współrzędnych (wystarczy podwójna pętla nad pikselami obrazu i matrycą). Spróbuj na oba sposoby!

1

W rzeczywistości nie trzeba używać rozmiaru FFT wystarczająco dużego, aby pomieścić cały obraz. Możesz zrobić wiele mniejszych nakładających się uderzeń 2d. Możesz wyszukać "fast convolution" "overlap save" "overlap add".

Jednak dla jądra 9x9. Możesz nie zauważyć dużej przewagi prędkości.