Bibliotecas

Para a leitura e visualização da imagem irei utilizar o pacote imager. Ademais, os pacotes dplyr e ggplot2 serão usados para manipulação de dados e visualização da área extraida ao final do experimento.

library(imager)
library(ggplot2)
library(dplyr)

Leitura da Imagem

Vamos ler a imagem através da função imager::load.image:

img <- load.image('https://medpix.nlm.nih.gov/images/full/synpic54624.jpg')

Imagem original

Imagem original

A imagem utilizada no experimento possui as seguintes dimensões: 555 \(\times\) 623.

O array 4D (Padrão CImg) que representa a imagem tem dimensão:

dim(img)
## [1] 555 623   1   3

Por termos uma imagem RGB, temos três canais de cores… contudo, irei extrair a imagem em escala de cinza utilizando a função imager::grayscale, pelo método LUMA, i.e, uma combinação linear das três componentes RGB.

img_gray <- img %>% grayscale %>% as.matrix

Experimento

O melhor resultado até o momento de escrita desse trabalho foi obtido com o processamento da imagem obedecendo o seguinte fluxo:

O Fluxo começa com a obtenção do negativo da imagem, já que o tumor está na parte de baixa intensidade. Após, os filtros de sobel são empregados para evidenciar as possiveis bordas do tumor. Em seguida, adicionamos o filtro à imagem original e reescalonamos para o intervalo [0, 1]. Prosseguindo, utilizamos um processo de “alongamento” de intensidades no intervalo [0.35, 0.55]. Após, aplicamos um kernel suavizante gaussiano e, finalmente, binarizamos a imagem com um limiar de 0.29 e extraimos as regiões conectadas (filtrando para manter a maior e mais homogênea (< var) região, o tumor).

O Código para obtenção do resultado final de segmentação segue:

img_filter <- img_gray %>%
  apply_linear_kernel(kernel = kernel_sobel(horizontal = T)) %>%
  apply_linear_kernel(kernel = kernel_sobel(horizontal = F)) 

img_filtered <- minmax(img_gray + img_filter)
img_bin <- img_filtered %>%
  histogram_stretch(0.35, 0.55) %>% 
  apply_linear_kernel(kernel_gaussian(5, sigma = 10)) %>%
  as.cimg %>% threshold(0.29)

connections <- img_bin %>% split_connected

connections %>% 
  purrr::keep(~ sum(.) > 5000) %>% 
  purrr::keep(~ var(as.data.frame(.)$x) < 1000) %>%
  plot