Méthode d'extraction de zone à l'aide de l'automate cellulaire Essayez l'extraction de zone de l'image avec growcut (Python)

introduction

De nombreuses méthodes ont été proposées pour segmenter (extraire) une zone spécifique d'une image. Les méthodes bien connues incluent la méthode de coupe de graphe, la méthode de réglage de niveau et la méthode d'expansion de surface. Les méthodes de coupe de graphe et de réglage de niveau peuvent extraire des zones avec une grande précision, mais il est assez difficile de créer un programme. La méthode d'expansion de zone est facile à configurer, mais la précision n'est pas bonne car elle extrait simplement la zone qui correspond au seuil à partir du point de départ. Cependant, une méthode spéciale a été proposée qui rend très facile la construction d'un programme et a une bonne précision. Telle est la méthode de coupe de croissance. growcut est une méthode d'extraction de région utilisant un automate cellulaire. La zone est déterminée en répétant le processus dans lequel le pixel d'intérêt est attaqué par les pixels voisins et remplacé par les étiquettes des pixels voisins. Cette fois, j'ai essayé de construire cette méthode growcut avec python, donc je vais expliquer le programme.

Quelle est la méthode Growcut?

La méthode

growcut est une méthode pour segmenter le premier plan lorsque des points de départ pour le premier plan et l'arrière-plan sont donnés dans l'image. Cette méthode est basée sur un automate cellulaire et peut être interprétée comme des bactéries avec une étiquette de premier plan et des bactéries avec une étiquette de fond diffusent à partir du point de départ et se brouillent pour chaque pixel de l'image en compétition. Chaque pixel remarquable est envahi par des bactéries qui se cachent dans les pixels voisins. Chaque bactérie a un pouvoir offensif et défensif, et lorsqu'une bactérie tente d'envahir un pixel (donnez sa propre étiquette à ce pixel), le pouvoir défensif de ce pixel atténue dans une certaine mesure l'attaque. Même ainsi, si la puissance d'attaque est supérieure à la puissance d'attaque du pixel à envahir, ce pixel sera envahi. Il semble que le premier plan puisse être extrait en effectuant ce processus d'invasion pour tous les pixels et en répétant cette série d'étapes plusieurs fois. Veuillez vous référer aux références pour les formules détaillées. </ p>

Des données d'utilisation

Les données utilisées sont une image en niveaux de gris de M. Lenna. Cette fois, cette Lenna est extraite par la méthode de coupe de croissance. figure_2.png

Programme complet

L'ensemble du programme créé cette fois est le suivant.

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):
    #Près de 8
    diffY = [-1,-1,-1,0,0,1,1,1]
    diffX = [-1,0,1,-1,1,-1,0,1]

    #Initialisation de l'étiquette
    label = np.zeros(image.shape)
    label[foreGround[:,0], foreGround[:,1]] = 1
    label[backGround[:,0], backGround[:,1]] = -1

    #Puissance offensive
    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)

    #commencer 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]

                    #Pouvoir défensif de la cellule d'attention
                    shield = 1.0 - np.abs(image[i,j] - image[i+dy,j+dx])

                    #La puissance d'attaque des cellules voisines dépasse-t-elle la puissance de défense du pixel d'intérêt?
                    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()

Explication du programme

La classe Sampling est une classe pour déterminer le point de départ. Cliquez avec le bouton droit pour atteindre le point de départ. Enfin, tous les points d'amorçage sont renvoyés. Puisqu'il ne s'agit pas d'une partie particulièrement importante, une explication détaillée est omise.

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)

Ce qui suit est une explication de la fonction growcut. Dans la méthode growcut, le processus d'envahissement de tous les pixels des pixels voisins est répété plusieurs fois. En d'autres termes

python


for t in range(iter):
    #Répétez le processus d'invasion plusieurs fois

Cela signifie que. Ce processus d'invasion définit chaque pixel comme le pixel d'intérêt, et la différence des valeurs de pixel des pixels voisins est définie comme la puissance de défense du pixel d'intérêt. C'est

python


shield = 1.0 - np.abs(image[i,j] - image[i+dy,j+dx])

est. Cette puissance défensive atténue l'attaque des pixels voisins, mais si elle dépasse encore l'attaque du pixel d'intérêt, le pixel d'intérêt est envahi et l'étiquette du pixel voisin est donnée au pixel d'intérêt. Et la puissance d'attaque du pixel d'attention est également mise à jour. C'est,

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

Il devient. Il semble que la segmentation du premier plan soit possible en répétant ces étapes.

Résultat d'exécution

Le point rouge est le point de départ du premier plan et le point bleu est le point de départ de l'arrière-plan. C'est un peu sale, mais vous pouvez voir que c'est principalement segmenté. Je n'ai aucune idée de pourquoi cela fonctionne si bien. La personne qui y pense est incroyable.

figure_1.png

Les références

Ceci est un papier original par growcut. “GrowCut” - Interactive Multi-Label N-D Image Segmentation By Cellular Automata

Il semble qu'un certain professeur de l'Université de Tokyo l'ait écrit. Growthcut de pointe pour le traitement d'image écrit en 100 lignes

Recommended Posts

Méthode d'extraction de zone à l'aide de l'automate cellulaire Essayez l'extraction de zone de l'image avec growcut (Python)
Traitement d'image à partir de zéro avec python (4) Extraction de contour
Essayez une recherche similaire de recherche d'images à l'aide du SDK Python [Recherche]
[Python] Régression LASSO avec contrainte d'équation utilisant la méthode du multiplicateur
[Python] Utilisation d'OpenCV avec Python (filtrage d'image)
[Python] Utilisation d'OpenCV avec Python (transformation d'image)
Essayez d'utiliser le module Python Cmd
Essayez de brouiller l'image avec opencv2
Essayez d'utiliser Amazon DynamoDB à partir de Python
Essayez d'extraire une chaîne de caractères d'une image avec Python3
Essayez une formule utilisant Σ avec python
Essayez d'utiliser l'API Kraken avec Python
Derrière le flyer: utiliser Docker avec Python
Essayez d'utiliser l'appareil photo avec OpenCV de Python
Essayez d'imaginer les données d'élévation du National Land Research Institute avec Python
Essayez d'utiliser Python avec Google Cloud Functions
Essayez d'utiliser le framework web de Python Django (1) - De l'installation au démarrage du serveur
Travailler avec OpenStack à l'aide du SDK Python
Essayez l'analyse de cluster par K-means
Acquisition d'images depuis une caméra avec Python + OpenCV
Essayez d'appeler Python depuis Ruby avec une économie
Essayez de mesurer la position d'un objet sur le bureau (système de coordonnées réel) à partir de l'image de la caméra avec Python + OpenCV
J'ai essayé de "lisser" l'image avec Python + OpenCV
J'ai essayé de "différencier" l'image avec Python + OpenCV
Traitement d'image à partir de zéro avec python (5) Transformation de Fourier
Essayez de résoudre le diagramme homme-machine avec Python
Essayez d'utiliser l'API BitFlyer Ligntning en Python
Python: essayez d'utiliser l'interface utilisateur sur Pythonista 3 sur iPad
Essayez d'utiliser le framework Web Python Tornado Partie 1
J'ai essayé de "binariser" l'image avec Python + OpenCV
Essayez d'utiliser le module de collections (ChainMap) de python3
Essayez d'utiliser le framework Web Python Tornado Partie 2
Essayez d'implémenter la méthode Monte Carlo en Python
Essayez d'accéder à l'API YQL directement depuis Python 3
Essayez d'utiliser l'API DropBox Core avec Python
Extraire le tableau des fichiers image avec OneDrive et Python
Essayez de résoudre le livre des défis de programmation avec python3
Apprenez Nim avec Python (dès le début de l'année).
Comment récupérer des données d'image de Flickr avec Python
Essayez de traduire avec Python tout en conservant la mise en page PDF
Essayez de résoudre le problème d'affectation du médecin de formation avec Python
[Python] Obtenez les nombres dans l'image graphique avec OCR
[Python] Spécifiez la plage de l'image en faisant glisser la souris
Détruire l'expression intermédiaire de la méthode sweep avec Python
Déterminer le seuil à l'aide de la méthode P-tile en python
Essayez de projeter la conversion d'image en utilisant OpenCV avec Python
Identifiez le nom de l'image de la fleur avec des keras (flux tenseur)
Convertissez l'image au format .zip en PDF avec Python
Lire le code QR à partir du fichier image avec Python (Mac)
Méthode d'installation lors de l'utilisation de RealSense à partir de Python (édition pyenv)
[Python] Masquez l'image dans un cercle à l'aide de Pillow
Analyse des composants principaux à l'aide de python de nim avec nimpy
Étude de Python Hour8: Utilisation de packages
Installez le dernier Python de pyenv installé par homebrew
Comment connaître le nombre de GPU de python ~ Remarques sur l'utilisation du multitraitement avec pytorch ~
Essayez de gratter avec Python.