I have a long-ish code which stores the grey values of an image's pixels in a matrix called data and then does some numerical analysis using those values. At one point in the code, I need to ask the user to select a region of the image to serve as a reference for the analysis of the rest of the image. To do so, I've indexed the pixels (from 1 to rows x cols, which is the number of pixels in the image) and I'm using a dynamic module where the user can draw a polygon on the image and the coordinates of the pixels inside the polygon are stored in a vector; my code for this is a variation of Heike's code here. This is my code for the dynamic module:
points=ConstantArray[0,{rows*cols,2}];
For[j=1,j<=rows,j++,
For[l=1,l<=cols,l++,
points[[(j-1)cols+l,1]]=l;
points[[(j-1)cols+l,2]]=j];];
selection[region_,pt_]:=Round[(
Total@Mod[
(#-RotateRight[#])&@(ArcTan@@(pt-#)&/@region),
2Pi,
-Pi
]/2/Pi
)];
DynamicModule[
{plot, pos},
plot=Legended[
ListDensityPlot[
data,
PlotRange->Full,
ColorFunction->"Rainbow",
ImageSize->Large
],
BarLegend[
{"Rainbow",{Min[data],Max[data]}},
LegendMarkerSize->575
]
];
Manipulate[
pos=Pick[Range[Length[points]],selection[region,#]&/@points,1];
Show[
plot,
Epilog->{
{Transparent,Point[points[[pos]]]},
{Transparent,Point[Complement[points,points[[pos]]]]},
{EdgeForm[Red],FaceForm[{Red,Opacity[0.35]}],Polygon[region]}
}
],
{{region,{}},Locator,LocatorAutoCreate->All},
Row[{
Button["confirm",MANY OPERATIONS GO HERE],
Button["undo",region=Drop[region,-1]],
Button["reset",region={};pos={}]
}]
]
]
Now, pos (the vector where the selected pixels' indices are stored) does not work outside of the dynamic module; if I close the module and then ask Mathematica to tell me what's stored in pos, all I get is pos
. Therefore, as you can see, all of the code for the analysis that takes place after the user draws the polygon is inside what the "confirm" button does.
The problem with this approach is that the code is really long and involves many operations and numerical solutions of equations and so on. This is a problem because Mathematica (10.4.1.0) doesn't seem able to handle so many operations inside a dynamic module; it stops without notice after a certain number of operations and throws an "internal error" message on the error-message window.
I've tested the code without the dynamic module (filling pos with an arbitrary amount of arbitrary integers beforehand), and the code works fine. The problem is clearly the dynamic module.
In order to avoid this, I'd like to output the result of the dynamic module (i.e. the numbers stored in pos) to the rest of the code. I thus have two questions:
- How do I do this?
- How can I a avoid forcing the user to run two separate pieces of code instead of just one? If I write
;
after the dynamic module, the module doesn't appear at all; if I don't add it, I don't know how to add code after the dynamic module without starting a new input section.
Thanks a lot in advance.