Python de 0 à 1 | Explication détaillée des opérateurs Sobel et Laplacien pour la netteté des images

Cet article est partagé par la communauté Huawei Cloud « [Python de zéro à un] Cinquante-huit. Amélioration et calcul de l'image : netteté de l'image avec les opérateurs Sobel et Laplacien pour réaliser la détection des contours », auteur : eastmount.

1.Opérateur Sobel

L'opérateur Sobel est un opérateur différentiel discret pour la détection des bords, qui combine le lissage gaussien et la dérivation différentielle. Cet opérateur est utilisé pour calculer la valeur approximative de la luminosité de l'image, et en fonction de la luminosité du bord de l'image, un point spécifique dépassant un certain nombre dans la zone est enregistré comme bord. L'opérateur Sobel ajoute la notion de poids sur la base de l'opérateur Prewitt. Il estime que la distance entre des points adjacents a des effets différents sur le pixel actuel. Plus la distance au pixel est proche, plus l'impact sur le pixel actuel est important, réaliser l'image Affiner et mettre en évidence les contours des bords [1-4].

Le positionnement des bords de l'opérateur Sobel est plus précis et est souvent utilisé dans les images comportant beaucoup de bruit et de dégradés de niveaux de gris. Son modèle d'algorithme est présenté dans la formule (1), où dx représente la direction horizontale et dy représente la direction verticale [3].

cke_135.png

La formule de calcul des pixels est la suivante :

cke_136.png

La formule finale de calcul du pixel de l'opérateur Sobel est la suivante :

cke_137.png

L'opérateur Sobel détecte le bord en fonction du phénomène d'atteinte de la valeur extrême au bord en fonction de la différence pondérée des niveaux de gris des points adjacents supérieur, inférieur, gauche et droit du pixel. Il a un effet lissant sur le bruit et fournit des informations plus précises sur la direction des contours. Étant donné que l'opérateur Sobel combine le lissage gaussien et la dérivation différentielle (différenciation), le résultat sera plus résistant au bruit. Lorsque les exigences de précision ne sont pas très élevées, l'opérateur Sobel est une méthode de détection de bord plus couramment utilisée.

Python et OpenCV encapsulent l'opérateur Sobel dans la fonction Sobel(), et son prototype de fonction est le suivant :

  • dst = Sobel(src, dprofondeur, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])

    – src représente l'image d'entrée

    – dst représente la carte des bords de sortie, qui a la même taille et le même nombre de canaux que l'image d'entrée

    - dprofondeur indique la profondeur requise de l'image cible. Pour différentes images d'entrée, l'image cible de sortie a des profondeurs différentes

    – dx représente l'ordre de différence dans la direction x, la valeur est 1 ou 0

    – dy représente l'ordre de différence dans la direction y, avec une valeur de 1 ou 0

    – ksize indique la taille de l'opérateur Sobel, et sa valeur doit être positive et impaire

    – l'échelle représente la constante d'échelle de la dérivée d'échelle, il n'y a pas de facteur d'échelle par défaut

    – delta représente une valeur incrémentielle facultative ajoutée au résultat avant de le stocker dans l'image cible

    – borderType représente le mode bordure. Pour plus de détails, voir BorderTypes

Notez qu'après le traitement de l'opérateur Sobel, il est également nécessaire d'appeler la fonction convertScaleAbs() pour calculer la valeur absolue et convertir l'image en une image 8 bits pour l'affichage. Le prototype de l'algorithme est le suivant :

  • dst = convertScaleAbs(src[, dst[, alpha[, bêta]]])

    – src représente le tableau d'origine

    – dst représente le tableau de sortie, avec une profondeur de 8 bits

    – alpha représente le facteur d'échelle

    – bêta représente la valeur ajoutée après la mise à l'échelle des éléments du tableau d'origine

Le code d'implémentation de l'opérateur Sobel est le suivant.

# -*- codage : utf-8 -*-

# Par:Eastmount

importer CV2

importer numpy en tant que np

importer matplotlib.pyplot en tant que plt



#lire l'image

img = cv2.imread('luo.png')

lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#Traitement d'image en niveaux de gris

grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)



#OpérateurSobel

x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0) # Trouver la dérivée première de x

y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1) # Trouver la dérivée du premier ordre de y

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

Sobel = cv2.addWeighted(absX, 0,5, absY, 0,5, 0)

#Utilisé pour afficher normalement les étiquettes chinoises

plt.rcParams['font.sans-serif']=['SimHei']

#afficher les graphiques

titles = ['image originale', 'opérateur Sobel']

images = [lenna_img, Sobel]

pour moi dans la plage (2):

plt.subplot(1,2,i+1), plt.imshow(images[i], 'gris')

plt.title(titres[i])

plt.xticks([]),plt.yticks([])

plt.show()

Les résultats d'exécution sont présentés dans la figure 1 :

cke_138.png

2. Opérateur laplacien

L'opérateur laplacien est un opérateur différentiel du second ordre dans l'espace euclidien à n dimensions et est souvent utilisé dans le domaine de l'amélioration d'image et de l'extraction de bords. Il calcule les pixels du voisinage grâce à la différence d'échelle de gris. Le processus de base est le suivant :

  • Déterminez la valeur de gris du pixel au centre de l'image et la valeur de gris des autres pixels autour de lui ;
  • Si le niveau de gris du pixel central est plus élevé, augmentez le niveau de gris du pixel central ;
  • Au contraire, le niveau de gris du pixel central est réduit, de manière à réaliser l'opération de netteté de l'image.

Dans le processus de mise en œuvre de l'algorithme, l'opérateur laplacien calcule le gradient dans les quatre ou huit directions du pixel central du voisinage, puis ajoute les gradients pour déterminer la relation entre l'échelle de gris du pixel central et l'échelle de gris des autres pixels du voisinage. Enfin, grâce à l'opération de dégradé, l'échelle de gris des pixels est ajustée [2].

Une fonction binaire continue f(x,y) dont l'opération de Laplace est définie comme :

cke_139.png

L'opérateur laplacien est divisé en quatre quartiers et huit quartiers. Le quatre quartiers consiste à trouver le gradient dans quatre directions du pixel central du quartier, et le huit quartiers consiste à trouver le gradient dans huit directions. Parmi eux, le modèle à quatre voisins est représenté dans la formule (5) :

cke_140.png

La formule de calcul de ses pixels peut être simplifiée comme suit :

cke_141.png

On peut constater grâce au modèle que lorsque l'échelle de gris des pixels du voisinage est la même, le résultat de l'opération de convolution du modèle est 0 ; lorsque l'échelle de gris du pixel central est supérieure à l'échelle de gris moyenne des autres pixels du voisinage, le Le résultat de l'opération de convolution du modèle est un nombre positif ; Lorsque le niveau de gris du pixel central est inférieur au niveau de gris moyen des autres pixels du voisinage, la convolution du modèle est négative. Le résultat de l'opération de convolution est traité avec un facteur d'atténuation approprié et ajouté au pixel central d'origine pour obtenir une netteté de l'image.

Le modèle à huit quartiers de l’opérateur laplacien est le suivant :

cke_142.png

La formule de calcul de ses pixels peut être simplifiée comme suit :

cke_143.png

Python et OpenCV encapsulent l'opérateur laplacien dans la fonction Laplacian(), et son prototype de fonction est le suivant :

  • dst = Laplacien(src, ddegree[, dst[, ksize[, scale[, delta[, borderType]]]]])

    – src représente l'image d'entrée

    – dst représente la carte des bords de sortie, qui a la même taille et le même nombre de canaux que l'image d'entrée

    – dprofondeur représente la profondeur requise de l’image cible

    – ksize représente la taille d'ouverture du filtre utilisé pour calculer la dérivée seconde. Sa valeur doit être un nombre positif et un nombre impair, et la valeur par défaut est 1. Pour plus de détails, consultez getDerivKernels

    – scale indique un facteur d'échelle facultatif pour calculer la valeur laplacienne. La valeur par défaut est 1, voir getDerivKernels pour plus de détails

    – delta représente une valeur incrémentielle facultative ajoutée au résultat avant de le stocker dans l'image cible. La valeur par défaut est 0

    – borderType représente le mode bordure. Pour plus de détails, voir BorderTypes

Notez que l'opérateur laplacien utilise en fait principalement le fonctionnement de l'opérateur Sobel. En ajoutant les dérivées dans la direction x et la direction y de l'image calculée par l'opérateur Sobel, le résultat de netteté de l'image d'entrée est obtenu.

Dans le même temps, après avoir effectué le traitement de l'opérateur laplacien, vous devez également appeler la fonction convertScaleAbs() pour calculer la valeur absolue et convertir l'image en une image 8 bits pour l'affichage. Le prototype de l'algorithme est le suivant :

  • dst = convertScaleAbs(src[, dst[, alpha[, bêta]]])

    – src représente le tableau d'origine

    – dst représente le tableau de sortie, avec une profondeur de 8 bits

    – alpha représente le facteur d'échelle

    – bêta représente la valeur ajoutée après la mise à l'échelle des éléments du tableau d'origine

Lorsque ksize=1, la fonction Laplacian() utilise une ouverture 3×3 (modèle à quatre quartiers) pour le traitement de transformation. Le code suivant utilise l'opérateur laplacien de ksize=3 pour le traitement de la netteté de l'image, et le code est le suivant :

# -*- codage : utf-8 -*-

# Par:Eastmount

importer CV2

importer numpy en tant que np

importer matplotlib.pyplot en tant que plt



#lire l'image

img = cv2.imread('luo.png')

lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#Traitement d'image en niveaux de gris

grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)



Algorithme de #Laplace

dst = cv2.Laplacian(grayImage, cv2.CV_16S, ksize = 3)

Laplacien = cv2.convertScaleAbs(dst)

#Utilisé pour afficher normalement les étiquettes chinoises

plt.rcParams['font.sans-serif']=['SimHei']

#afficher les graphiques

titles = ['image originale', 'opérateur laplacien']

images = [lenna_img, laplacien]

pour moi dans la plage (2):

plt.subplot(1,2,i+1), plt.imshow(images[i], 'gris')

plt.title(titres[i])

plt.xticks([]),plt.yticks([])

plt.show()

Les résultats d'exécution sont présentés dans la figure 2 :

cke_144.png

L'algorithme de détection des contours est principalement basé sur les dérivées du premier et du second ordre de l'intensité de l'image, mais les dérivées sont généralement très sensibles au bruit, un filtre est donc nécessaire pour filtrer le bruit, et l'algorithme d'amélioration de l'image ou de seuillage est appelé pour le traitement, et enfin une détection de bord est effectuée. Ce qui suit est le processus de détection des contours après débruitage et seuillage du filtre gaussien, et compare quatre algorithmes d'extraction de contours courants.

# -*- codage : utf-8 -*-

# Par:Eastmount

importer CV2

importer numpy en tant que np

importer matplotlib.pyplot en tant que plt

#lire l'image

img = cv2.imread('luo.png')

lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

#Traitement d'image en niveaux de gris

grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#Filtre gaussien

flou gaussien = cv2.Flou gaussien (grayImage, (3,3), 0)

#traitement du seuil

ret, binaire = cv2.threshold (flou gaussien, 127, 255, cv2.THRESH_BINARY)

#OpérateurRoberts

kernelx = np.array([[-1,0],[0,1]], dtype=int)

kernely = np.array([[0,-1],[1,0]], dtype=int)

x = cv2.filter2D (binaire, cv2.CV_16S, noyaux)

y = cv2.filter2D (binaire, cv2.CV_16S, noyau)

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

Roberts = cv2.addWeighted(absX, 0,5, absY, 0,5, 0)

#OpérateurPrewitt

kernelx = np.array([[1,1,1],[0,0,0],[-1,-1,-1]], dtype=int)

kernely = np.array([[-1,0,1],[-1,0,1],[-1,0,1]], dtype=int)

x = cv2.filter2D (binaire, cv2.CV_16S, noyaux)

y = cv2.filter2D (binaire, cv2.CV_16S, noyau)

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

Préwitt = cv2.addWeighted(absX,0.5,absY,0.5,0)

#OpérateurSobel

x = cv2.Sobel(binaire, cv2.CV_16S, 1, 0)

y = cv2.Sobel(binaire, cv2.CV_16S, 0, 1)

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

Sobel = cv2.addWeighted(absX, 0,5, absY, 0,5, 0)

Algorithme de #Laplace

dst = cv2.Laplacien (binaire, cv2.CV_16S, ksize = 3)

Laplacien = cv2.convertScaleAbs(dst)

# Image d'effet

titres = ['Image source', 'Image binaire', 'Image Roberts',

'Image Prewitt', 'Image Sobel', 'Image Laplacienne']

images = [lenna_img, binaire, Roberts, Prewitt, Sobel, Laplacian]

pour moi dans np.arange(6) :

plt.subplot(2,3,i+1),plt.imshow(images[i],'gris')

plt.title(titres[i])

plt.xticks([]),plt.yticks([])

plt.show()

Les résultats de sortie sont présentés dans la figure 3. Parmi eux, l'opérateur laplacien est relativement sensible au bruit. Comme son algorithme peut provoquer des limites de pixels doubles, il est souvent utilisé pour déterminer si les pixels de bord sont situés dans les zones claires ou sombres de l'image, et est rarement utilisé pour la détection des bords. ; l'opérateur Robert convient aux images à forte pente et à faible bruit. L'effet est meilleur, en particulier pour les images avec plus de bords de plus et moins 45 degrés, mais la précision du positionnement est médiocre ; l'opérateur Prewitt a un meilleur effet sur l'extraction des bords du gris. images dégradées, sans tenir compte de la distance des points adjacents au pixel actuel. L'effet du point ; l'opérateur Sobel prend en compte les facteurs complets et a un meilleur effet sur le traitement de l'image avec plus de bruit.

cke_145.png

3. Résumé

Cet article présente principalement les connaissances sur la netteté de l'image et la détection des bords, explique en détail l'opérateur Sobel et l'opérateur laplacien, et extrait les contours des bords à travers de petites images Luoluo. La technologie de netteté des images et d'extraction des bords peut éliminer le bruit dans les images, extraire certaines variables utilisées pour caractériser les images dans les informations d'image et fournir une base pour la reconnaissance d'images.

les références:

  • [1] Écrit par Gonzales, traduit par Ruan Qiuqi. Digital Image Processing (3e édition) [M]. Pékin : Electronic Industry Press, 2013.
  • [2] Ruan Qiuqi, Digital Image Processing (3e édition) [M], Pékin : Electronic Industry Press, 2008.
  • [3] Yang Xiuzhang, Yu Xiaomin, Fan Yufeng, Li Na. Recherche sur la technologie de netteté d'image et d'extraction de bords basée sur les costumes Miao [J]. Modern Computer, 2018-10.
  • [4] Eastmount. [Traitement d'image Python] 4. Filtrage moyen, filtrage par boîte, filtrage gaussien et filtrage médian pour le lissage d'image [EB/OL]. (2018-09-02). https://blog.csdn. net / Eastmount/article/détails/82216380. 
  • [5] Eastmount. [Traitement d'image numérique] 7. Explication détaillée du lissage normal de l'image, du lissage gaussien, de la netteté laplacienne, de Sobel et de Prewitt de l'amélioration de l'image MFC [EB/OL]. (2015-06-08). https:/ / blog .csdn.net/eastmount/article/ details/46378783.  
  • [6] DSQiu. Affinage de l'image (amélioration) et détection des contours [EB/OL] (20/08/2012). https://dsqiu.iteye.com/blog/1638589.https://blog.csdn.net. /poem_qianmo/article/details/23184547. 
  • [7] C. Tomasi, R Manduchi. Filtrage bilatéral pour les images grises et couleur [C]. Actes de la conférence internationale IEEE sur la vision par ordinateur, Bombay, Inde. 1998 : 839-846.

Cliquez pour suivre et découvrir pour la première fois les nouvelles technologies de Huawei Cloud~

La version Web de Windows 12 deepin-IDE compilée par des lycéens a été officiellement dévoilée. Il est connu sous le nom de "développé véritablement indépendamment" QQ a réalisé "des mises à jour simultanées à trois terminaux", et l'architecture NT sous-jacente est basée sur Electron QQ pour Linux a officiellement publié la version 3.2.0 "Père de Hongmeng" Wang Chenglu : Le système de version PC Hongmeng sera lancé l'année prochaine pour défier ChatGPT. Ces 8 produits nationaux de grand modèle d'IA GitUI v0.24.0 sont publiés. Le fond d'écran par défaut d'Ubuntu 23.10, un Git terminal écrit en Rust, est révélé. Le "Tauren" dans le labyrinthe. JetBrains annonce la feuille de route WebStorm 2023.3 en Chine. Écosystème Java humain, Solon v2.5.3 publié
{{o.name}}
{{m.nom}}

おすすめ

転載: my.oschina.net/u/4526289/blog/10108642