Extraction du squelette de traitement d'images numériques Python et algorithme de bassin versant

不言
Libérer: 2018-04-27 10:25:41
original
3706 Les gens l'ont consulté

Cet article présente principalement l'algorithme d'extraction de squelette et de bassin versant du traitement d'images numériques Python. Maintenant, je le partage avec vous et vous donne une référence. Jetons un coup d'oeil ensemble

L'extraction de squelette et l'algorithme de bassin versant appartiennent également à la catégorie du traitement morphologique, et sont placés dans le sous-module morphologie.

1. Extraction du squelette

Extraction du squelette, également appelée amincissement de l'image binaire. Cet algorithme peut affiner une région connectée en une largeur d'un pixel pour l'extraction de caractéristiques et la représentation de la topologie cible.

Le sous-module morphologie fournit deux fonctions pour l'extraction du squelette, à savoir la fonction Skeletonize() et la fonction medial_axis(). Regardons d'abord la fonction Skeletonize().

Le format est : skimage.morphologie.squelette(image)

L'entrée et la sortie sont toutes deux des images binaires.

Exemple 1 :

from skimage import morphology,draw
import numpy as np
import matplotlib.pyplot as plt
#创建一个二值图像用于测试
image = np.zeros((400, 400))
#生成目标对象1(白色U型)
image[10:-10, 10:100] = 1
image[-100:-10, 10:-10] = 1
image[10:-10, -100:-10] = 1
#生成目标对象2(X型)
rs, cs = draw.line(250, 150, 10, 280)
for i in range(10):
 image[rs + i, cs] = 1
rs, cs = draw.line(10, 150, 250, 280)
for i in range(20):
 image[rs + i, cs] = 1
#生成目标对象3(O型)
ir, ic = np.indices(image.shape)
circle1 = (ic - 135)**2 + (ir - 150)**2 < 30**2
circle2 = (ic - 135)**2 + (ir - 150)**2 < 20**2
image[circle1] = 1
image[circle2] = 0

#实施骨架算法
skeleton =morphology.skeletonize(image)

#显示结果
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4))
ax1.imshow(image, cmap=plt.cm.gray)
ax1.axis(&#39;off&#39;)
ax1.set_title(&#39;original&#39;, fontsize=20)
ax2.imshow(skeleton, cmap=plt.cm.gray)
ax2.axis(&#39;off&#39;)
ax2.set_title(&#39;skeleton&#39;, fontsize=20)
fig.tight_layout()
plt.show()
Copier après la connexion

Générez une image de test avec trois objets cibles dessus et effectuez respectivement une extraction du squelette. Les résultats sont. comme suit :

Exemple 2 : Utilisation des propres images de chevaux du système pour l'extraction du squelette

from skimage import morphology,data,color
import matplotlib.pyplot as plt
image=color.rgb2gray(data.horse())
image=1-image #反相
#实施骨架算法
skeleton =morphology.skeletonize(image)
#显示结果
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4))

ax1.imshow(image, cmap=plt.cm.gray)
ax1.axis(&#39;off&#39;)
ax1.set_title(&#39;original&#39;, fontsize=20)
ax2.imshow(skeleton, cmap=plt.cm.gray)
ax2.axis(&#39;off&#39;)
ax2.set_title(&#39;skeleton&#39;, fontsize=20)
fig.tight_layout()
plt.show()
Copier après la connexion

medial_axis signifie l'axe médial. La méthode de transformation de l'axe médial est utilisée pour calculer la largeur de l'objet cible de premier plan (valeur 1). Le format est :

. skimage.morphologie. medial_axis(image,mask=None,return_distance=False)

masque : masque. La valeur par défaut est Aucun. Si un masque est donné, l'algorithme du squelette sera exécuté uniquement sur les valeurs de pixels à l'intérieur du masque.

return_distance : valeur bool, la valeur par défaut est False Si elle est True, en plus de renvoyer le squelette, la valeur de transformation de distance sera également renvoyée en même temps. La distance fait ici référence à la distance entre tous les points de l'axe central et le point d'arrière-plan.

import numpy as np
import scipy.ndimage as ndi
from skimage import morphology
import matplotlib.pyplot as plt
#编写一个函数,生成测试图像
def microstructure(l=256):
 n = 5
 x, y = np.ogrid[0:l, 0:l]
 mask = np.zeros((l, l))
 generator = np.random.RandomState(1)
 points = l * generator.rand(2, n**2)
 mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
 mask = ndi.gaussian_filter(mask, sigma=l/(4.*n))
 return mask > mask.mean()
data = microstructure(l=64) #生成测试图像

#计算中轴和距离变换值
skel, distance =morphology.medial_axis(data, return_distance=True)
#中轴上的点到背景像素点的距离
dist_on_skel = distance * skel
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
ax1.imshow(data, cmap=plt.cm.gray, interpolation=&#39;nearest&#39;)
#用光谱色显示中轴
ax2.imshow(dist_on_skel, cmap=plt.cm.spectral, interpolation=&#39;nearest&#39;)
ax2.contour(data, [0.5], colors=&#39;w&#39;) #显示轮廓线
fig.tight_layout()
plt.show()
Copier après la connexion

2. Algorithme de bassin versant

Un bassin versant fait référence à une crête en géographie. L'eau s'écoule généralement des deux côtés de la crête vers différents « bassins versants ». L'algorithme de bassin versant est un algorithme classique de segmentation d'images et une méthode de segmentation morphologique mathématique basée sur la théorie de la topologie. Si les objets cibles de l’image sont connectés entre eux, il sera plus difficile de segmenter. L’algorithme de partage des eaux est souvent utilisé pour résoudre de tels problèmes et permet généralement d’obtenir de meilleurs résultats.

L'algorithme de bassin versant peut être combiné avec la transformation de distance pour trouver des « bassins versants » et des « limites de bassin versant » pour segmenter les images. La transformation de distance d'une image binaire est la distance entre chaque pixel et le pixel non nul le plus proche. Nous pouvons utiliser le package scipy pour calculer la transformation de distance.

Dans l'exemple ci-dessous, deux cercles qui se chevauchent doivent être séparés. Nous calculons d'abord la transformation de distance de ces pixels blancs sur le cercle aux pixels de fond noir, sélectionnons la valeur maximale dans la transformation de distance comme point marqueur initial (s'il s'agit d'une couleur inversée, prenons la valeur minimale), à ​​partir de ces marqueurs. points Les deux bassins versants s'agrandissent de plus en plus et se croisent finalement au niveau de la crête de la montagne. Déconnectés de la crête de la montagne, nous obtenons deux cercles distincts.

Exemple 1 : Segmentation d'image de crête de montagne basée sur la transformation de distance

import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage as ndi
from skimage import morphology,feature
#创建两个带有重叠圆的图像
x, y = np.indices((80, 80))
x1, y1, x2, y2 = 28, 28, 44, 52
r1, r2 = 16, 20
mask_circle1 = (x - x1)**2 + (y - y1)**2 < r1**2
mask_circle2 = (x - x2)**2 + (y - y2)**2 < r2**2
image = np.logical_or(mask_circle1, mask_circle2)
#现在我们用分水岭算法分离两个圆
distance = ndi.distance_transform_edt(image) #距离变换
local_maxi =feature.peak_local_max(distance, indices=False, footprint=np.ones((3, 3)),
       labels=image) #寻找峰值
markers = ndi.label(local_maxi)[0] #初始标记点
labels =morphology.watershed(-distance, markers, mask=image) #基于距离变换的分水岭算法
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 8))
axes = axes.ravel()
ax0, ax1, ax2, ax3 = axes
ax0.imshow(image, cmap=plt.cm.gray, interpolation=&#39;nearest&#39;)
ax0.set_title("Original")
ax1.imshow(-distance, cmap=plt.cm.jet, interpolation=&#39;nearest&#39;)
ax1.set_title("Distance")
ax2.imshow(markers, cmap=plt.cm.spectral, interpolation=&#39;nearest&#39;)
ax2.set_title("Markers")
ax3.imshow(labels, cmap=plt.cm.spectral, interpolation=&#39;nearest&#39;)
ax3.set_title("Segmented")
for ax in axes:
 ax.axis(&#39;off&#39;)
fig.tight_layout()
plt.show()
Copier après la connexion

L'algorithme du bassin versant est également Il peut être combiné avec un dégradé pour réaliser une segmentation d'image. Généralement, les images dégradées ont des valeurs de pixels plus élevées sur les bords et des valeurs de pixels plus faibles ailleurs. Idéalement, les crêtes devraient être exactement sur les bords. Par conséquent, nous pouvons trouver des crêtes basées sur les gradients.

Exemple 2 : Segmentation d'images de bassin versant basée sur un dégradé

import matplotlib.pyplot as plt
from scipy import ndimage as ndi
from skimage import morphology,color,data,filter
image =color.rgb2gray(data.camera())
denoised = filter.rank.median(image, morphology.disk(2)) #过滤噪声
#将梯度值低于10的作为开始标记点
markers = filter.rank.gradient(denoised, morphology.disk(5)) <10
markers = ndi.label(markers)[0]
gradient = filter.rank.gradient(denoised, morphology.disk(2)) #计算梯度
labels =morphology.watershed(gradient, markers, mask=image) #基于梯度的分水岭算法
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(6, 6))
axes = axes.ravel()
ax0, ax1, ax2, ax3 = axes
ax0.imshow(image, cmap=plt.cm.gray, interpolation=&#39;nearest&#39;)
ax0.set_title("Original")
ax1.imshow(gradient, cmap=plt.cm.spectral, interpolation=&#39;nearest&#39;)
ax1.set_title("Gradient")
ax2.imshow(markers, cmap=plt.cm.spectral, interpolation=&#39;nearest&#39;)
ax2.set_title("Markers")
ax3.imshow(labels, cmap=plt.cm.spectral, interpolation=&#39;nearest&#39;)
ax3.set_title("Segmented")
for ax in axes:
 ax.axis(&#39;off&#39;)
fig.tight_layout()
plt.show()
Copier après la connexion

Recommandations associées :

Traitement morphologique avancé du traitement d'images numériques python

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal