6
$\begingroup$

Here is a microscopy image of some cells I want to make measurements on with Mathematica:

microscopy image of Cells

In order to make some measurements of cells in a microscopy image I have written a simple dynamic overlay of a LocatorPane on top of my image of cells. The LocatorPane draws a polygon on top of my microscopy image to allow me to measure a cell of interest or create a mask for that cell:

image of Cells with polygon LocatorPane overlay

Here is the code I am using for this:

pts = {{201, 428}, {227, 404}, {261, 405}, {282, 414}, {255, 
    441}, {233, 457}, {218, 469}, {196, 469}, {188, 454}};

Framed[     
 Overlay[      
  {       
   Dynamic@imageOfCells,       
   LocatorPane[Dynamic[pts], 
    Dynamic[Graphics[{Red, Opacity[0.25], Polygon[pts]}, 
      PlotRange -> {{1, 600}, {1, 600}}, ImageSize -> {600, 600}]], 
    LocatorAutoCreate -> True, 
    Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 10]]       
   }
   , All, 2, ImageSize -> All, Alignment -> {Automatic, Automatic}      
  ] (*close Overlay *)     
 ]

Already there may be a small problem of alignment and/or unequal image sizes as the frame around the image is not quite symmetrical and on the right-edge of the frame you can move locators off the image. The image is 600x600 (check with ImageDimensions) and the Polygon graphics in the LocatorPane has a PlotRange->{{1,600},{{1,600}} and the ImageSize of the Plot is also {600,600} so I'm not sure what I am doing wrong here. Maybe just an ImageMargin or ImagePadding tweak is needed?

In any case, the main problem I am having is that when I try to put this overlay into a column (or a grid or a row) with a Button beneath it (the button is to allow me to store the coordinates of interest in a list), the overlay falls apart and the background image of the cells shrinks unexpectedly and becomes misaligned. Here is what it looks like:

background of overlay misaligned and too small

Here is the code I am using (I have put it inside a DynamicModule but the overlay still falls apart if you remove DynamicModule and just have it in a Column):

 DynamicModule[{pts = {{201, 428}, {227, 404}, {261, 405}, {282, 
     414}, {255, 441}, {233, 457}, {218, 469}, {196, 469}, {188, 
     454}}},     

 pointsList = {};

 Column[{              
   Framed[        
    Overlay[         
      {          
      Dynamic@imageOfCells,          
      LocatorPane[Dynamic[pts], 
       Dynamic[Graphics[{Red, Opacity[0.25], 
          Polygon[pts(*,SplineClosed\[Rule]True*)]}(*,Point[pts]}*), 
         PlotRange -> {{1, 600}, {1, 600}}, ImageSize -> {600, 600}]],
        LocatorAutoCreate -> True, 
       Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 10]]          
      }         
     , Automatic, 2         
     ] (*close Overlay *)        
    ] (* close Framed *)       
   ,       
   Button[        
    "Store Points", AppendTo[pointsList, pts]
    ]              
   } (* close argument list to Column[] *)
  ]    (* close Column[] *)     
 ] (* close DynamicModule *)

Any suggestions on how to fix this and how to be sure the positions of the LocatorPane and the background microscopy image are really aligned?

$\endgroup$
3
  • $\begingroup$ What do you exactly want to measure: the area, perimeter, ...? $\endgroup$
    – mrz
    Commented Mar 23, 2016 at 20:39
  • $\begingroup$ @mrz I am interested in measuring area, perimeter and creating masks for the cells to be used on fluorescent channels images. Actually though I think I have the overlay inside the column solved without a somewhat inelegant work around. Still not sure if I have my polygon plot quite aligned correctly over the microscopy image yet. Any thoughts on making sure the overlay is correctly aligned so x,y coordinate (1,1) in the plot is where image coordinate (1,1) is in the image? $\endgroup$
    – user13999
    Commented Mar 23, 2016 at 20:54
  • $\begingroup$ @user13999 Why don't you post the "inelegant workaround" as a self-answer? No matter how elegant, it could still help others, and perhaps generate some discussion towards a more elegant / robust / general solution. $\endgroup$
    – MarcoB
    Commented Mar 25, 2016 at 14:42

1 Answer 1

1
$\begingroup$

The problem is certainly that your imageOfCells has no ImageSize -> ... option. In this case the size of the displayed Image[...]depends on the environment of the image (alone in a cell, in a list, as a function parameter). The solution is simply to had the option ImageSize ->{600,600}to your image :

imageOfCells=Import["https://i.sstatic.net/JQQbJ.jpg"];

DynamicModule[{pts = {{201, 428}, {227, 404}, {261, 405}, {282, 
     414}, {255, 441}, {233, 457}, {218, 469}, {196, 469}, {188, 
     454}}},

pointsList = {};
Column[{
   Framed[
    Overlay[
     {
      Dynamic (* Dynamic is here useless *) @ Image[imageOfCells,ImageSize -> {600, 600}],
      LocatorPane[Dynamic[pts], 
       Dynamic[Graphics[{Red, Opacity[0.25], 
          Polygon[pts(*,SplineClosed\[Rule]True*)]}(*,Point[pts]}*), 
         PlotRange -> {{1, 600}, {1, 600}}, ImageSize -> {600, 600}]],
        LocatorAutoCreate -> True, 
       Appearance -> Graphics[{Red, Disk[]}, ImageSize -> 10]]
      }
     , Automatic, 2
     ] (*close Overlay *)
    ] (* close Framed *)
   ,
   Button[
    "Store Points", AppendTo[pointsList, pts]
    ]
   } (* close argument list to Column[] *)
  ]    (* close Column[] *)
 ] (* close DynamicModule *)

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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