I am just beginning to learn about image processing. I would like to know

  • 1) How to show an original image with a visible mask of an arbitrary shape?

  • 2) how to calculate the pixel intensities in the region defined by the mask?

For example, I would like to be able to calculate the pixel intensities of the cells and the nuclei in the following image. Could anyone help me help me to understand how to better show the mask on the original image?

Thus far, what I have achieved is shown below, I'm not sure what to do next to do the calculations? Is there a way to compute the pixel intensities inside of the shapes generated by MorphologicalPerimeter?

image = Import@"http://i.stack.imgur.com/0ULvT.jpg";
Colorize[MorphologicalPerimeter[image, 0.125], 
  ColorFunction -> (Blend[{White, Red}, #] &)];
ImageMultiply[image, Colorize[MorphologicalPerimeter[image, 0.125], 
  ColorFunction -> (Blend[{White, Red}, #] &)]]

Mathematica graphics

  • $\begingroup$ Can you explain again what kind of masking you are looking for? What is the point of the masking? When you say "compute the pixel intensities inside the shapes" does that imply that you would like to output a matrix of intensities for each object or what? $\endgroup$ – C. E. Nov 26 '14 at 0:51
  • $\begingroup$ @Pickett I am looking to create a mask of the cell boundary, and a separate mask of the cell nucleus (localize bright region of each cell). I would then like to compute the intensities inside of each of the shapes. I.E what is the average intensity inside of each nucleus and what's the average intensity inside of each cell. These could just be a list of numbers for each cell. {Mean[nucleus_i],Mean[cell_i]} $\endgroup$ – tarhawk Nov 26 '14 at 0:57
  • $\begingroup$ ok, I see. Thank you. $\endgroup$ – C. E. Nov 26 '14 at 1:03

One way to approach this is to binarize the image twice: first to find the outer parts of the cells and then to try and locate the inner (nucleus) of the cells.

img = Import["http://i.stack.imgur.com/0ULvT.jpg"];
imgBin1 = Binarize[Dilation[img, 1]];
imgBin2 = Binarize[Dilation[img, 1], 0.6];
ColorCombine[{imgBin1, imgBin2, imgBin2}]

The final command above is just for visualization -- you can change the binarization thresholds to get a picture that better captures what you are looking for.

enter image description here

ComponentMeasurements can be used in combination with MorphologicalComponents

ComponentMeasurements[MorphologicalComponents[imgBin1], "Count"]
ComponentMeasurements[MorphologicalComponents[imgBin2], "Count"]

to find the sizes of the outer and inner regions. Similarly, the average of the intensities in each region can be found using

ComponentMeasurements[ImageMultiply[img, imgBin1], "MeanIntensity"]
ComponentMeasurements[ImageMultiply[img, imgBin2], "MeanIntensity"]
| improve this answer | |
  • $\begingroup$ Thanks for the suggestions at @bill s, I have updated the code to now take the difference in intensities between the two regions (cell and nucleus). $\endgroup$ – tarhawk Nov 27 '14 at 14:15

I will show a way to find the cells and the nucleusus with LaplacianGaussianFilter.


To find the nucleuses there many ways to define the regions, the idea here is to find local maxima, rather then absolute maxima, which the threshold does.

This finds the centers of the nucleuses.

  nucleouscenter=Binarize[ImageMultiply[MaxDetect[#], #] &@
   LaplacianGaussianFilter[ColorNegate@img, 1], 0.4]

you can check with ColorCombine that is in the centers:

   ColorCombine[{nucleouscenter, nucleouscenter, img}]

enter image description here

You can then use dilation, as the other answers to create a mask for just the nucleous.However, we use the filter parameter and a threshold.

     thenucleuses = 
          ImageMultiply[Binarize[LaplacianGaussianFilter[ColorNegate@img, 5], 0.05], img]

We cluster with MorphologicalComponents,

     compsnucl = MorphologicalComponents[thenucleuses]

enter image description here

These parameters are probably very conservative given the size of the components.

Full Cells

Similarly we can find the full cells with

     Binarize[LaplacianGaussianFilter[img, 7], 0.001]) 

enter image description here

You can adjust the size of the Laplacian filter to adjust the tolerance of the edges. In this case note that the largest component is the background, which could be useful if you are trying to measure the properties of the background also.


In a grayscale image, ImageData gives the values of the intensity at each pixel. So let's find the total intensity of each cell found in the previous section. You can use MorphologicalMeasurements, but we will do it step by step so you know what you are obtaining.

MorphologicalComponents is the clustering function. In this case it gives back the same image with cluster id as the pixel.

Since in the cell case we have clustered each plus the background plus the black borders in each cell .The number of clusters is,

DeleteDuplicates@Flatten[comps]-2 // Length


cluster 0 is the "empty" borders around each cell, 24 clusters is one for the large background and 23 "cells".

The intensity at each cell is

  clusterintensity = 
    SortBy[Function[{x}, (Part[newimg, ##] & @@@ 
     Position[comps, x])] /@ (Range[24]), Length]

I sort by length so the last one is for "large" Background

And we can then histogram the intensities.

  Histogram[((Plus@@@clusterintensity)[[1 ;; -2]])/(Plus @@  (clusterintensity[[-1]])), {0.015}, Frame -> True,PlotLabel -> "Intensity"]
  Histogram[(Length /@ clusterintensity)[[1 ;; -2]], {45}, Frame -> True, PlotLabel -> "Size (Pixel)"]

enter image description here

Note that we found 15 nucleuses versus 23 cells. It is either because of the flourescent distribution within the cell, the shape of the cell or the fact that some cells may be out of focus. That for you to figure out I suppose.

We will match the nucleus to cells by position of the centroid.

 nucleouscentroid=N /@ Mean /@ 
    (Position[compsnuc, #] & /@ Range[15])

 cellcentroid=N /@ Mean /@ 
    Most@SortBy[(Position[comps, #] & /@ Range[24]),Length]

Here is a quick and dirty way to match them.

  nucleous2cell=Flatten@(Position[#, Min[#]] & /@ 
    Function[{x}, Abs@Norm[x - #]&/@cellcentroid] /@ nucleouspos)

nucleous2cell gives us which cell links to which nucleus, the nucleus number being its index.

The nucleus intensity

    nucintensity =Plus @@@ SortBy[
       Function[{x}, (Part[newimg, ##] & @@@Position[compsnuc, x])] /@ (Range[15]), Length]

Since you probably want the ratio, we use MapIndexed with nucleous2cell

 nucintensityOvercellintensity = 
    Plus @@ (clusterintensity[[nucleous2cell[[Last@#2]]]]) &, 

Histogram[nucintensityOvercellintensity, {0.05}, Frame -> True]

enter image description here

| improve this answer | |
  • $\begingroup$ This is such a wonderful example and demonstration. Maybe you should add this to the actual demonstrations project? $\endgroup$ – tarhawk May 30 '15 at 14:41
  • $\begingroup$ I'm not sure if part of the answer was lost in editing. But there are missing components to the answer presented above. Where is newimg defined? $\endgroup$ – tarhawk Apr 26 '17 at 19:52

To calculate the ratio of mean intensities between the two regions of the cell (cytoplasm and nucleus). 1) I have used the code provided by bill s above as a starting point:
2) Next I subtracted the nucleus region from each cell using ImageSubtract.
3) I then use ComponentMeasurements to calculate the mean intensity of each cell sans the nucleus.
4) Because the threshold recognizes more cells than nuclei, I ensure that I calculate the ratio between equal numbers of both.

  img = Import["http://i.stack.imgur.com/0ULvT.jpg"];  
  imgBin1 = Binarize[Dilation[image, 1], 0.141];  
  imgBin2 = Binarize[Dilation[image, 1], 0.325];  
  ImageMultiply[image // Binarize, imgBin2 // Colorize];  
  ColorCombine[{imgBin1, imgBin2}];  
  ComponentMeasurements[MorphologicalComponents[imgBin1], "Count"];  
  ComponentMeasurements[MorphologicalComponents[imgBin2], "Count"];  
  nucleus = ComponentMeasurements[ImageMultiply[image, imgBin2], 
  cellsOnly = ImageSubtract[ImageMultiply[image, imgBin1], 
   ImageMultiply[image, imgBin2]];  

enter image description here

cell = ComponentMeasurements[cellsOnly, "MeanIntensity"];  

  difference[i_, j_] := total = {Length[i] - Length[j], Length[i], Length[j]};  
  difference[cells, nucleus]

  ratio = Mean@(nucleus[[All, 2]]/Drop[cells[[All, 2]], -total[[1]]])  

Next I will seek to ensure that the ordering of the ComponentMeasurements given by cell and nucleus correspond to the same cell and nucleus. And to ensure that the MeanIntensities of cellOnly are not being skewed by the subtraction of the nucleus from each cell. The resulting ratios seem to be okay, so I think I am on the right track.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.