Quel est le moyen le plus efficace d'implémenter un filtre de convolution dans un pixel shader?
La mise en œuvre de convolution dans un pixel shader est un peu plus onéreuse que le nombre très élevé de récupérations de texture.
Une façon directe de la mise en œuvre d'un filtre de convolution est de faire N x N recherches par fragment à l'aide de deux cycles par fragment. Un simple calcul indique qu'une image de 1024x1024 floue avec un 4x4 noyau Gaussien aurait besoin 1024 x 1024 x 4 x 4 = 16M
recherches.
Que peut-on faire à ce sujet?
- Peut-on utiliser certains d'optimisation qui aurait besoin de moins de recherches? Je ne suis pas intéressé dans le noyau optimisations spécifiques comme ceux de la Gaussienne (ou sont-ils noyau spécifique?)
- Peut-on au moins faire ces recherches plus rapidement en quelque sorte l'exploitation de la localité de pixels personne pour travailler avec?
Merci!
source d'informationauteur Albus Dumbledore
Vous devez vous connecter pour publier un commentaire.
Noyaux gaussiens sont séparables, ce qui signifie que vous pouvez faire une horizontale passer d'abord, puis un vertical passer (ou l'inverse). Qui tourne en O(N^2) en O(2N). Qui fonctionne pour tous les filtres séparables, et pas seulement pour le flou (pas tous filtres sont séparables, mais ils sont nombreux, et certains sont "aussi bien que").
Ou,dans le cas particulier d'un filtre de flou (Gauss ou pas), qui sont toutes sorte de "somme pondérée", vous pouvez profiter de la texture d'interpolation, ce qui peut être plus rapide pour le petit noyau tailles (mais définitivement pas pour les gros noyau tailles).
EDIT: l'image de la "interpolation linéaire" méthode
MODIFIER (comme demandé par Jerry Cercueil) pour résumer les commentaires:
Dans le "filtre de texture" méthode de l'interpolation linéaire de produire une somme pondérée des adjacente texels en fonction de l'inverse de la distance à partir de l'échantillon, l'emplacement du texel centre. Ceci est fait par la texture du matériel, pour gratuit. De cette façon, 16 pixels, peut être résumée en 4 extrait. Filtrage de Texture peuvent être exploitées en plus de séparer le noyau.
Dans l'exemple de l'image, en haut à gauche, votre échantillon (le cercle) frappe le centre de texel. Ce que vous obtenez est le même que le "plus proche" de filtrage, vous obtenez ce que texel de la valeur. En haut à droite, vous êtes dans le milieu entre deux texels, ce que vous obtenez est le 50/50 moyenne entre eux (représenté par le plus léger shader de bleu). En bas à droite, vous goûtez entre 4 texels, mais un peu plus vers le haut à gauche. Qui vous donne une moyenne pondérée de tous les 4, mais avec le poids biaisée vers le haut à gauche (le plus sombre de l'ombre de bleu).
Les suggestions suivantes sont une gracieuseté de la datenwolf (voir ci-dessous):
"Un autre méthodes que je voudrais suggérer, c'est de l'exploitation dans l'espace de fourier, où la convolution se transforme en un simple produit de la transformée de fourier du signal et de la transformée de fourier du noyau. Bien que la transformée de fourier sur le GPU lui-même est assez fastidieux à mettre en œuvre, au moins en utilisant des shaders OpenGL. Mais c'est assez facile à faire en OpenCL. En fait je mettre en œuvre de telles choses avec OpenCL, maintenant, beaucoup de traitement d'image dans mon moteur 3D qui se passe dans OpenCL.
OpenCL a été conçu spécifiquement pour la course sur les Gpu. Une transformée de Fourier Rapide est en fait le morceau de code en exemple sur la page Wikipedia OpenCL article: en.wikipedia.org/wiki/OpenCL et oui, le gain de performance est énorme. Une FFT exécute avec au plus O(n log n), l'inverse même. Le filtre à noyau de fourier de la représentation peuvent être précalculées. La voie est à la FFT -> multiplier avec le noyau -> IFFT, ce qui revient à O(n + 2n log n) opérations. Prenez en note le produit de convolution est seulement O(n).
Dans le cas d'une séparables, finie la convolution comme un flou gaussien de la séparation de la solution sera mieux que la transformée de fourier de la méthode. Mais en cas de généralisation, de la possible non-séparables les noyaux les méthodes de fourier est probablement la méthode la plus rapide disponible.
OpenCL qui s'intègre bien avec l'OpenGL, par exemple, vous pouvez utiliser OpenGL tampons (des textures et des vertex) pour à la fois d'entrée et de sortie d'OpenCL programmes."
De plus que d'être séparable, Gaussien filtres sont également calculable en O(1) :
Il y a des calculs récursifs comme le Deriche :
http://hal.inria.fr/docs/00/07/47/78/PDF/RR-1893.pdf
Rotoglup la réponse à ma question ici mon être la peine de lire; en particulier, ce blog à propos de flou Gaussien m'a vraiment aidé à comprendre le concept de filtres séparables.