Umbral
Esta es la forma más fácil de separar objetos del fondo seleccionando píxeles por encima o por debajo de un cierto umbral. Esto suele ser útil cuando vamos a segmentar objetos por su fondo. Puedes leer más sobre el umbral
aquí .
Las personas familiarizadas con la película Terminator probablemente estarán de acuerdo en que fue la mejor película de ciencia ficción de la época. En la película, James Cameron introdujo un concepto interesante de efectos visuales, que permitió a los espectadores esconderse detrás de los ojos de un cyborg llamado Terminator. Este efecto se conoce como "Terminator Vision" (Inglés Terminator Vision). En cierto sentido, separó las siluetas de personas del fondo. Esto puede sonar completamente inapropiado entonces, pero la segmentación de imágenes es una parte importante de muchas técnicas de procesamiento de imágenes en la actualidad.
Segmentación de imagen
Hay varias bibliotecas escritas para el análisis de imágenes. En este artículo, analizaremos en detalle scikit-image, una biblioteca de procesamiento de imágenes de Python.
Scikit-image

Scikit-image es una biblioteca de Python para el procesamiento de imágenes.
Instalación
scikit-image se instala de la siguiente manera:
pip install -U scikit-image(Linux and OSX) pip install scikit-image(Windows)

Descripción general de la imagen de Python
Antes de pasar a los aspectos técnicos de la segmentación de imágenes, es importante familiarizarse un poco con el ecosistema de imágenes Scikit y cómo procesa las imágenes.
Importar imagen GrayScale de la biblioteca de skimage
El módulo de datos de skimage contiene varios ejemplos integrados de conjuntos de datos, que generalmente se almacenan en formato jpeg o png.
from skimage import data import numpy as np import matplotlib.pyplot as plt image = data.binary_blobs() plt.imshow(image, cmap='gray')
Importar imagen en color de la biblioteca de skimage
from skimage import data import numpy as np import matplotlib.pyplot as plt image = data.astronaut() plt.imshow(image)

Importar una imagen desde una fuente externa

Descargar múltiples imágenes
images = io.ImageCollection('../images/*.png:../images/*.jpg') print('Type:', type(images)) images.files Out[]: Type: <class 'skimage.io.collection.ImageCollection'>
Guardar imágenes
Segmentación de imagen
Ahora que tenemos una idea de scikit-image, ofrecemos considerar los detalles de la segmentación de imágenes. La segmentación de imágenes es el proceso de dividir una imagen digital en varios segmentos para simplificar y / o cambiar la representación de la imagen a algo más significativo y más fácil de analizar.
En este artículo, consideraremos algoritmos para modelos enseñados tanto con un maestro (supervisado) como sin un maestro (sin supervisión).
Algunos de los algoritmos de segmentación están disponibles en la biblioteca de imágenes scikit.Segmentación con un profesor: algunos conocimientos preliminares, posiblemente a partir de aportes humanos, se utilizan para guiar el algoritmo.
Segmentación sin profesor: no se requieren conocimientos previos. Estos algoritmos intentan dividir automáticamente las imágenes en áreas significativas. El usuario aún puede configurar ciertos parámetros para obtener los resultados deseados.
Probemos esto en una imagen tutorial que viene con un conjunto de datos de imagen scikit predefinido.
Importación regular
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
Característica de imagen 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
Imagen
text = data.page() image_show(text)

Esta imagen es un poco más oscura, pero quizás aún podamos elegir un valor que nos dé una segmentación razonable sin algoritmos complicados. Ahora, para ayudarnos a elegir este valor, utilizaremos un histograma.
En este caso, el histograma muestra el número de píxeles en la imagen con diferentes intensidades encontradas en esta imagen. En pocas palabras, un histograma es un gráfico en el que el eje X muestra todos los valores que están en la imagen, y el eje Y muestra la frecuencia de estos valores.
fig, ax = plt.subplots(1, 1) ax.hist(text.ravel(), bins=32, range=[0, 256]) ax.set_xlim(0, 256);

Nuestro ejemplo resultó ser una imagen de 8 bits, por lo que tenemos 256 valores posibles a lo largo del eje X. El histograma muestra que hay una concentración de píxeles bastante brillantes (0: negro, 255: blanco). Este es probablemente nuestro fondo de texto bastante claro, pero el resto es un poco borroso. Un histograma de segmentación ideal sería bimodal para que podamos seleccionar un número justo en el medio. Ahora intentemos crear algunas imágenes segmentadas basadas en un valor umbral simple.
Umbral controlado
Como nosotros mismos elegimos un valor umbral, lo llamamos un valor umbral controlado.
text_segmented = text > (value concluded from histogram ie 50,70,120 ) image_show(text_segmented);
Izquierda: texto> 50 | Mediados: texto> 70 | Derecha: texto> 120No obtuvimos resultados perfectos, ya que la sombra de la izquierda crea problemas. Probemos con el umbral desatendido ahora.
Umbral no controlado
Umbral no controlado Scikit-image tiene una serie de métodos automáticos de determinación de umbral que no requieren entrada al elegir el umbral óptimo. Estos son algunos de los métodos: otsu, li, local.
text_threshold = filters.threshold_
Izquierda otsu || Derecha: liEn el caso de local, también necesitamos especificar block_size. La compensación ayuda a ajustar la imagen para obtener mejores resultados.
text_threshold = filters.threshold_local(text,block_size=51, offset=10) image_show(text > text_threshold);

Este método da un muy buen efecto. En gran medida, uno puede deshacerse de las regiones ruidosas.
Segmentación con un algoritmo para un modelo con un profesor.
El umbral es un proceso de segmentación muy simple, y no funcionará correctamente en una imagen de alto contraste, para lo cual necesitaremos herramientas más avanzadas.
En esta sección, utilizaremos una imagen de ejemplo que está disponible gratuitamente y trataremos de segmentar la parte de la cabeza utilizando métodos con el maestro.
Antes de hacer cualquier segmentación de imagen, se recomienda eliminar el ruido utilizando algunos filtros.Sin embargo, en nuestro caso, la imagen no tiene un ruido significativo, por lo que la aceptaremos tal cual. El siguiente paso es convertir la imagen a escala de grises usando rgb2gray.
image_gray = color.rgb2gray(image) image_show(image_gray);

Utilizaremos dos métodos de segmentación que funcionan con principios completamente diferentes.
Segmentación activa del contorno
La segmentación de la ruta activa también se llama serpiente y se inicializa usando una ruta o línea definida por el usuario alrededor de una región de interés, y luego esta ruta se comprime lentamente y es atraída o repelida por la luz y los bordes.
Para nuestra imagen de ejemplo, dibujemos un círculo alrededor de la cabeza humana para inicializar la serpiente.
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)
Los cálculos anteriores calculan las coordenadas xey de los puntos en la periferia del círculo. Como le dimos una resolución de 200, calculará 200 de esos puntos.
fig, ax = image_show(image) ax.plot(points[:, 0], points[:, 1], '--r', lw=3)

Luego, el algoritmo segmenta la cara de la persona del resto de la imagen, ajustando una curva cerrada a los bordes de la cara.

Podemos configurar parámetros llamados alfa y beta. Los valores alfa más altos hacen que la curva se contraiga más rápido, mientras que la beta hace que la curva sea más suave.
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);

Segmentación aleatoria del caminante
En este método, la segmentación se lleva a cabo mediante el etiquetado interactivo, que se denomina etiquetas. Al dibujar cada píxel en la etiqueta para la que se calcula la mayor probabilidad, puede obtener una segmentación de imagen de alta calidad. Se pueden encontrar más detalles sobre este método en
este trabajo.
A continuación, utilizaremos nuevamente los valores anteriores de nuestro ejemplo. Podríamos haber hecho diferentes inicializaciones, pero por simplicidad, ceñámonos al principio de los círculos.
image_labels = np.zeros(image_gray.shape, dtype=np.uint8)
El algoritmo de paso aleatorio acepta etiquetas como entrada. Por lo tanto, tendremos un círculo grande que cubra toda la cara de la persona, y otro círculo más pequeño cerca del centro de la cara.
indices = draw.circle_perimeter(80, 250,20)

Ahora usemos Random Walker y veamos qué sucede.
image_segmented = seg.random_walker(image_gray, image_labels)

El resultado no es el mejor, los bordes de la cara permanecieron inalcanzados. Para corregir esta situación, podemos ajustar el parámetro de pasaje hasta obtener el resultado deseado. Después de varios intentos, establecemos el valor en 3000, que funciona bastante 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);

Todo esto es para la segmentación con el profesor, donde tuvimos que proporcionar ciertos datos de entrada, así como configurar algunos parámetros. Sin embargo, no siempre es posible que una persona mire la imagen y luego decida qué contribución dar y por dónde comenzar. Afortunadamente, para tales situaciones, tenemos métodos de segmentación no controlados.
Segmentación sin profesor
La segmentación sin un maestro no requiere conocimiento previo. Considere una imagen que es tan grande que es imposible ver todos los píxeles a la vez. Por lo tanto, en tales casos, la segmentación sin un maestro puede dividir la imagen en varias subregiones, por lo que en lugar de millones de píxeles, tiene decenas o cientos de áreas. Veamos dos de estos algoritmos:
Agrupación iterativa lineal simple
El método (inglés Simple Linear Iterative Clustering o SLIC) utiliza un algoritmo de aprendizaje automático llamado K-Means. Toma todos los valores de píxeles de la imagen e intenta dividirlos en un número determinado de subdominios. Lea
este trabajo para obtener información detallada.
SLIC funciona con diferentes colores, por lo que utilizaremos la imagen original.
image_slic = seg.slic(image,n_segments=155)
Todo lo que necesitamos hacer es simplemente establecer un valor promedio para cada segmento que encontremos, lo que hace que se parezca más a una imagen.

Redujimos esta imagen de 512 * 512 = 262,000 píxeles a 155 segmentos.
Felzenszwalb
Este método también utiliza un algoritmo de aprendizaje automático denominado agrupamiento de árbol de mínima extensión. Felzenszwaib no nos dice el número exacto de grupos en los que se dividirá la imagen. Generará todos los grupos que considere adecuados para esto.
image_felzenszwalb = seg.felzenszwalb(image) image_show(image_felzenszwalb);

Hay demasiadas regiones en la imagen. Vamos a contar la cantidad de segmentos únicos.
np.unique(image_felzenszwalb).size 3368
Ahora volvamos a colorearlos usando el valor promedio sobre el segmento, como lo hicimos en el algoritmo SLIC.
image_felzenszwalb_colored = color.label2rgb(image_felzenszwalb, image, kind='avg') image_show(image_felzenszwalb_colored);
Ahora tenemos menos segmentos. Si quisiéramos incluso menos segmentos, podríamos cambiar el parámetro de escala. Este enfoque a veces se llama sobre segmentación.

Esto es más como una imagen posterizada, que es esencialmente solo una reducción en la cantidad de colores. Para combinarlos de nuevo (RAG).
Conclusión
La segmentación de imágenes es un paso muy importante en el procesamiento de imágenes. Esta es un área activa de investigación con una variedad de aplicaciones, que van desde visión por computadora hasta imágenes médicas, tráfico y video vigilancia. Python proporciona una biblioteca robusta de imágenes scikit con una gran cantidad de algoritmos de procesamiento de imágenes. Está disponible de forma gratuita y sin restricciones, respaldado por una comunidad activa. Le recomiendo que lea su documentación. El artículo original se puede encontrar
aquí .