mlampros / SuperpixelImageSegmentation

Image Segmentation using Superpixels, Affinity Propagation and Kmeans Clustering
https://mlampros.github.io/SuperpixelImageSegmentation/
18 stars 6 forks source link

Segment Morphological Features? #3

Closed LiamMacNeil closed 1 year ago

LiamMacNeil commented 1 year ago

Hi Lampros,

Is there any functionality for morphological operations on segments (e.g., area, length, etc.)? Or any compatibility with EBImage::computefeatures.shape on segment masks?

Thank you for the great package functions!

mlampros commented 1 year ago

hi @LiamMacNeil,

The 'SuperpixelImageSegmentation' package allows to compute the segments only.

I wasn't aware of the 'computefeatures.shape' function so I had to run the following example from the 'EBImage' R package,

  require(EBImage)
  ## load and segment nucleus
  y = readImage(system.file("images", "nuclei.tif", package="EBImage"))[,,1]
  x = thresh(y, 10, 10, 0.05)
  x = opening(x, makeBrush(5, shape='disc'))
  x = bwlabel(x)
  display(y, title="Cell nuclei")
  display(x, title="Segmented nuclei")

  ## compute shape features
  fts = computeFeatures.shape(x)
# > fts
#   s.area s.perimeter s.radius.mean s.radius.sd s.radius.min s.radius.max
# 1      25          18      2.526282   1.0775468    0.8888889     4.097575
# 2     127          36      5.935332   0.9142652    3.8611111     7.704065
# 3      36          26      3.454497   1.7139869    0.8846154     6.064861
# 4      81          31      4.794818   1.2394572    2.7921400     6.978486

Thus, the functions of the EBImage allows to extract the 77 segmented areas for which specific features are computed,


dim(fts)
# [1] 77  6

In one of the latest versions of the package I added the 'return_labels_2_dimensionsional' parameter so that the user can receive also the segments (including the background) in form of labels (or clusters). The following is just an example based on the previous image of the 'EBImage' package (but using the first 3 dimensions),


require(EBImage)
require(OpenImageR)
require(SuperpixelImageSegmentation)

## load and segment nucleus
y = EBImage::readImage(system.file("images", "nuclei.tif", package="EBImage"))[,,1:3]

y_mt = y@.Data
dim(y_mt)
str(y_mt)

OpenImageR::imageShow(y_mt)

init = Image_Segmentation$new()

num_spix = 600

set.seed(seed = 1)
spx = init$spixel_segmentation(input_image = y_mt,
                               method = "slic",
                               superpixel = num_spix,
                               colour_type = 'LAB',
                               AP_data = TRUE,
                               use_median = TRUE,
                               return_labels_2_dimensionsional = TRUE,      # returns the segments
                               sim_color_radius = 20,
                               verbose = T)

str(spx)
str(spx$spix_labels)
image(spx$spix_labels)

clusters = spx$spix_labels

# assuming (visually) that the clusters 1 and 2 correspond to background
clusters[1:40, 1:40]

# set these to background (or to the value of 0)
clusters[clusters %in% 1:2] = 0

# and the remaining segments to 1
clusters[clusters != 0] = 1

image(clusters)

The separation of the segments can be approximated but then the user has to find a way to extract the shapes from this binary image and compute the statistics.

mlampros commented 1 year ago

feel free to open an issue if the code of the 'SuperpixelImageSegmentation' R package does not work as expected.

LiamMacNeil commented 1 year ago

Hi @mlampros,

Thank you for the example of cluster extraction, It should work as expected, just requiring some extra work on my end to extract morphology with other packages.

Cheers.