En este momento estoy tratando con algo de procesamiento de imágenes en Python a través de PIL (Python Image Library). Mi objetivo principal es contar el número de células coloreadas en una imagen inmunohistoquímica. Sé que hay programas relevantes, bibliotecas, funciones y tutoriales al respecto, y revisé casi todos. Mi objetivo principal es escribir el código manualmente desde cero, tanto como sea posible. Por lo tanto, estoy tratando de evitar el uso de muchas bibliotecas y funciones exteriores. He escrito la mayor parte del programa. Así que aquí está lo que está sucediendo paso a paso:
El programa toma el archivo de imagen:
Y lo procesa para los glóbulos rojos (básicamente, apaga los valores RGB por debajo de un cierto umbral para el rojo):
Y crea el mapa booleano del mismo (va a pegar una parte ya que es grande) que básicamente pone 1 donde sea que se encuentre con un píxel rojo en la segunda imagen procesada de arriba.
22222222222222222222222222222222222222222
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000011111100000000000000000001100002
20000000001111100000000000000000011111002
20000000000110000000000000000000011111002
20000000000000000000000000000000111111002
20000000000000000000000000000000111111102
20000000000000000000000000000001111111102
20000000000000000000000000000001111111102
20000000000000000000000000000000111111002
20000000000000000000000000000000010000002
20000000000000000000000000000000000000002
22222222222222222222222222222222222222222
Intencionalmente generé ese marco como cosa en los bordes con 2s para ayudarme a contar el número de grupos de 1s en ese mapa booleano.
Mi pregunta para ustedes es, ¿cómo puedo contar eficientemente el número de celdas (grupos de 1s) en ese tipo de mapa booleano? Encontré http://en.wikipedia.org/wiki/Connected-component_labeling que se ve extremadamente relacionado y similar, pero por lo que veo, está en el nivel de píxeles. El mío está en el nivel booleano. Solo 1s y 0s.
Muchas gracias.
Respuestas:
Algo así como un enfoque de fuerza bruta, pero hecho invirtiendo el problema para indexar sobre colecciones de píxeles para encontrar regiones, en lugar de rasterizar sobre la matriz.
Huellas dactilares:
fuente
Scipy
hacerlo, que probablemente también sea más rápida ^^ 'Pero probablemente sea un buen ejercicio de todos modos y muestra cómo hacerlo en general. Entonces votaré.Puede usar
ndimage.label
, que es una buena manera de hacer esto. Devuelve una nueva matriz, con cada característica que tiene un valor único y el número de características. También puede especificar un elemento de conexión.fuente
Aquí hay un algoritmo que es O (número total de píxeles + número de píxeles de celda). Simplemente escaneamos la imagen en busca de píxeles de celda, y cuando encontramos una, llenamos la celda para borrarla.
Implementación en Common Lisp, pero podrás traducirlo a Python trivialmente.
fuente
Más un comentario extendido que una respuesta:
Como @interjay ha insinuado, en una imagen binaria, es decir, una en la que solo hay 2 colores, los píxeles toman el valor 1 o 0. Esto puede ser cierto o no en el formato de representación de imagen que está utilizando, pero es cierto en la representación 'conceptual' de tu imagen; no permita que los detalles de implementación lo confundan con este problema. Uno de esos detalles de implementación es el uso de 2s alrededor del borde de la imagen, una forma perfectamente sensata de identificar la zona muerta alrededor de la imagen, pero sin afectar cualitativamente el carácter binario de la imagen.
En cuanto al examen de los píxeles N, NE, NW y W: esto tiene que ver con la conectividad de píxeles en la formación del componente. Cada píxel (excepto los casos especiales de borde) tiene 8 vecinos (N, S, E, W, NE, NW, SE, SW) pero ¿cuáles son candidatos para su inclusión en el mismo componente? A veces, los componentes que se encuentran solo en las esquinas (NE, NW, SE, SW) no se consideran conectados, a veces sí.
Debe decidir qué es apropiado para su aplicación. Le sugiero que realice, a mano, algunas operaciones del algoritmo secuencial, verificando diferentes vecinos para cada píxel, para tener una idea de lo que está sucediendo.
fuente