Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selection of data in a region of interest in a matrix (with Mathematica)

I am having a (mathematica 8.0.1.0-) problem which I cannot solve by myself. I have measurement data in a matrix, I want to select some of them and then add them up.

To explain my problem better, here an easy example. The data can be produced by a matrix S:

S = Table[ -Sin[i/2] - Sin[j/2], {i,20}, {j,20}];

They can be nicely plotted with:

xmin = N[Min[S]]; 
xmax = N[Max[S]]; 
mycolorfun = Function[ Blend[{Blue,Cyan,Green,Yellow,Red},#] ];

and

MatrixPlot[S, PlotRange -> {All,All,All}, AspectRatio -> 1/1,
   ColorFunction -> (mycolorfun[ Rescale[ #1{xmin,xmax} ] ]&),
   ColorFunctionScaling -> False, MaxPlotPoints -> Automatic,
   FrameLabel -> {y,x} ]

Then one should get a picture similar to this one:

enter image description here

Now I want to select the data which are inside of the brown drawn polygon. These data should be added up at the end.

How can I do this? Ok, I could use rectangles and build a sub-matrix by choosing/guessing good start and end indices. Then I just have to build the sum of this sub-matrix. But I would prefer polygons (more precise if we do not argue about little problems with the matrix values which are crossed by the line of the polygon). And I would love it if I could select my region of interest (ROI) directly by “painting” the polygon into the Matrix (no more time consuming choosing/guessing of matrix indices).
Could somebody here help me with my problem? If it is not solvable with mathematica, is there some other program which I could use?

I would be very happy about some help and hints!

like image 224
partial81 Avatar asked Jul 13 '11 12:07

partial81


2 Answers

If selecting the area of interest graphically by hand is not a problem, then you could:

First, create an image out of your data, using a visualization which makes it easy for you to select manually afterward:

S = Table[-Sin[i/50.] - Sin[j/50.], {i, 400}, {j, 400}];
img = ReliefImage@S

Then use the Front End Graphic Tools to draw the polygon over the region that interests you (right click mouse button):

enter image description here

Follow by getting the mask that corresponds to your polygon (again, right click button):

enter image description here

Finally, make a binary image out of the mask and use it to recover the sum of the pixel inside the polygon:

Total[S*ImageData@mask, Infinity]

The whole process looks like this:

enter image description here

EDIT: If you'd like to define your area of interest using a free-hand contour, use the Free-hand line tool instead of polygon. Make sure to increase the width of the stroke so that it is easy to close the contour when drawing. You may do so by moving the Stroke>Thickness slider to the right.

That would look like this:

enter image description here

Then create the mask by filling the inside of the free-hand contour using the function FillingTransform, and proceed as before:

enter image description here

like image 132
Matthias Odisio Avatar answered Sep 19 '22 06:09

Matthias Odisio


Perhaps this:

upl = 20;
s = Table[-Sin[i/2] - Sin[j/2], {i, upl}, {j, upl}];

xmin = N[Min[s]]; xmax = N[Max[s]]; mycolorfun = 
Function[Blend[{Blue, Cyan, Green, Yellow, Red}, #]];

mp = MatrixPlot[s, PlotRange -> {All, All, All}, AspectRatio -> 1/1, 
ColorFunction -> (mycolorfun[Rescale[#1, {xmin, xmax}]] &), 
ColorFunctionScaling -> False, MaxPlotPoints -> Automatic, 
FrameLabel -> {"y", "x"}];
Manipulate[
{{x1, y1}, {x2, y2}} = 
 Floor /@ {{p1[[1]], upl - p1[[2]]}, {p2[[1]], upl - p2[[2]]}};
    mp,
{{p1, {1, 1}}, Locator}, {{p2, {19, 19}}, Locator}]

Dynamic[{{x1, y1}, {x2, y2}}]
Dynamic[N@s[[y2 ;; y1, x1 ;; x2]] // MatrixForm]

which produces things like enter image description here with the part of the matrix updated live as you move the locators.

To create polygons instead, just add more locators. Selecting the part of the matrix is then more complicated and it depends on how you want things output.

like image 38
acl Avatar answered Sep 21 '22 06:09

acl