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:
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!
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):
Follow by getting the mask that corresponds to your polygon (again, right click button):
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:
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:
Then create the mask by filling the inside of the free-hand contour using the function FillingTransform
, and proceed as before:
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 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With