forked from tferr/Scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWipe_Background.ijm
More file actions
116 lines (105 loc) · 3.57 KB
/
Wipe_Background.ijm
File metadata and controls
116 lines (105 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* Wipe_Background.ijm
* IJ BAR: https://github.com/tferr/Scripts#scripts
*
* ImageJ macro that clears (sets to zero) clusters of thresholded pixels of defined
* circularity & size within the active area ROI (or the whole image if no ROI exists).
*
* It tries to be as unobtrusive as possible and accepts any grayscale image including
* multidimensional hyperstacks. Currently the filtering is restricted to the Z-dimension,
* but it could be easily extended to other dimensions. It could be greatly simplified if
* the goal was to deal exclusively with 2D/3D images
*
* Known issues:
* - 5D stacks escape batch mode
*
* TF, 2014.10
*/
getThreshold(lower, upper);
if (lower==-1 && !is("binary"))
exit("A thresholded or 8-bit binary image is required.");
optnsA = newArray("Active ROI", "Whole image");
optnsB = newArray("Current slice only", "All slices", "Preceding slices", "Subsequent slices");
imgID = getImageID();
Stack.getDimensions(null, null, channels, depth, frames);
Stack.getPosition(channel, activeSlice, frame);
start = activeSlice;
end = activeSlice;
roi = selectionType();
areaROI = roi>-1 && roi<5 || roi==9;
scope = optnsB[0];
whole = false;
setBatchMode(true);
// Prompt for range and scope of analysis
Dialog.create("Wipe Background - Filtering Particles");
Dialog.addNumber("Size "+ fromCharCode(8804), 10, 0, 10, "pixels");
Dialog.addString("Circ.", "0.00-1.00", 15);
if (areaROI)
Dialog.addChoice("Scope:", optnsA);
if (depth>1)
Dialog.addChoice("Apply to:", optnsB);
Dialog.addMessage("Clusters of thresholded pixels\nwithin the range of the "+
"specified\nsettings will be cleared (set to 0)");
Dialog.show();
size = Dialog.getNumber();
circ = Dialog.getString();
if (areaROI)
if (Dialog.getChoice==optnsA[1])
whole = true;
if (depth>1) {
scope = Dialog.getChoice();
if (scope==optnsB[1]) {
start = 1; end = depth;
} else if (scope==optnsB[2]) {
start = 1; end = activeSlice;
} else if (scope==optnsB[3]) {
start = activeSlice; end = depth;
} else {
start = activeSlice; end = activeSlice;
}
}
// Create stack of noise particles
analyzerArg = "size=0-"+ size +" pixel circularity="+ circ +" show=Masks ";
if (scope!=optnsB[0])
analyzerArg += " stack";
if (whole)
run("Select None");
run("Analyze Particles...", analyzerArg);
maskID = getImageID();
if (maskID==imgID) {
beep(); showStatus("No particles found!"); exit();
} else {
// Active image is now a mask from ParticleAnalyzer (background= 255). This mask
// is never a multidimensional stack (IJ 1.48o), so we'll convert it. Then, chosen
// noise within the selected range will be set to 0, all remaining pixels to 1
run("Invert", "stack");
if (channels*frames >1 && scope!=optnsB[0]) {
run("Stack to Hyperstack...", "channels="+ channels +" slices="+ depth +" frames="+ frames);
maskID = getImageID();
}
for (c=1; c<=channels; c++) {
for (t=1; t<=frames; t++) {
for (z=1; z<=depth; z++) {
Stack.setPosition(c, z, t);
if (z>=start && z<=end)
run("Divide...", "value=255 slice");
else
run("Set...", "value=1 slice");
}
}
}
// Perform the filtering
if (scope==optnsB[0])
imageCalculator("Multiply stack", imgID, maskID);
else
imageCalculator("Multiply", imgID, maskID);
// Restore original settings
Stack.setPosition(channel, activeSlice, frame);
if (areaROI) run("Restore Selection");
setThreshold(lower, upper);
closeImg(maskID);
}
setBatchMode(false);
// For whatever reason (IJ 1.48o) some hyperstacks manage to be displayed in BatchMode
function closeImg(id) {
selectImage(id); close();
}