Une image lissée et floue peut être obtenue en faisant la moyenne des valeurs de pixel autour du pixel d'intérêt dans l'image en utilisant le filtre suivant.
\left(
\begin{matrix}
1/9 & 1/9 & 1/9 \\
1/9 & 1/9 & 1/9 \\
1/9 & 1/9 & 1/9
\end{matrix}
\right)
Cependant, cela rend l'image globalement floue, de sorte que les bords sont également flous. Si vous souhaitez conserver les bords mais également réduire le bruit, utilisez un filtre pour cela.
La moyenne pondérée ne consiste pas simplement à calculer la moyenne des valeurs de pixel autour du pixel d'intérêt, mais reflète surtout ce qui est proche du pixel d'intérêt. Ensuite, quand il s'agit de distribuer les poids, le filtre gaussien dit qu'il doit être distribué selon la distribution normale. La distribution gaussienne de moyenne 0 et de dispersion ρ s'exprime comme suit.
\frac{1}{ \sqrt{2 \pi \sigma}} \exp
\begin{pmatrix}
-
\frac{x^2}{2\sigma ^ 2}
\end{pmatrix}
Ce sera une dimension, donc si vous l'étendez à deux dimensions
\frac{1}{ 2 \pi \sigma ^2} \exp
\begin{pmatrix}
-
\frac{x^2 + y ^2}{2\sigma ^ 2}
\end{pmatrix}
Le filtre gaussien pondère la distance entre le pixel remarquable et le pixel périphérique approché par la fonction gaussienne, mais le filtre bilatéral pondère également la différence entre les valeurs de pixel du pixel remarquable et le pixel périphérique avec la fonction gaussienne. ing. Si la différence de valeur de pixel par rapport au pixel d'intérêt est faible (= teinte et luminosité similaires), le poids est grand, et si la différence de valeur de pixel par rapport au pixel d'intérêt est grande, le poids est petit. Si l'image d'entrée est f (i, j) et la sortie est g (i, j)
g(i,j) =
\frac{ \sum_{n=-w}^{w} \sum_{m=-w}^{w} w(i,j,m,n) f(i+m, j+n) }
{\sum_{n=-w}^{w} \sum_{m=-w}^{w} w(i,j,m,n)}
w(i,j,m,n) = \exp
\begin{pmatrix}
- \frac{m^2 + n^2}{2 \sigma_{1}^2}
\end{pmatrix}
\exp
\begin{pmatrix}
- \frac{(f(i,j)-f(i+m, j+n))^2}
{2 \sigma_{2}^2}
\end{pmatrix}
Cela devient une formule ridicule. La pondération de la distance entre le pixel d'attention et le pixel périphérique est représentée par l'exp dans la première moitié de la formule concernant w, et la différence entre les valeurs de pixel du pixel d'attention et le pixel cible de calcul est représentée par l'exp dans la seconde moitié de la formule concernant w. C'est un filtre pour la moyenne, mais w n'est pas configuré pour ajouter jusqu'à 1, vous avez donc besoin d'un dénominateur pour additionner toutes les valeurs du noyau pour obtenir 1.
Référence: http://imagingsolution.net/imaging/bilateralfilter/
cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]]) → dst
http://docs.opencv.org/3.0-last-rst/modules/imgproc/doc/filtering.html?highlight=laplacian#bilateralfilter
--src: Image d'entrée --d: zone utilisée pour brouiller le pixel d'intérêt --sigmaColor: écart type de la couleur. S'il est important, un poids important est adopté même si la différence des valeurs de pixel est grande. --sigmaSpace: écart type de la distance. S'il est important, un poids important est adopté même si la distance entre les pixels est large.
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('images.jpg', cv2.IMREAD_COLOR)
bi = cv2.bilateralFilter(img, 15, 20, 20)
bi2 = cv2.bilateralFilter(bi, 15, 20, 20)
bi3 = cv2.bilateralFilter(bi2, 15, 20, 20)
plt.subplot(2,2,1),plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title("original")
plt.xticks([]),plt.yticks([])
plt.subplot(2,2,2),plt.imshow(cv2.cvtColor(bi, cv2.COLOR_BGR2RGB))
plt.title("bi")
plt.xticks([]),plt.yticks([])
plt.subplot(2,2,3),plt.imshow(cv2.cvtColor(bi2, cv2.COLOR_BGR2RGB))
plt.title("bi2")
plt.xticks([]),plt.yticks([])
plt.subplot(2,2,4),plt.imshow(cv2.cvtColor(bi3, cv2.COLOR_BGR2RGB))
plt.title("bi3")
plt.xticks([]),plt.yticks([])
plt.show()
Le résultat du filtrage plusieurs fois. Après l'avoir appliqué trois fois, la chose semblable au bruit disparaît, mais la chose semblable à un pseudo-contour apparaît. L'image était peut-être un peu mauvaise ...
Ceci est une image avec presque aucun bruit filtré. Au fur et à mesure que le nombre de fois augmente, le pseudo-contour est accentué et ressemble davantage à une illustration.
Les pondérations du filtre bilatéral en fonction de la différence entre la valeur de pixel du pixel d'intérêt et la valeur de pixel du pixel périphérique, mais dans le filtre moyen non local, la zone comprenant le pixel périphérique est la zone périphérique du pixel d'intérêt comme la correspondance de modèle. Le poids est déterminé par leur similitude.
L'explication avec des images concrètes est facile à comprendre ici. http://opencv.jp/opencv2-x-samples/non-local-means-filter
la cérémonie
w(i,j,m,n) = \exp
\begin{pmatrix}
\frac{
\sum_{t=-w}^{w} \sum_{s=-w}^{w} (f(i+s,j+t) -f(i+m+s, j+n+t))^2
}
{}
\end{pmatrix}
Peut être appliqué à g (i, j) dans l'équation ci-dessus. Il semble que la zone autour du pixel d'intérêt et la zone autour des pixels périphériques sont similaires, mais honnêtement, je ne comprends pas le sens de la formule ...
cv2.fastNlMeansDenoisingColored(src[, dst[, h[, hColor[, templateWindowSize[, searchWindowSize]]]]])
http://docs.opencv.org/3.0-beta/modules/photo/doc/denoising.html
--src: Image d'entrée (couleur) --templateWindowSize: Taille du modèle de zone périphérique --searchWindowSize: taille de la zone pour rechercher des poids --h: Le degré de lissage du filtre du composant de luminosité, s'il est grand, le bruit diminuera, mais il affectera également la partie de bord.
--hColor: Le degré de lissage du filtre de composant de couleur, 10 suffit
Référence: http://ishidate.my.coocan.jp/opencv310_6/opencv310_6.htm
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('images.jpg', cv2.IMREAD_COLOR)
dst = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21)
plt.subplot(2,1,1),plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title("original")
plt.xticks([]),plt.yticks([])
plt.subplot(2,1,2),plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
plt.title("NLMeans")
Un seul coup peut réduire considérablement le bruit.
Recommended Posts