Reputation: 11
I'm writing an ImageJ Macro to help with a complex tissue analysis. One function in this macro inputs an image with 3 existing non-overlapping ROIs, waits for the user to manually select a new ROI and confirm their selection by pressing the spacebar, and then works to detect which existing ROI the user's new ROI overlaps to determine the new ROI's name, then saves the ROI to measure its area and overlay it over the image.
For example, if the image's 3 existing ROIs are ROI_1, ROI_2, and ROI_3, and the user's new ROI overlaps with ROI_2, the new ROI should be saved as ROI_2_NC.
Below is my code, which works for one user-generated ROI.
while (true){
if (isKeyDown("space") == true){ // user presses space after selecting an ROI
roiManager("add");
for (m = 0; m < 3; m++) { // cycle through the existing 3 ROIs in the image
roiManager("Select", newArray(m, roiManager("count")-1));
roiManager("AND"); // look for overlaps
if (selectionType() != -1) {
roiManager("Deselect");
lesionname = RoiManager.getName(m);
roiManager("Select", roiManager("count")-1); // the newest ROI
roiManager("Rename", lesionname + "_NC");
roiManager("measure");
Overlay.addSelection;
break();
}
roiManager("Deselect"); // make sure we are starting again from scratch
}
}
break();
wait(100); // protects against multiple detection of single keystroke
}
print("done");
However, I want to allow the user to select as many ROIs as they wish in this image (hitting spacebar every time) until they choose to exit (by hitting ALT).
I've tried to add a requirement for ALT before the break(); command which exits the while loop, as below (new addition in BOLD):
while (true){
if (isKeyDown("space") == true){ // user presses space after selecting an ROI
roiManager("add");
for (m = 0; m < 3; m++) { // cycle through the existing 3 ROIs in the image
roiManager("Select", newArray(m, roiManager("count")-1));
roiManager("AND"); // look for overlaps
if (selectionType() != -1) {
roiManager("Deselect");
lesionname = RoiManager.getName(m);
roiManager("Select", roiManager("count")-1); // the newest ROI
roiManager("Rename", lesionname + "_NC");
roiManager("measure");
Overlay.addSelection;
break();
}
roiManager("Deselect"); // make sure we are starting again from scratch
}
}
**if (isKeyDown("alt") == true) {
break(); // exits out of while loop
}**
wait(100); // protects against multiple detection of single keystroke
}
print("done");
The addition allows me to press spacebar multiple times, but has resulted in some unexpected inconsistencies in the earlier part of my code. Now when I press the spacebar, sometimes the newly-selected ROI gets added multiple times (and when this happens only the last ROI added gets renamed), and sometimes the new ROI either doesn't get measured, gets measured multiple times, or isn't added as an overlay. I think pressing the spacebar down longer makes things worse, but I have tried extending the wait time to wait(1000), which does not fully prevent these inconsistencies from occurring and makes the macro feel very laggy when using. I've also tried moving the wait command higher up in the code (under the roiManager("add"); step or after the roiManager("measure"); step), but this doesn't seem to help either.
Based on the type of results I've been getting, it feels like the errors have to do with the code looping in unintended ways when I ask it to continuously detect the use of the spacebar. I think the computer is either repeating through a loop after one press of SPACE or skipping lines altogether, but I can't figure out where the issue is and am not quite sure how to debug this.
Upvotes: 0
Views: 80
Reputation: 328
As already proposed yesterday on Reddit, you should make "key-down" transient by adding setKeyDown("none"):
if (isKeyDown("space")) {
setKeyDown("none");
// then here comes the action code
}
Inserting "wait"-times instead isn't a solution in this case!
However there is much more in your code that needs revision.
Upvotes: 0