Search code examples
rimagefeature-detection

Plotting numbers of features in EBImage in R


I have a question regarding the computeFeatures function of EBImage. I used the following code to compute the features.

biocLite("EBImage")
library (EBImage)
Image <- readImage("test.jpg")
Image3<-getFrame(Image,3)
x = thresh(Image3, w=15, h=15, offset=0.05) 
x = opening(x, makeBrush(5, shape='disc')) 
x = bwlabel(x) 
fts = computeFeatures.shape(x) 

This gives me a list of the computed features. However, this is a list of 39 features, and I am only interested in a few of them. Thus I would like to know which of the computeFeatures correspond to each features in the image.

A solution was presented at http://www.bricol.net/research/leafranks/11-01MS/EBImage-introduction.pdf by using the following code:

> nmask = thresh(nuc, 10, 10, 0.05) 
> nmask = opening(nmask, makeBrush(5, shape='disc')) 
> nmask = fillHull(nmask) 
> nmask = bwlabel(nmask) Cell bodies are segmented using propagate. 
> ctmask = opening(cel>0.1, makeBrush(5, shape='disc')) 
> cmask = propagate(cel, nmask, ctmask)
> res = paintObjects(cmask, img, col='#ff00ff') 
> res = paintObjects(nmask, res, col='#ffff00')
> xy = lapply(hullFeatures(cmask), function(hf) hf[, c('g.x', 'g.y')]) 
> labels = lapply(xy, function(z) as.character(1:nrow(z))) 
> font = drawfont(weight=600, size=16) 
> res = drawtext(res, xy=xy, labels=labels , font=font, col="white")

Which plots numbers corresponding to the features on the Image. However, the function hullFeatures is no longer available.

Thus, is there an other way to plot the number of the features or objects in the Image?


Solution

  • The functions hullFeatures and drawtext are defunct. hullFeatures has been replaced by computeFeatures.shape. Now one needs to use computeFeatures.moment to find the position of each object. The base text function is now used to add text to an image plotted in raster mode.

    A great overview of EBImage can be found in the vignette: vignette("EBImage-introduction", package = "EBImage"). However, with version 4.22.1, the vignette no longer shows how to number the segmented objects. Here's a recreation of the example from the PDF dated April 22, 2010 by Pau, Sklyar and Huber.

    To clarify the nomenclature a bit, the computeFeatures family of functions return a matrix of dimension n x p where n is the number of segmented objects (rows) and p is the number of features (columns). In this example, each object is a cell. The features returned by computeFeatures.moment are m.cx, m.cy, m.majoraxis, m.eccentricity and m.theta. The position is specified by the first two features.

    # Starting from EBImage
      if (!require(EBImage)) {
        source("http://bioconductor.org/biocLite.R")
        biocLite("EBImage")
        library(EBImage)
      }
    
    # Use example nuclei and cells, make colorized composite
      nuc <- readImage(system.file('images', 'nuclei.tif', package='EBImage'))
      cel <- readImage(system.file('images', 'cells.tif', package='EBImage'))
      img <- rgbImage(green=1.5*cel, blue=nuc)
    
    # Recreate nuclear and cell masks, add border to color composite
      nmask <- thresh(nuc, 10, 10, 0.05)
      nmask <- opening(nmask, makeBrush(5, shape='disc')) 
      nmask <- fillHull(nmask) 
      nmask <- bwlabel(nmask)
      ctmask <- opening(cel>0.1, makeBrush(5, shape='disc')) 
      cmask <- propagate(cel, nmask, ctmask)
      res <- paintObjects(cmask, img, col='#ff00ff') 
      res <- paintObjects(nmask, res, col='#ffff00')
    
    # Determine position (center of mass) of each object in 'cmask'
      M <- apply(cmask, 3, computeFeatures.moment) # list of length 4 returned
      xy <- lapply(M, function(m) m[,c("m.cx", "m.cy")])
    
    # Create labels and plot in 'raster' mode 
      labels <- lapply(xy, function(z) as.character(1:nrow(z)))
      plot(getFrame(res, 3, type = "render")) # or plot(res[,,,3])
    
    # Add labels by text function
      text(xy[[3]], labels[[3]], col = "white")
    

    frame 3 of example with numbered cells