top of page
Buscar
  • danielreyes107

Segmentador lineal manual

Segmentado lineal (manual)

Este código que veremos a continuación es un poco complicado, por lo que lo explicaremos línea por línea, se trata de una función que a partir de una imagen con tumor (obligatoriamente), genera otras tres imágenes. En la que la primera se trata de un recorte en el que se aplica zoom hacia la zona más relevante, es decir donde se encuentra el tumor, y las otras dos extraen la forma del tumor. Este código no es preciso ya que tiene una gran dependencia de los colores, y está hecho de manera manual, sin hacer uso de la arquitectura UNet


Codigo



Ya explicamos que hace esta función, pero ¿Cómo lo hace?, pues eso es lo que trataremos de explicar a continuación.


crop_segmentation_tumor, que es el nombre que recibe este método, tiene dos parámetros, el primero es la ruta de la imagen que deseamos usar y la segunda la clase a la que esta pertenece, este segundo podríamos tomarlo del propio path, pero vi más sencillo implementarlo de esta forma. Empezamos tomando la imagen, empleando imread de CV2, imread proviene de image read, que como podemos deducir, lee la imagen del archivo especificado por parámetro. Seguidamente, agregamos a grayscale una versión en blanco y negro de esta imagen aplicando cvtColor o lo que es lo mismo convert color, transformando la imagen de RGB a Grayscale (BGR2GRAY).

Una vez tenemos esa imagen en monocromático realizamos un proceso de desenfoque Gaussiano o Gaussian Blur (que lleva el nombre del matemático y científico Carl Friedrich Gauss), esta es una técnica de suavizado de imágenes, este tipo de técnicas se emplea en la reducción de ruido (ruido de las imágenes) y en la reducción de los detalles. En este caso lo aplicamos con un kernel de tamaño 5x5, es decir ira por agrupaciones de cinco píxeles y un tipo de borde constante.


Ilustración 42: Ejemplo desenfoque gaussiano (ref.)


En general, buscamos convertir una imagen en escala de grises en una imagen binaria, donde los píxeles son 0 (negro) o 255 (blanco), para ello hacemos uso de threshold, esta función contiene cuatro parámetros, la imagen a la que vamos a aplicarle este “filtro”, dos valores enteros que hacen de umbral, inferior y superior, y el formato del umbral, binario, los valores 45 y 255, por lo que todos los pixeles que se encuentre en ese rango se convertirán en blanco y el resto a negro, la elección de estos números viene a base de distintas pruebas, los valores más comúnmente usado son 127 y 225. Esta imagen “binarizada” se la almacenaremos en threshold_img.



Ilustración 43: Binarización de una radiográfica (ref.)


Sobre esta misma variable threshold_img, realizaremos dos procesos, el primero de erosión (cv2.erode), esta función generar erosiones sobre los límites del objeto en primer plano, normalmente se realiza sobre imágenes binarias y consiste en un píxel en la imagen original (ya sea 1 o 0) se considerará 1 solo si todos los píxeles debajo del kernel, son 1; de lo contrario, se erosiona (se reduce a cero). Por tanto, erode, es útil para eliminar pequeños ruidos blancos, aunque también se puede utilizar para separar dos objetos conectados. El segundo procesamiento de imagen es la dilatación (dilate), este es contrario al anterior, consiste en incrementar el área del objeto que se encuentra en “primer plano” y acentuar las características, este se define como un píxel de la imagen original (ya sea 1 o 0) tomara el valor 1 si al menos un píxel debajo del núcleo es 1.

En casos como la eliminación de ruido, la erosión va seguida de dilatación. Porque la erosión elimina los ruidos blancos, pero también encoge nuestro objeto. Entonces lo dilatamos. Dado que el ruido se ha ido, no volverá, pero el área del objeto aumentará. También es útil para unir partes rotas de un objeto. Ambos contienen un parámetro iteración y que al igual que con los valores del umbral, se han extraído tras la experiencia, este define la cantidad de veces que se van a realizar cada una de las operaciones. Las operaciones de dilatación y erosión son:


• Dilatación:

𝒅𝒔𝒕(𝒙, 𝒚) = 𝑚𝑎𝑥(𝒙′, 𝒚′): 𝒆𝒍𝒆𝒎𝒆𝒏𝒕(𝒙′, 𝒚′) ≠ 𝟎𝒔𝒓𝒄(𝒙 + 𝒙′, 𝒚 + 𝒚′)

• Erosión:

𝒅𝒔𝒕(𝒙, 𝒚) = 𝑚𝑎𝑥(𝒙′, 𝒚′): 𝒆𝒍𝒆𝒎𝒆𝒏𝒕(𝒙′, 𝒚′) ≠ 𝟎𝒔𝒓𝒄(𝒙 + 𝒙′, 𝒚 + 𝒚′)



Ilustración 44: Dilatación y erosión (ref.)


El siguiente paso consiste en hallar el contorno, para ello la utilidad findContours de OpenCV (CV2) es ideal, este es capaz de hallar los contornos externo del objeto que deseamos extrapolar de la imagen, esto se logra con el parámetro mode que hemos agregado cómo modo RETR_EXTERNAL, por otra parte, el tercer campo CHAIN_APPROX_SIMPLE, comprime los segmentos horizontales, verticales y diagonales y deja solo sus puntos finales, dejándonos cuatro propiedades cardinales.


Será necesario hallar los centros de los contornos ya que con ellos podremos tomar los puntos mínimos y máximos (o lo que es lo mismo los puntos izquierda extreme_pnts_left, derecha extreme_pnts_right, arriba extreme_pnts_top y abajo extreme_pnts_bottom, que se posicionan alrededor del tumor). Estos puntos los emplearemos finalmente para generar una imagen recortada, en cuyo interior se podrá observar en el mejor de los casos solo el tumor y un poco del contorno.

Tras generar esta nueva imagen realizaremos una agrupación de plots, en la que la primera figura consistirá en la imagen original, la segunda la contendrá la versión recortada, la tercera y la cuarta se generaran a partir de la recortada, pero aplicándoles threshold que explicamos antes, ambos con umbrales de 190 y 255, en la primera la binarización será normal es decir solo los pixeles entre ese umbral serán blancos y el resto negros y el segundo es su inversa, los pixeles entre esos valores se volverán negros y el resto blancos.



Ilustración 45: Demostración de segmentación lineal manual

7 visualizaciones0 comentarios

Entradas Recientes

Ver todo

Comments


bottom of page