Es wurden viele Methoden vorgeschlagen, um einen bestimmten Bereich aus einem Bild zu segmentieren (zu extrahieren). Bekannte Methoden umfassen die Graph-Cut-Methode, die Level-Set-Methode und die Flächenerweiterungsmethode. Die Methoden zum Ausschneiden und Einstellen von Graphen können Bereiche mit hoher Genauigkeit extrahieren, es ist jedoch ziemlich schwierig, ein Programm zu erstellen. Die Flächenerweiterungsmethode ist einfach einzurichten, aber die Genauigkeit ist nicht gut, da sie einfach den Bereich, der in den Schwellenwert passt, aus dem Startpunkt extrahiert. Es wurde jedoch eine spezielle Methode vorgeschlagen, die das Erstellen eines Programms sehr einfach macht und eine gute Genauigkeit aufweist. Das ist die Grow-Cut-Methode. Growcut ist eine Regionsextraktionsmethode unter Verwendung eines Zellautomaten. Der Bereich wird bestimmt, indem der Vorgang wiederholt wird, bei dem das interessierende Pixel von den benachbarten Pixeln angegriffen wird und die Beschriftungen der benachbarten Pixel in allen Pixeln immer mehr ersetzt werden. Dieses Mal habe ich versucht, diese Growcut-Methode mit Python zu erstellen, daher werde ich das Programm erklären.
Die
Growcut-Methode ist eine Methode zum Segmentieren des Vordergrunds, wenn im Bild Startpunkte für den Vordergrund und den Hintergrund angegeben sind. Diese Methode basiert auf einem Zellautomaten und kann als Bakterien mit einer Vordergrundmarkierung und Bakterien mit einer Hintergrundmarkierung interpretiert werden, die vom Startpunkt diffundieren und während des Wettbewerbs für jedes Pixel im Bild verschlüsseln. Jedes bemerkenswerte Pixel wird von Bakterien befallen, die in nahegelegenen Pixeln lauern. Jedes Bakterium hat Angriffs- und Verteidigungskraft, und wenn ein Bakterium versucht, in ein Pixel einzudringen (diesem Pixel eine eigene Bezeichnung zu geben), dämpft die Verteidigungskraft dieses Pixels den Angriff in gewissem Maße. Wenn jedoch die Angriffskraft größer ist als die Angriffskraft des Pixels, in das eingedrungen werden soll, wird dieses Pixel angegriffen. Es scheint, dass der Vordergrund extrahiert werden kann, indem dieser Invasionsprozess für alle Pixel durchgeführt und diese Reihe von Schritten viele Male wiederholt wird. Detaillierte Formeln finden Sie in den Referenzen. </ p>
Die verwendeten Daten sind ein Graustufenbild von Herrn Lenna. Dieses Mal wird diese Lenna durch die Grow-Cut-Methode extrahiert.
Das gesamte diesmal erstellte Programm sieht wie folgt aus.
python
# encoding:utf-8
import numpy as np
import cv2
import matplotlib.pyplot as plt
class Sampling:
def __init__(self, image):
self.image = image
self.points = []
def mouse(self, event):
if event.button == 3:
self.axis.plot(event.xdata, event.ydata, "ro")
self.points.append([event.ydata, event.xdata])
self.fig.canvas.draw()
def start(self):
self.fig = plt.figure()
self.axis = self.fig.add_subplot(111)
self.fig.canvas.mpl_connect("button_press_event", self.mouse)
plt.gray()
self.axis.imshow(self.image)
plt.show()
plt.clf()
return np.array(self.points).astype(np.int)
def growCut(image, foreGround, backGround, iter=100):
#In der Nähe von 8
diffY = [-1,-1,-1,0,0,1,1,1]
diffX = [-1,0,1,-1,1,-1,0,1]
#Etiketteninitialisierung
label = np.zeros(image.shape)
label[foreGround[:,0], foreGround[:,1]] = 1
label[backGround[:,0], backGround[:,1]] = -1
#Offensivkraft
power = np.zeros(image.shape)
power[foreGround[:,0], foreGround[:,1]] = 1.0
power[backGround[:,0], backGround[:,1]] = 1.0
power_next = np.copy(power)
label_next = np.copy(label)
#Starten Sie Growcut
for t in range(iter):
print(t)
power = np.copy(power_next)
label = np.copy(label_next)
for i in range(1,image.shape[0]-1):
for j in range(1,image.shape[1]-1):
for k in range(8):
dy, dx = diffY[k], diffX[k]
#Defensive Kraft der Aufmerksamkeitszelle
shield = 1.0 - np.abs(image[i,j] - image[i+dy,j+dx])
#Übersteigt die Angriffskraft benachbarter Zellen die Verteidigungskraft des interessierenden Pixels?
if shield * power[i+dy,j+dx] > power[i,j]:
label_next[i,j] = label[i+dy,j+dx]
power_next[i,j] = power[i+dy,j+dx] * shield
return label_next
def main():
image = cv2.imread("Lenna.png ", 0).astype(np.float)
image = (image - image.min()) / (image.max() - image.min())
plt.gray()
plt.imshow(image)
plt.show()
foreGround = Sampling(image).start()
backGround = Sampling(image).start()
mask = growCut(image, foreGround, backGround)
mask[mask != 1] = 0
plt.gray()
plt.subplot(131)
plt.imshow(image)
plt.subplot(132)
plt.imshow(image)
plt.plot(foreGround[:,1], foreGround[:,0], "ro")
plt.plot(backGround[:,1], backGround[:,0], "bo")
plt.subplot(133)
plt.imshow(image * mask)
plt.show()
Die Sampling-Klasse ist eine Klasse zum Bestimmen des Startpunkts. Klicken Sie mit der rechten Maustaste, um den Startpunkt zu erreichen. Schließlich werden alle Startpunkte zurückgegeben. Da dies kein besonders wichtiger Teil ist, wird auf eine ausführliche Erläuterung verzichtet.
python
class Sampling:
def __init__(self, image):
self.image = image
self.points = []
def mouse(self, event):
if event.button == 3:
self.axis.plot(event.xdata, event.ydata, "ro")
self.points.append([event.ydata, event.xdata])
self.fig.canvas.draw()
def start(self):
self.fig = plt.figure()
self.axis = self.fig.add_subplot(111)
self.fig.canvas.mpl_connect("button_press_event", self.mouse)
plt.gray()
self.axis.imshow(self.image)
plt.show()
plt.clf()
return np.array(self.points).astype(np.int)
Das Folgende ist eine Erklärung der Growcut-Funktion. Bei der Growcut-Methode wird der Vorgang des Eindringens aller Pixel von benachbarten Pixeln viele Male wiederholt. Mit anderen Worten
python
for t in range(iter):
#Wiederholen Sie den Invasionsprozess iterativ
Es bedeutet das. Dieser Invasionsprozess definiert jedes Pixel als das interessierende Pixel und definiert die Differenz der Pixelwerte benachbarter Pixel als die Verteidigungskraft des interessierenden Pixels. Das ist
python
shield = 1.0 - np.abs(image[i,j] - image[i+dy,j+dx])
ist. Diese Verteidigungskraft dämpft den Angriff benachbarter Pixel, aber wenn sie den Angriff des interessierenden Pixels immer noch überschreitet, wird das interessierende Pixel eingedrungen und die Beschriftung des benachbarten Pixels wird dem interessierenden Pixel gegeben. Die Angriffskraft des Aufmerksamkeitspixels wird ebenfalls aktualisiert. Das ist,
python
if shield * power[i+dy,j+dx] > power[i,j]:
label_next[i,j] = label[i+dy,j+dx]
power_next[i,j] = power[i+dy,j+dx] * shield
Es wird. Es scheint, dass eine Segmentierung des Vordergrunds durch Wiederholen dieser Schritte möglich ist.
Der rote Punkt ist der Vordergrund-Startpunkt und der blaue Punkt ist der Hintergrund-Startpunkt. Es ist ein bisschen schmutzig, aber Sie können sehen, dass es meistens segmentiert ist. Ich habe keine Ahnung, warum es so gut funktioniert. Die Person, die darüber nachdenkt, ist erstaunlich.
Dies ist ein Originalpapier von growcut. “GrowCut” - Interactive Multi-Label N-D Image Segmentation By Cellular Automata
Es scheint, dass ein bestimmter Lehrer an der Universität von Tokio es geschrieben hat. Wachstumsschnitt auf dem neuesten Stand der Technik für die Bildverarbeitung in 100 Zeilen
Recommended Posts