Flou gaussien - écart type, rayon et taille du noyau


19

J'ai implémenté un shader de fragment de flou gaussien dans GLSL. Je comprends les principaux concepts derrière tout cela: convolution, séparation de x et y en utilisant la linéarité, plusieurs passes pour augmenter le rayon ...

J'ai encore quelques questions:

  • Quelle est la relation entre sigma et radius?

    J'ai lu que sigma est équivalent à radius, je ne vois pas comment sigma est exprimé en pixels. Ou "rayon" n'est-il qu'un nom pour sigma, sans rapport avec les pixels?

  • Comment choisir sigma?

    Étant donné que j'utilise plusieurs passes pour augmenter le sigma, comment choisir un bon sigma pour obtenir le sigma que je veux à un passage donné? Si le sigma résultant est égal à la racine carrée de la somme des carrés des sigmas et que sigma est équivalent au rayon, quel est un moyen facile d'obtenir le rayon souhaité?

  • Quelle est la bonne taille d'un noyau et comment est-elle liée à Sigma?

    J'ai vu la plupart des implémentations utiliser un noyau 5x5. C'est probablement un bon choix pour une implémentation rapide avec une qualité décente, mais y a-t-il une autre raison de choisir une autre taille de noyau? Quel est le lien entre sigma et la taille du noyau? Dois-je trouver le meilleur sigma pour que les coefficients en dehors de mon noyau soient négligeables et se normalisent juste?

Réponses:


21

Quelle est la relation entre sigma et radius? J'ai lu que sigma est équivalent à radius, je ne vois pas comment sigma est exprimé en pixels. Ou "rayon" n'est-il qu'un nom pour sigma, sans rapport avec les pixels?

Il y a trois choses en jeu ici. La variance, ( σ2 ), le rayon et le nombre de pixels. Comme il s'agit d'une fonction gaussienne bidimensionnelle, il est logique de parler de la matrice de covariance place. Quoi qu'il en soit cependant, ces trois concepts sont faiblement liés.Σ

Tout d'abord, le gaussien 2D est donné par l'équation:

g(z)=1(2π)2|Σ|e-12(z-μ)TΣ-1 (z-μ)

Où est un vecteur de colonne contenant les coordonnées et dans votre image. Alors, , et est un vecteur de colonne codifiant la moyenne de votre fonction gaussienne, dans le et directions . x y z = [ x y ] μ x y μ = [ μ x μ y ]zXyz=[Xy]μXyμ=[μXμy]

Exemple:

Maintenant, disons que nous définissons la matrice de covariance , et . Je définirai également le nombre de pixels à x . De plus, ma «grille», où j'évalue ce PDF, va passer de à , en et . Cela signifie que j'ai une résolution de grille de . Mais c'est complètement arbitraire. Avec ces paramètres, j'obtiendrai l'image de la fonction de densité de probabilité sur la gauche. Maintenant, si je change la «variance», (vraiment, la covariance), telle queΣ=[1001]μ=[00]100100-dixdixXydix-(-dix)100=0,2Σ=[9009] et garder tout le reste identique, je reçois l'image à droite.

entrez la description de l'image ici

1001002020-dixdixdix-(-dix)20=1

entrez la description de l'image ici

Voilà comment vous devez comprendre l'interaction entre ces variables. Si vous souhaitez le code, je peux également le poster ici.

Comment choisir sigma?

Le choix de la matrice de variance / covariance de votre filtre gaussien dépend fortement de l'application. Il n'y a pas de «bonne» réponse. C'est comme demander quelle bande passante doit-on choisir pour un filtre. Encore une fois, cela dépend de votre application. En règle générale, vous souhaitez choisir un filtre gaussien de telle sorte que vous supprimez une quantité considérable de composants haute fréquence dans votre image. Une chose que vous pouvez faire pour obtenir une bonne mesure est de calculer la DFT 2D de votre image et de superposer ses coefficients avec votre image gaussienne 2D. Cela vous indiquera quels coefficients sont lourdement pénalisés.

Par exemple, si votre image gaussienne a une covariance si large qu'elle englobe de nombreux coefficients haute fréquence de votre image, vous devez alors réduire ses éléments de covariance.


1
Ces images seraient mieux si elles utilisaient une palette de couleurs séquentielle. le jet est le pire.
endolith

@endolith "Better" dépend de l'application. Je n'utilise pas de jet lorsqu'une discrimination visuelle du contraste est nécessaire. (Chaud c'est mieux). Ici cependant, le message est à la taille du gaussien, donc pas de mal fait avec le jet. Merci pour le lien cependant.
Tarin Ziyaee

2
C'est une réponse bien pensée et vraiment bien visualisée! Prenez cette image en haut à gauche, par exemple. Il est clair que cette combinaison de variance et de taille de noyau serait un gaspillage, car il s'agit d'un noyau 100x100 où seul le centre 30x30 (~ 9%) est non nul.
Adam Smith

5

Le paramètre sigma suffit pour définir le flou gaussien d'un point de vue continu. En pratique cependant, les images et les noyaux de convolution sont discrets. Comment choisir une approximation discrète optimale du noyau gaussien continu?

L'approximation discrète sera plus proche du noyau gaussien continu lors de l'utilisation d'un plus grand rayon. Mais cela peut se faire au prix d'une durée de calcul supplémentaire.

Idéalement, on devrait sélectionner une valeur pour sigma, puis calculer un rayon qui permet de représenter fidèlement le noyau gaussien continu correspondant. Pour une erreur d'approximation donnée, plus le sigma est grand, plus le rayon doit être grand.

Fait intéressant, cela peut devenir très compliqué pour bien faire les choses. Lors de la construction de la matrice gaussienne, est-ce la meilleure solution pour échantillonner le noyau continu ou existe-t-il de meilleures approximations? Comment normaliser le noyau discret calculé pour tenir compte de la troncature? etc.

À titre de référence, dans Mathematica, la fonction GaussianMatrix propose plusieurs façons de calculer une matrice discrète gaussienne, par exemple en utilisant une approximation de Bessel discrète. Par défaut, radius = 2 * sigma, ce qui signifie qu'avec sigma = 1, la matrice sera 5x5.


C'est une question assez ancienne. Mais un rayon de 2 * sigma ne résulterait-il pas en une matrice de 9x9?
Delusional Logic

@DelusionalLogic avec sigma = 1, radius = 2, donc la matrice aura une taille 4 mais a besoin d'une taille impaire donc une taille 5x5. Du moins, c'est comme ça que je le comprends ..
Micka

Si le rayon est de 2, le voisinage étend le pixel central de 2 pixels à gauche, 2 à droite, etc. C'est juste la convention que Mathematica utilise.
Matthias Odisio

2

Il s'avère que les lignes du triangle de Pascal se rapprochent assez bien d'une gaussienne et ont l'avantage pratique d'avoir des valeurs entières dont la somme est une puissance de 2 (nous pouvons stocker ces valeurs exactement comme des entiers, des valeurs à virgule fixe ou des flottants). Par exemple, disons que nous souhaitons construire un noyau gaussien 7x7, nous pouvons le faire en utilisant la 7ème ligne du triangle de Pascal comme suit:

entrez la description de l'image ici

Notez que ce filtre a l'influence minimale aux coins tout en restant entier. Vous pouvez utiliser la valeur moyenne 20/64 pour déterminer le sigma d'écart type correspondant qui est 64 / (20 * sqrt (2 * pi)) = 1,276 pour le gaussien approximatif dans ce cas. Vous pouvez représenter graphiquement le gaussien pour voir qu'il s'agit d'un excellent ajustement.

Donc, un bon point de départ pour déterminer un écart-type raisonnable pour un noyau gaussien vient du triangle de Pascal (alias coefficients binomiaux ) - pour un filtre (N + 1) x (N + 1) correspondant à l'utilisation de construction ci-dessus

entrez la description de l'image ici

GaussianMatrix [3] de Wolfram Alpha utilise juste r / 2 = 1,5. Curieusement, GaussianMatrix [{3,1.276}] ne produit pas le même filtre 2D que le mien et n'est pas le suivant pour x, y entre -3 et 3:

entrez la description de l'image ici

Je ne sais pas pourquoi pas? Mon filtre 2D est un excellent ajustement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.