|
| 1 | +/** |
| 2 | + * Lookup Tables (LUTs) |
| 3 | + * ---------------------------------------------- |
| 4 | + * |
| 5 | + * This short macro showcases different way to use the Lookup Tables, the while loop, the window dialog getBoolean() |
| 6 | + * |
| 7 | + * Due to the simple nature of this code, no copyright is applicable |
| 8 | + * |
| 9 | + * Code created for Image Processing and Analysis For Life Scientists MOOC on EdX |
| 10 | + * https://www.edx.org/course/image-processing-and-analysis-for-life-scientists |
| 11 | + * |
| 12 | + * 2018 - Romain Guiet, EPFL - SV - BIOP |
| 13 | + * https://biop.epfl.ch |
| 14 | + */ |
| 15 | + |
| 16 | +// clear environment |
| 17 | +roiManager("Reset"); |
| 18 | +run("Close All"); |
| 19 | +run("Clear Results"); |
| 20 | + |
| 21 | +// Create a new image with a unique ID |
| 22 | +id = round( random() * 100 ); |
| 23 | +newImage("User Drawing - "+id, "8-bit black", 512, 512, 1); |
| 24 | + |
| 25 | +// ask user to draw some ROIs |
| 26 | +waitForUser("Please Draw a Large Region Of Interest,\nThen Press 'OK'"); |
| 27 | +Roi.setName("Large ROI"); |
| 28 | +roiManager("Add"); |
| 29 | + |
| 30 | +waitForUser("Please Draw a smaller ROI overlapping (partially) with the large one,\nThen Press 'OK'"); |
| 31 | +Roi.setName("Small ROI"); |
| 32 | +roiManager("Add"); |
| 33 | + |
| 34 | +// |
| 35 | +roiManager("Select", newArray(0,1)); |
| 36 | +roiManager("OR"); |
| 37 | +roiManager("Add"); |
| 38 | +roiManager("Select", (roiManager("Count")-1) ); // select the last ROI (newest one ) |
| 39 | +roiManager("Rename", "OR"); |
| 40 | + |
| 41 | +roiManager("Select", newArray(0,1)); |
| 42 | +roiManager("AND"); |
| 43 | +roiManager("Add"); |
| 44 | +roiManager("Select", (roiManager("Count")-1) ); |
| 45 | +roiManager("Rename", "AND"); |
| 46 | + |
| 47 | +roiManager("Select", newArray(0,1)); |
| 48 | +roiManager("XOR"); |
| 49 | +roiManager("Add"); |
| 50 | +roiManager("Select", (roiManager("Count")-1) ); |
| 51 | +roiManager("Rename", "XOR"); |
| 52 | + |
| 53 | +// Create an output image |
| 54 | +for(i=0;i<roiManager("Count");i++){ |
| 55 | + if (i!=0) run("Add Slice"); |
| 56 | + roiManager("Select",i); |
| 57 | + roiManager("Fill"); |
| 58 | +} |
| 59 | +run("Make Composite", "display=Composite"); |
| 60 | +Stack.setDisplayMode("color"); |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | + |
| 65 | +// Do some measurement |
| 66 | +roiManager("Deselect"); |
| 67 | +roiManager("Measure"); |
| 68 | + |
| 69 | +// Create a nicer result table for the user with the areas |
| 70 | + |
| 71 | +// Our goal is to have a table with one line == one observation |
| 72 | + |
| 73 | +// We can make our custom table a bit more flexible by using loops and getting the column names directly from the ROI names in the Label column |
| 74 | + |
| 75 | +// We will recover the names of the images and the areas for further processing |
| 76 | + |
| 77 | +n = nResults; // how many rows we have to recover |
| 78 | + |
| 79 | +// Create an array that will contain the areas |
| 80 | +areas = newArray(n); |
| 81 | + |
| 82 | +// Create an array that will contain the ROI names |
| 83 | +roiNames = newArray(n); |
| 84 | + |
| 85 | +for(i=0; i<n; i++) { |
| 86 | + |
| 87 | + // Pick up the label |
| 88 | + name = getResultLabel(i); |
| 89 | + // The name is like this 'Image_Name:ROI name:Slice' |
| 90 | + // We do not care about the Slice here, only the image name and the ROI name |
| 91 | + // Split the names at the colon |
| 92 | + splitName = split(name, ':'); |
| 93 | + |
| 94 | + // Keep the roiName, which is at index 1 |
| 95 | + roiNames[i] = splitName[1]; |
| 96 | + |
| 97 | + // Recover the value of the area |
| 98 | + areas[i] = getResult("Area", i); |
| 99 | +} |
| 100 | + |
| 101 | + |
| 102 | +// Now that everything is set, we can create a new results table |
| 103 | +// Because getResult and setResult only work with a window exactly called "Results", |
| 104 | +// we need to rename the old one before starting a new one. |
| 105 | +// We could also use run("Clear Results"); but this way we keep the raw data just in case |
| 106 | +IJ.renameResults("Raw"); // keep the raw measurements aside |
| 107 | + |
| 108 | + |
| 109 | +// Suppose we want to call our new measurements table "Custom" by the end of the processing |
| 110 | +// We need to check first if there is already a table called "Custom", so that we can APPEND to it |
| 111 | +row= 0; |
| 112 | +if( isOpen("Custom") ) { |
| 113 | + IJ.renameResults("Custom", "Results"); |
| 114 | + row = nResults; // get the current number of rows |
| 115 | +} |
| 116 | + |
| 117 | +// Append data to the table at the correct row |
| 118 | +setResult("Label", row, "Measured Area") ; // Label for the given row, the 0 is the column |
| 119 | +setResult("Image Name", row, getTitle()); // Add the image name to the table |
| 120 | + |
| 121 | +// Now we go through all the columns we have created |
| 122 | +for(i=0; i<n; i++) { |
| 123 | + // We make a new column for each ROI name and add the corresponding area |
| 124 | + setResult(roiNames[i], row, areas[i]); |
| 125 | +} |
| 126 | + |
| 127 | +// Now we can do some custom calculations |
| 128 | +// For instance compute how much of the Large ROI is contributing to the overlap |
| 129 | +// The formula would be (In column names) AND / LARGE ROI * 100 or (the area both have in common divided by the area of the large roi time 100 to have it percent |
| 130 | +area_large = getResult("Large ROI", row); |
| 131 | +area_and = getResult("AND", row); |
| 132 | + |
| 133 | +// Create new measurement |
| 134 | +large_ratio = area_and / area_large * 100; |
| 135 | + |
| 136 | +// Add the new column |
| 137 | +setResult("Large ROI % Overlap", row, large_ratio); |
| 138 | + |
| 139 | +updateResults; |
| 140 | + |
| 141 | +// Here we will rename our results "Custom" |
| 142 | +IJ.renameResults("Custom"); |
| 143 | + |
| 144 | +// And bring back the original results tables name |
| 145 | +IJ.renameResults("Raw","Results"); // bring back the raw measurements as a Results window. New results will be appended to this one and not to our custom one. |
| 146 | + |
| 147 | +// Our custom results are exactly behind the Results window, so we need to make it come to the front |
| 148 | +selectWindow("Custom"); |
0 commit comments