This is some extremely simple code that shows an image and manipulates a circle (that will be used to select a region of the image to analyze). All those Dynamic
s eliminate some terrible lag, I understand the one for the circle, but why are the other necessary?
theImage = pickAnImage; (*mine is 368 by 252*)
Manipulate[
circularSelector = Graphics[{Yellow, Dynamic[Circle[center, radius]]}];
xRange = Dynamic[{center[[1]] - radius, center[[1]] + radius}];
yRange = Dynamic[{center[[2]] - radius, center[[2]] + radius}];
Column[{Show[theImage, circularSelector],
xRange,
yRange}],
{{center, {184, 126}}, {0, 0}, {368, 252}, 1, Locator, Appearance -> None},
{{radius, 50}, 2, 100, 1, Appearance -> "Labeled"}]
Consider now adding one line of code to show the section of the image in the selection, something like
ImageTake[theImage,xRange,yRange],
Well, that doesn't work. It works if the Dynamic
s are removed from the definition of xRange
and yRange
, but then all the lag is back!:
theImage = pickAnImage; (*mine is 368 by 252*)
Manipulate[
circularSelector = Graphics[{Yellow, Dynamic[Circle[center, radius]]}];
xRange = {center[[1]] - radius, center[[1]] + radius};
yRange = {center[[2]] - radius, center[[2]] + radius};
Column[{Show[theImage, circularSelector],
xRange,
yRange,
ImageTake[theImage, yRange, xRange]}],
{{center, {184, 126}}, {0, 0}, {368, 252}, 1, Locator, Appearance -> None},
{{radius, 50}, 2, 100, 1, Appearance -> "Labeled"}]
How do I fix this? More importantly, what's the reason behind it? When using Manipulate
, I seem to run into lag and this Dynamic
stuff seems to be behind it. I've checked the usual resources, but something as simple as this (A Manipulate
with several images, or how to optimize code for snappiness) is rarely described.
EDIT: As requested by Nasser (thanks btw) I'm adding the code that doesn't work (selection is not shown):
theImage = pickAnImage; (*mine is 368 by 252*)
Manipulate[
circularSelector =
Graphics[{Yellow, Dynamic[Circle[center, radius]]}];
xRange = Dynamic[{center[[1]] - radius, center[[1]] + radius}];
yRange = Dynamic[{center[[2]] - radius, center[[2]] + radius}];
Column[{Show[theImage, circularSelector],
xRange,
yRange,
ImageTake[theImage, yRange, xRange]}],
{{center, {184, 126}}, {0, 0}, {368, 252}, 1, Locator, Appearance -> None},
{{radius, 50}, 2, 100, 1, Appearance -> "Labeled"}]
As mentioned before, if the Dynamic
are removed from xRange and yRange this works (second code above), but moving the circle is laggy compared to the first code (and it will get worst once more complex code is added).