Seuillage
C'est le moyen le plus simple de séparer les objets de l'arrière-plan en sélectionnant des pixels au-dessus ou en dessous d'un certain seuil. Ceci est généralement utile lorsque nous allons segmenter des objets en fonction de leur arrière-plan. Vous pouvez en savoir plus sur le seuil
ici .
Les gens familiers avec le film Terminator conviendront probablement que c'était le plus grand film de science-fiction de l'époque. Dans le film, James Cameron a introduit un concept intéressant d'effets visuels, qui a permis aux téléspectateurs de se cacher derrière les yeux d'un cyborg appelé Terminator. Cet effet est devenu connu sous le nom de "Terminator Vision" (English Terminator Vision). Dans un sens, il a séparé les silhouettes des gens de l'arrière-plan. Cela peut sembler tout à fait inapproprié alors, mais la segmentation d'image est aujourd'hui un élément important de nombreuses techniques de traitement d'image.
Segmentation d'image
Il existe un certain nombre de bibliothèques écrites pour l'analyse d'images. Dans cet article, nous discuterons en détail de scikit-image, une bibliothèque de traitement d'images Python.
Scikit-image

Scikit-image est une bibliothèque Python pour le traitement d'images.
L'installation
scikit-image est installé comme suit:
pip install -U scikit-image(Linux and OSX) pip install scikit-image(Windows)

Présentation de l'image Python
Avant de passer aux aspects techniques de la segmentation d'images, il est important de se familiariser un peu avec l'écosystème d'images Scikit et la façon dont il traite les images.
Importer une image GrayScale de la bibliothèque skimage
Le module de données skimage contient plusieurs exemples intégrés d'ensembles de données, qui sont généralement stockés au format jpeg ou png.
from skimage import data import numpy as np import matplotlib.pyplot as plt image = data.binary_blobs() plt.imshow(image, cmap='gray')
Importer une image couleur de la bibliothèque skimage
from skimage import data import numpy as np import matplotlib.pyplot as plt image = data.astronaut() plt.imshow(image)

Importer une image depuis une source externe

Téléchargez plusieurs images
images = io.ImageCollection('../images/*.png:../images/*.jpg') print('Type:', type(images)) images.files Out[]: Type: <class 'skimage.io.collection.ImageCollection'>
Enregistrement d'images
Segmentation d'image
Maintenant que nous avons une idée de scikit-image, nous proposons de considérer les détails de la segmentation de l'image. La segmentation d'image est le processus de division d'une image numérique en plusieurs segments afin de simplifier et / ou de changer la représentation de l'image en quelque chose de plus significatif et plus facile à analyser.
Dans cet article, nous considérerons les algorithmes pour les modèles enseignés à la fois avec un enseignant (supervisé) et sans enseignant (non supervisé).
Certains algorithmes de segmentation sont disponibles dans la bibliothèque d'images de scikit.Segmentation avec un enseignant: certaines connaissances préliminaires, peut-être issues de contributions humaines, sont utilisées pour guider l'algorithme.
Segmentation sans enseignant: aucune connaissance préalable n'est requise. Ces algorithmes tentent de diviser automatiquement les images en zones significatives. L'utilisateur peut toujours configurer certains paramètres pour obtenir les résultats souhaités.
Essayons cela sur une image de didacticiel fournie avec un jeu de données d'image scikit prédéfini.
Importation régulière
import numpy as np import matplotlib.pyplot as plt import skimage.data as data import skimage.segmentation as seg import skimage.filters as filters import skimage.draw as draw import skimage.color as color
Fonction d'imagerie simple
def image_show(image, nrows=1, ncols=1, cmap='gray'): fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=(14, 14)) ax.imshow(image, cmap='gray') ax.axis('off') return fig, ax
Image
text = data.page() image_show(text)

Cette image est un peu plus sombre, mais peut-être que nous pouvons toujours choisir une valeur qui nous donnera une segmentation raisonnable sans algorithmes compliqués. Maintenant, pour nous aider à choisir cette valeur, nous allons utiliser un histogramme.
Dans ce cas, l'histogramme montre le nombre de pixels dans l'image avec différentes intensités trouvées dans cette image. Autrement dit, un histogramme est un graphique dans lequel l'axe X montre toutes les valeurs qui sont dans l'image, et l'axe Y montre la fréquence de ces valeurs.
fig, ax = plt.subplots(1, 1) ax.hist(text.ravel(), bins=32, range=[0, 256]) ax.set_xlim(0, 256);

Notre exemple s'est avéré être une image 8 bits, nous avons donc 256 valeurs possibles le long de l'axe X. L'histogramme montre qu'il y a une concentration de pixels assez lumineux (0: noir, 255: blanc). C'est très probablement notre joli fond de texte clair, mais le reste est un peu flou. Un histogramme de segmentation idéal serait bimodal afin que nous puissions sélectionner un nombre en plein milieu. Essayons maintenant de créer des images segmentées basées sur une valeur de seuil simple.
Seuil contrôlé
Puisque nous choisissons nous-mêmes une valeur seuil, nous l'appelons une valeur seuil contrôlée.
text_segmented = text > (value concluded from histogram ie 50,70,120 ) image_show(text_segmented);
Gauche: texte> 50 | Milieu: texte> 70 | Droite: texte> 120Nous n'avons pas obtenu de résultats parfaits, car l'ombre de gauche crée des problèmes. Essayons avec le seuil sans surveillance maintenant.
Seuil incontrôlé
Seuil non contrôlé Scikit-image dispose d'un certain nombre de méthodes de détermination automatique de seuil qui ne nécessitent pas d'entrée lors du choix du seuil optimal. Voici quelques-unes des méthodes: otsu, li, local.
text_threshold = filters.threshold_
Otsu gauche || Droite: liDans le cas de local, nous devons également spécifier block_size. Le décalage permet d'ajuster l'image pour de meilleurs résultats.
text_threshold = filters.threshold_local(text,block_size=51, offset=10) image_show(text > text_threshold);

Cette méthode donne un assez bon effet. Dans une large mesure, on peut se débarrasser des régions bruyantes.
Segmentation avec un algorithme pour un modèle avec un enseignant
Le seuillage est un processus de segmentation très simple, et il ne fonctionnera pas correctement sur une image à contraste élevé, pour laquelle nous aurons besoin d'outils plus avancés.
Dans cette section, nous allons utiliser un exemple d'image disponible gratuitement et essayer de segmenter la partie tête en utilisant des méthodes avec l'enseignant.
Avant d'effectuer une segmentation d'image, il est recommandé d'en supprimer le bruit à l'aide de certains filtres.Cependant, dans notre cas, l'image n'a pas de bruit significatif, nous l'accepterons telle quelle. L'étape suivante consiste à convertir l'image en niveaux de gris à l'aide de rgb2gray.
image_gray = color.rgb2gray(image) image_show(image_gray);

Nous utiliserons deux méthodes de segmentation qui fonctionnent sur des principes complètement différents.
Segmentation active des contours
La segmentation du chemin actif est également appelée serpent et est initialisée à l'aide d'un chemin ou d'une ligne défini par l'utilisateur autour d'une région d'intérêt, puis ce chemin est lentement compressé et attiré ou repoussé par la lumière et les bords.
Pour notre exemple d'image, dessinons un cercle autour de la tête humaine pour initialiser le serpent.
def circle_points(resolution, center, radius): """ Generate points which define a circle on an image.Centre refers to the centre of the circle """ radians = np.linspace(0, 2*np.pi, resolution) c = center[1] + radius*np.cos(radians)
Les calculs ci-dessus calculent les coordonnées x et y des points à la périphérie du cercle. Puisque nous avons donné une résolution de 200, il calculera 200 de ces points.
fig, ax = image_show(image) ax.plot(points[:, 0], points[:, 1], '--r', lw=3)

L’algorithme segmente ensuite le visage de la personne du reste de l’image, en ajustant une courbe fermée aux bords du visage.

Nous pouvons configurer des paramètres appelés alpha et bêta. Des valeurs alpha plus élevées accélèrent la contraction de la courbe, tandis que la bêta rend la courbe plus lisse.
snake = seg.active_contour(image_gray, points,alpha=0.06,beta=0.3) fig, ax = image_show(image) ax.plot(points[:, 0], points[:, 1], '--r', lw=3) ax.plot(snake[:, 0], snake[:, 1], '-b', lw=3);

Segmentation aléatoire des marcheurs
Dans cette méthode, la segmentation est effectuée à l'aide d'un étiquetage interactif, appelé étiquettes. En dessinant chaque pixel sur l'étiquette pour laquelle la probabilité la plus élevée est calculée, vous pouvez obtenir une segmentation d'image de haute qualité. Plus de détails sur cette méthode peuvent être trouvés dans
cet ouvrage.
Ensuite, nous utiliserons à nouveau les valeurs précédentes de notre exemple. Nous aurions pu faire différentes initialisations, mais pour plus de simplicité, restons-en au principe des cercles.
image_labels = np.zeros(image_gray.shape, dtype=np.uint8)
L'algorithme de passage aléatoire accepte les étiquettes en entrée. Ainsi, nous aurons un grand cercle couvrant tout le visage de la personne et un autre petit cercle près du milieu du visage.
indices = draw.circle_perimeter(80, 250,20)

Maintenant, utilisons Random Walker et voyons ce qui se passe.
image_segmented = seg.random_walker(image_gray, image_labels)

Le résultat n'est pas le meilleur, les bords du visage sont restés intacts. Pour corriger cette situation, nous pouvons ajuster le paramètre de passage jusqu'à obtenir le résultat souhaité. Après plusieurs tentatives, nous avons défini la valeur sur 3000, ce qui fonctionne assez bien.
image_segmented = seg.random_walker(image_gray, image_labels, beta = 3000) # Check our results fig, ax = image_show(image_gray) ax.imshow(image_segmented == 1, alpha=0.3);

C'est tout pour la segmentation avec l'enseignant, où nous devions fournir certaines données d'entrée, ainsi que configurer certains paramètres. Cependant, il n'est pas toujours possible pour une personne de regarder l'image, puis de décider quelle contribution apporter et par où commencer. Heureusement, pour de telles situations, nous avons des méthodes de segmentation incontrôlées.
Segmentation sans enseignant
La segmentation sans enseignant ne nécessite pas de connaissances préalables. Considérez une image si grande qu'il est impossible de voir tous les pixels à la fois. Ainsi, dans de tels cas, la segmentation sans enseignant peut diviser l'image en plusieurs sous-régions, donc au lieu de millions de pixels, vous avez des dizaines ou des centaines de zones. Regardons deux de ces algorithmes:
Regroupement itératif linéaire simple
La méthode (English Simple Linear Iterative Clustering ou SLIC) utilise un algorithme d'apprentissage automatique appelé K-Means. Il prend toutes les valeurs de pixels de l'image et essaie de les diviser en un nombre donné de sous-domaines. Lisez
ce travail pour des informations détaillées.
SLIC fonctionne avec différentes couleurs, nous allons donc utiliser l'image d'origine.
image_slic = seg.slic(image,n_segments=155)
Tout ce que nous devons faire est simplement de définir une valeur moyenne pour chaque segment que nous trouvons, ce qui le fait ressembler davantage à une image.

Nous avons réduit cette image de 512 * 512 = 262 000 pixels à 155 segments.
Felzenszwalb
Cette méthode utilise également un algorithme d'apprentissage automatique appelé clustering d'arbre couvrant un minimum. Felzenszwaib ne nous dit pas le nombre exact de clusters dans lesquels l'image sera divisée. Il générera autant de clusters qu'il le jugera bon.
image_felzenszwalb = seg.felzenszwalb(image) image_show(image_felzenszwalb);

Il y a trop de régions dans l'image. Comptons le nombre de segments uniques.
np.unique(image_felzenszwalb).size 3368
Maintenant, recolorons-les en utilisant la valeur moyenne sur le segment, comme nous l'avons fait dans l'algorithme SLIC.
image_felzenszwalb_colored = color.label2rgb(image_felzenszwalb, image, kind='avg') image_show(image_felzenszwalb_colored);
Maintenant, nous obtenons moins de segments. Si nous voulions encore moins de segments, nous pourrions changer le paramètre d'échelle. Cette approche est parfois appelée sur-segmentation.

Cela ressemble plus à une image postérisée, qui n'est essentiellement qu'une réduction du nombre de couleurs. Pour les combiner à nouveau (RAG).
Conclusion
La segmentation d'image est une étape très importante dans le traitement d'image. Il s'agit d'un domaine de recherche actif avec une variété d'applications, allant de la vision par ordinateur aux images médicales, au trafic et à la vidéosurveillance. Python fournit une bibliothèque d'images scikit robuste avec un grand nombre d'algorithmes de traitement d'image. Il est disponible gratuitement et sans restrictions, soutenu par une communauté active. Je vous recommande de lire leur documentation. L'article original se trouve
ici .