Как я могу определить пропорцию определенного цвета изображения в R? - PullRequest
1 голос
/ 28 февраля 2020

Я пытаюсь написать скрипт, чтобы отличить guish количество / площадь поверхности цветных капель от белого фона изображения:

bluedroplets.png

Я только начал с определения цветов:

   red   <- as.vector(image[,,1])
   green <- as.vector(image[,,2])
   blue  <- as.vector(image[,,3])  
   white <- (red + green+ blue)

и преобразования их в координаты rgb chromati c (как предложено в Sonnentag et al. 2012; DOI: 10.1016 / j.agrformet.2011.09.009) :

   rcc <- red/white
   gcc <- green/white
   bcc <- blue/white

Так как капли могут иметь разную глубину цвета, я также создал «избыток синего» (для синих капель), который также адаптирован к статье выше (там они используют чрезмерный зеленый для описания зелени навеса) )

   excess_blue <- (2*bcc - (rcc+gcc))

Я могу использовать кривые плотности, чтобы определить пороги цвета и получить долю капель синего цвета на этом изображении, но я не знаю, как применить код к этому. Во-вторых, я хотел бы, чтобы на том же рисунке был выделен другой цвет (например, красный).

Спасибо за вашу помощь!

Тимо

1 Ответ

2 голосов
/ 28 февраля 2020

Это не простая задача, которую вы не должны пытаться выполнить на базе R, если у вас нет сильного желания заново изобретать много колес!

К счастью, есть несколько пакетов, которые могут помочь. Поскольку ваша задача аналогична той, с которой сталкиваются при анализе микроскопических c изображений клеток, хорошее место для начала - на странице просмотра медицинской визуализации CRAN

Здесь вы найдете ссылки к некоторым полезным пакетам, включая EBImage, который размещен на Bioconductor, а не на CRAN, поэтому вам придется установить его, используя:

install.packages("BiocManager")
BiocManager::install("EBImage")

Я адаптировал примеры, приведенные во введении EBImage стр. здесь.

Сначала мы загрузим пакет и убедимся, что можем прочитать ваше изображение:

library(EBImage)

dots <- readImage("~/blue_dots.png")
display(dots, method = "raster")

Смотрит хорошо. Теперь, поскольку точки имеют зеленовато-синий цвет, а остальная часть изображения - белый, канал с самой высокой контрастностью будет красным каналом. Давайте подтвердим это визуально:

par(mfrow = c(2, 2))
plot(dots)
text(140, 140, "All", cex = 3)
plot(getFrame(dots, 1))
text(140, 140, "Red", cex = 3, col = "red")
plot(getFrame(dots, 2))
text(140, 140, "Green", cex = 3, col = "green")
plot(getFrame(dots, 3))
text(140, 140, "Blue", cex = 3, col = "blue")
par(mfrow = c(1, 1))

enter image description here

Все каналы выглядят сильно коррелированными (на самом деле, если вы регрессируете зеленый канал на красный канал, вы получите скорректированный R в квадрате> 0,9).

Поэтому мы просто используем красный канал, чтобы найти точки. Мы извлекаем красный канал с помощью getFrame и находим оптимальное пороговое значение с помощью otsu:

dots <- getFrame(dots, 1)
threshold <- otsu(dots)
thresh_dots <- dots < threshold

Теперь мы убедились, что этот порог правильно выбрал наши точки:

display(thresh_dots)

Опять же, это выглядит довольно хорошо. Теперь мы можем попытаться посчитать точки, попросив пакет дать каждому отдельному региону свой номер. Мы можем убедиться, что это сработало визуально, выделив разные цвета для всех неподключенных областей:

nmask <- watershed( distmap(thresh_dots), 5)
display(colorLabels(nmask))

Довольно! И довольно хорошо согласно случайному осмотру. Вы можете увидеть сложность определения того, что такое точка, если вы посмотрите на большое «брызги» в нижней части изображения. Наш алгоритм назвал эти две точки, хотя можно утверждать, что это три или даже четыре точки (и мы могли бы изменить параметр водораздела, чтобы изменить это, если это было важно).

Теперь мы можем посчитать количество неподключенных областей, чтобы дать нам количество точек на странице:

length(table(bwlabel(thresh_dots)))
#> [1] 1576

И мы можем получить пропорцию нашего изображения, которая выше порогового значения, как это:

length(which(nmask > 0.5))/length(nmask)
#> [1] 0.134278

Таким образом, количество синих точек на изображении составляет около 1576, а процентное соотношение изображения, покрытого синими точками, составляет 13,43%.

Создано в 2020-02-28 с помощью представьте пакет (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...