Heim >Backend-Entwicklung >Python-Tutorial >Python-Skelettextraktion für die digitale Bildverarbeitung und Wassereinzugsgebietsalgorithmus

Python-Skelettextraktion für die digitale Bildverarbeitung und Wassereinzugsgebietsalgorithmus

不言
不言Original
2018-04-27 10:25:413745Durchsuche

In diesem Artikel werden hauptsächlich die Skelettextraktion und der Wassereinzugsgebietsalgorithmus der digitalen Bildverarbeitung mit Python vorgestellt. Jetzt teile ich ihn mit Ihnen und gebe Ihnen eine Referenz. Werfen wir gemeinsam einen Blick darauf

Die Skelettextraktion und der Wassereinzugsgebietsalgorithmus gehören ebenfalls zur Kategorie der morphologischen Verarbeitung und werden im Untermodul Morphologie platziert.

1. Skelettextraktion

Skelettextraktion, auch Binärbildausdünnung genannt. Dieser Algorithmus kann einen verbundenen Bereich zur Merkmalsextraktion und Zieltopologiedarstellung auf eine Breite von einem Pixel verfeinern.

Das Morphologie-Submodul stellt zwei Funktionen zur Skelettextraktion bereit, nämlich die Skeletonize()-Funktion und die medial_axis()-Funktion. Schauen wir uns zunächst die Skeletonize()-Funktion an.

Das Format ist: skimage.morphology.skeletonize(image)

Eingabe und Ausgabe sind beide Binärbilder.

Beispiel 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()

Erzeugen Sie ein Testbild mit drei Zielobjekten darauf und führen Sie jeweils eine Skelettextraktion durch. Die Ergebnisse sind wie folgt :

Beispiel 2: Verwendung der im System integrierten Pferdebilder zur Skelettextraktion

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()

medial_axis bedeutet mediale Achse. Die Transformationsmethode der medialen Achse wird verwendet, um die Breite des Vordergrundzielobjekts (1 Wert) zu berechnen. Das Format ist:

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

Maske: Maske. Der Standardwert ist „Keine“. Wenn eine Maske angegeben ist, wird der Skelettalgorithmus nur für die Pixelwerte innerhalb der Maske ausgeführt.

return_distance: bool-Wert, Standardwert ist False. Wenn es True ist, wird zusätzlich zur Rückgabe des Skeletts gleichzeitig auch der Abstandstransformationswert zurückgegeben. Der Abstand bezieht sich hier auf den Abstand zwischen allen Punkten auf der Mittelachse und dem Hintergrundpunkt.

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()

2. Watershed-Algorithmus

Eine Wasserscheide bezieht sich in der Geographie auf einen Bergrücken, und Wasser fließt normalerweise entlang beider Seiten des Bergrückens zu verschiedenen „Einzugsgebieten“. Der Watershed-Algorithmus ist ein klassischer Algorithmus zur Bildsegmentierung und eine mathematisch-morphologische Segmentierungsmethode basierend auf der Topologietheorie. Wenn die Zielobjekte im Bild miteinander verbunden sind, ist die Segmentierung schwieriger. Der Watershed-Algorithmus wird häufig zur Lösung solcher Probleme verwendet und erzielt normalerweise bessere Ergebnisse.

Der Wassereinzugsgebietsalgorithmus kann mit der Distanztransformation kombiniert werden, um „Einzugsgebietsbecken“ und „Wassereinzugsgebietsgrenzen“ zu finden und Bilder zu segmentieren. Die Distanztransformation eines Binärbildes ist die Distanz von jedem Pixel zum nächsten Nicht-Null-Pixel. Wir können das Scipy-Paket verwenden, um die Distanztransformation zu berechnen.

Im Beispiel unten müssen zwei überlappende Kreise getrennt werden. Wir berechnen zunächst die Distanztransformation von diesen weißen Pixeln auf dem Kreis zu den schwarzen Hintergrundpixeln und wählen den Maximalwert in der Distanztransformation als anfänglichen Markierungspunkt aus (wenn es sich um eine invertierte Farbe handelt, nehmen Sie den Minimalwert), beginnend mit dieser Markierung Punkte Die beiden Einzugsgebiete werden immer größer und kreuzen sich schließlich am Bergrücken. Vom Bergrücken getrennt, erhalten wir zwei separate Kreise.

Beispiel 1: Bildsegmentierung eines Bergrückens basierend auf der Distanztransformation

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()

Der Wassereinzugsgebietsalgorithmus kann dies auch Wird mit Gradient kombiniert, um eine Bildsegmentierung zu erreichen. Im Allgemeinen haben Verlaufsbilder an den Rändern höhere Pixelwerte und an anderen Stellen niedrigere Pixelwerte. Idealerweise sollten die Grate genau an den Rändern liegen. Daher können wir Bergkämme anhand von Steigungen finden.

Beispiel 2: Gradientenbasierte Wassereinzugsgebietsbildsegmentierung

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()

Verwandte Empfehlungen:

Erweiterte morphologische Verarbeitung der digitalen Bildverarbeitung in Python

Das obige ist der detaillierte Inhalt vonPython-Skelettextraktion für die digitale Bildverarbeitung und Wassereinzugsgebietsalgorithmus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn