J'ai essayé de "lisser" l'image avec Python + OpenCV

introduction

Le traitement d'image ne fournit pas toujours de belles images. Il est souvent peu clair ou bruyant. S'il y a du bruit, il peut être supprimé à l'aide d'une technique appelée lissage. Vous pouvez également créer intentionnellement une image floue et l'utiliser comme données factices.

Cette fois, nous utiliserons Python pour lisser l'image avec OpenCV.

Qu'est-ce que le lissage?

Le lissage, ou lissage, consiste simplement à ** rendre l'image floue **. On peut également dire que le flou de l'image adoucit le changement de valeur de pixel. Le bruit et les bords sont des changements soudains des valeurs de pixels. Le lissage peut éliminer ou rendre les bords moins visibles.

Préparation

L'environnement utilise Google Colaboratory. La version Python est ci-dessous.

import platform
print("python " + platform.python_version())
# python 3.6.9

Montrons l'image

Maintenant écrivons le code. Tout d'abord, importez OpenCV.

import cv2

De plus, importez les éléments suivants pour afficher l'image dans Colaboratory.

from google.colab.patches import cv2_imshow

Préparez également un exemple d'image. Cette fois, j'utiliserai l'image gratuite de Pixabay.

Maintenant, affichons l'exemple d'image préparé.

img = cv2.imread(path) #chemin spécifie où l'image est placée
cv2_imshow(img)

image.png

Préparez également une image avec du bruit pour en avoir besoin plus tard. Ici, ajoutons un bruit appelé "bruit de sel et de poivre" (également appelé bruit de sel de sésame) à l'image.

# salt-and-pepper noise
#Voir ci-dessous pour le code
# https://lp-tech.net/articles/nCvfb?page=2
import numpy as np

row, col, ch = img.shape
img_sp = cv2.imread(path)
# salt
pts_x = np.random.randint(0, col-1 , 1000)
pts_y = np.random.randint(0, row-1 , 1000)
img_sp[(pts_y,pts_x)] = (255, 255, 255)
# pepper
pts_x = np.random.randint(0, col-1 , 1000)
pts_y = np.random.randint(0, row-1 , 1000)
img_sp[(pts_y, pts_x)] = (0, 0, 0)
cv2_imshow(img_sp)

image.png

Lissage

Lissage général

Le lissage est simplement brouiller l'image. Le moyen le plus simple de lisser une image avec OpenCV est d'utiliser cv2.blur. Ici, flou signifie «flou».

Maintenant, affichons l'image lissée. Je vais l'afficher côte à côte avec l'image originale.

img_blur = cv2.blur(img, (3, 3))
imgs = cv2.hconcat([img, img_blur])
cv2_imshow(imgs)

image.png

La gauche est l'image d'origine et la droite est l'image lissée. Vous pouvez voir que la bonne est un peu floue.

Il existe deux arguments pour cv2.blur. Le premier est l'image d'entrée. Le second s'appelle le noyau. Lorsqu'un point de l'image est décidé, cela montre combien de zone autour d'elle est incluse. Pensez-y comme à la taille d'une boîte.

Dans l'exemple ci-dessus, il s'agit de (3, 3), ce qui signifie qu'il cible une zone 3x3 centrée sur un point de l'image. Dans cv2.blur, qui est un lissage général, l'intérieur du noyau est rempli avec la valeur moyenne des pixels de ce noyau. Plus la taille du noyau est grande, plus l'image est floue.

Affiche une image avec différentes tailles de noyau modifiées.

img1 = cv2.blur(img, (1, 1))
img2 = cv2.blur(img, (2, 2))
img3 = cv2.blur(img, (3, 3))
img4 = cv2.blur(img, (4, 4))
img5 = cv2.blur(img, (5, 5))
img6 = cv2.blur(img, (6, 6))

imgs_1 = cv2.hconcat([img1, img2, img3])
imgs_2 = cv2.hconcat([img4, img5, img6])
imgs = cv2.vconcat([imgs_1, imgs_2])
cv2_imshow(imgs)

image.png

En haut à gauche, l'image sera celle avec la taille du noyau augmentée. Vous pouvez voir que le flou de l'image devient de plus en plus fort.

Filtre gaussien

En plus du lissage général, OpenCV permet certains processus de lissage.

Ensuite, je présenterai un filtre gaussien. Dans le lissage général, les pixels du noyau sont remplis d'une valeur fixe appelée valeur moyenne. Pour les filtres gaussiens, la valeur change en fonction de la distance par rapport au centre du noyau. La valeur est la plus élevée au centre et diminue à mesure que la distance augmente. Il est appelé filtre gaussien car il suit une fonction appelée fonction gaussienne. La formule de la fonction gaussienne est:

\frac{1}{\sqrt{2\pi\sigma^2}}\exp\Bigl(-\frac{x^2}{2\sigma^2}\Bigr) \\

De plus, le graphique de la fonction de Gauss est le suivant.

image.png

Maintenant, lissons l'image avec un filtre gaussien. Je vais également l'afficher côte à côte avec l'image originale.

img_gauss = cv2.GaussianBlur(img, (3, 3), 3)
imgs = cv2.hconcat([img, img_gauss])
cv2_imshow(imgs)

image.png

cv2.GaussianBlur a trois arguments. Les deux premiers sont l'image d'entrée et la taille du noyau, similaire à cv2.blur. Le troisième argument correspond à la fonction gaussienne $ \ sigma $. Si $ \ sigma $ est petit, le pic sera plus élevé mais l'écart sera plus étroit. Inversement, plus $ \ sigma $ est grand, plus le spread est grand, mais plus le pic est bas.

filtre médian

Ensuite, je présenterai le filtre médian. median est la "valeur médiane", qui prend la valeur médiane des pixels contenus dans le noyau spécifié et remplit tout le noyau avec cette valeur. La différence avec le lissage général est qu'il utilise toujours des valeurs de pixels existantes, et non des valeurs de pixels moyennées.

Comparons l'image en utilisant le filtre médian avec l'image d'origine.

img_med = cv2.medianBlur(img, 3)
imgs = cv2.hconcat([img, img_med])
cv2_imshow(imgs)

image.png

cv2.medianBlur a deux arguments, l'image d'entrée et la taille du noyau. Dans ce qui précède, le deuxième argument est 3, ce qui représente un noyau 3x3.

Ce filtre médian est très utile pour éliminer les bruits de sel et de poivre. En fait, le résultat de l'application du filtre médian à l'image bruyante est le suivant.

image.png

Vous pouvez voir qu'il a été supprimé proprement.

filtre bilatéral

Enfin, je voudrais introduire un filtre bilatéral.

Bilatéral signifie «les deux sont», mais ce filtre peut bien laisser des bords. Jusqu'à présent, les filtres de lissage ont des pics flous tels que des bords. Le filtre bilatéral est un filtre pratique qui vous permet de rendre l'image floue tout en laissant les bords. Sortons-le avec l'image d'origine.

img_bi = cv2.bilateralFilter(img, 9, 75, 75)
imgs = cv2.hconcat([img, img_bi])
cv2_imshow(imgs)

image.png

Vous pouvez voir que les bords sont laissés fermement même s'ils sont globalement lisses.

Je vais omettre les détails de l'argument de cv2.bilateralFilter. Veuillez vous référer au document officiel d'OpenCV.

Résumé

Cette fois, j'ai utilisé Python pour lisser l'image avec OpenCV.

Si votre traitement d'image nécessite une suppression du bruit, essayez de lisser.

Pour plus de détails sur le lissage, reportez-vous à ce qui suit.

Recommended Posts

J'ai essayé de "lisser" l'image avec Python + OpenCV
J'ai essayé de "différencier" l'image avec Python + OpenCV
J'ai essayé de "binariser" l'image avec Python + OpenCV
J'ai essayé la "correction gamma" de l'image avec Python + OpenCV
[OpenCV / Python] J'ai essayé l'analyse d'image de cellules avec OpenCV
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé le rendu non réaliste avec Python + opencv
J'ai essayé de jouer avec l'image avec Pillow
J'ai essayé de traiter l'image en "style croquis" avec OpenCV
J'ai essayé de traiter l'image dans un "style de dessin au crayon" avec OpenCV
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé d'utiliser le filtre d'image d'OpenCV
J'ai essayé fp-growth avec python
J'ai essayé de gratter avec Python
Édition d'image avec python OpenCV
J'ai essayé gRPC avec Python
J'ai essayé de gratter avec du python
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé de résoudre le problème avec Python Vol.1
Python Open CV a essayé d'afficher l'image sous forme de texte.
J'ai essayé la "conversion de morphologie" de l'image avec Python + OpenCV
J'ai essayé de frapper l'API avec le client python d'echonest
[Python] Utilisation d'OpenCV avec Python (filtrage d'image)
[Python] Utilisation d'OpenCV avec Python (transformation d'image)
J'ai essayé webScraping avec python.
J'ai aimé le tweet avec python. ..
Trouver la similitude d'image avec Python + OpenCV
Essayez de brouiller l'image avec opencv2
J'ai essayé d'exécuter prolog avec python 3.8.2.
J'ai essayé la communication SMTP avec Python
J'ai essayé la reconnaissance faciale avec OpenCV
J'ai essayé de simuler la propagation de l'infection avec Python
J'ai essayé d'utiliser la bibliothèque Python de Ruby avec PyCall
J'ai essayé de reconnaître le visage de la vidéo (OpenCV: version python)
Traitement d'image avec Python et OpenCV [Tone Curve]
Acquisition d'images depuis une caméra avec Python + OpenCV
J'ai essayé un langage fonctionnel avec Python
J'ai essayé la récurrence avec Python ② (séquence de nombres Fibonatch)
Python: j'ai essayé le problème du voyageur de commerce
J'ai essayé la reconnaissance d'image simple avec Jupyter
Traitement d'image léger avec Python x OpenCV
Lissage des bords enregistrés avec python + OpenCV (BilateralFilter, NLMeansFilter)
J'ai essayé le framework de test Python Tornado
# J'ai essayé quelque chose comme Vlookup avec Python # 2
J'ai essayé de gratter le classement du calendrier de l'avent Qiita avec Python
J'ai essayé de résoudre l'édition du débutant du livre des fourmis avec python
J'ai essayé d'afficher le temps de lecture de la vidéo (OpenCV: version Python)
Je viens d'effacer l'objet en utilisant la réparation d'image (inpaint) (OpenCV: Python)
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
[Python] J'ai essayé de visualiser la nuit du chemin de fer de la galaxie avec WordCloud!
J'ai essayé des centaines de millions de SQLite avec python
[Python] J'ai essayé de remplacer le nom de la fonction par le nom de la fonction
J'ai essayé la reconnaissance d'image de CIFAR-10 avec Keras-Learning-
vprof - J'ai essayé d'utiliser le profileur pour Python
Comment couper la partie inférieure droite de l'image avec Python OpenCV