For this kind of image analysis, you can check out EBImage
:
install.packages("BiocManager")
BiocManager::install("EBImage")
Your workflow might look something like this. First, load the packages and read in your image. We'll also display it to show we're on the right track:
library(EBImage)
library(ggplot2)
dots <- readImage("https://i.stack.imgur.com/3RU7u.png")
display(dots, method = "raster")
Now we can use the computeFeatures
functions to get the centroids and maximum diameter of each cluster:
dots_bw <- getFrame(dots, 1)
labelled_dots <- bwlabel(dots_bw)
df <- as.data.frame(cbind(computeFeatures.moment(labelled_dots)[, 1:2],
computeFeatures.shape(labelled_dots)[, 5:6]))
df
#> m.cx m.cy s.radius.min s.radius.max
#> 1 65.73316 25.69588 11.095535 40.69698
#> 2 156.24181 129.77241 19.377341 33.83485
#> 3 483.60853 155.23006 9.419478 16.28808
#> 4 277.21467 409.62152 20.411710 28.77508
#> 5 397.36817 607.47749 8.424518 18.53617
#> 6 224.93790 623.28266 8.530353 15.26678
Now we want to find out which dimension matches which blob, so let's plot the raster in ggplot, and write the maximum pixel dimension above each blob.
img_df <- reshape2::melt(as.matrix(as.raster(as.array(dots))))
ggplot(img_df, aes(Var1, Var2, fill = value)) +
geom_raster() +
scale_fill_identity() +
scale_y_reverse() +
geom_text(inherit.aes = FALSE, data = df, color = "white",
aes(x = m.cx, y = m.cy, label = round(s.radius.max, 1))) +
coord_equal()
If you would rather have the total number of pixels than the maximum diameter in pixels, you can also get this from computeFeatures
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…