繁体   English   中英

如何确定R中图像某种颜色的比例?

[英]How can I determine the proportion of a certain colour of an image in R?

我正在尝试编写一个脚本来区分彩色液滴的数量/表面积与图像的白色背景:

bluedroplets.png

我刚开始定义颜色:

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

并将它们转换为 rgb 色度坐标(如 Sonnentag 等人 2012 年所建议的;DOI:10.1016/j.agrformet.2011.09.009):

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

由于水滴可能具有不同的颜色深度,我还创建了一个“过多的蓝色”(对于蓝色水滴),这也适用于上面的论文(他们使用过多的绿色来描述冠层的绿色)

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

我可能想使用密度曲线来确定颜色阈值并获得该图像的蓝色液滴的份额,但我不知道如何对其应用代码。 其次,我想在同一张图片中使用另一种颜色(例如红色)。

谢谢你的帮助!

蒂莫

这不是一项简单的任务,除非您强烈希望重新发明许多轮子,否则您也不应该尝试在基础 R 中进行!

幸运的是,有一些软件包可以提供帮助。 由于您的任务类似于分析细胞显微图像所面临的任务,因此从 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))

在此处输入图片说明

这些通道看起来都高度相关(事实上,如果你在红色通道上回归绿色通道,你会得到调整后的 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%。

reprex 包(v0.3.0) 于 2020 年 2 月 28 日创建

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM