Skip to content

Commit a7c98cf

Browse files
authored
Create Macro_Image_Segmentation
1 parent a103c3a commit a7c98cf

File tree

1 file changed

+384
-0
lines changed

1 file changed

+384
-0
lines changed

Macro_Image_Segmentation

+384
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
//** Created by Guyon Joris, INSERM u1029,
2+
// Bordeaux University, Pessac, Gironde, September 22, 2021
3+
//
4+
// This macro was created to faciliate the segmentation of an object from different acquisitions in Fiji.
5+
6+
7+
/*
8+
version 1.0, September 22, 2021
9+
*/
10+
11+
// ______________________________________________________________________________________________________________________
12+
// ----------------------------------------------------------------------------------------------------------------------
13+
// Variable declaration
14+
// ______________________________________________________________________________________________________________________
15+
// ----------------------------------------------------------------------------------------------------------------------
16+
17+
var unsharp_radius = 1;
18+
var unsharp_weight = 0.6;
19+
var med_filter_radius = 0;
20+
var sift_weight = 25;
21+
var minimum_radius = 5;
22+
var maximum_radius = 5;
23+
var med_filter_radius2 = 20;
24+
var sift_weight2 = 5000;
25+
var invert_selection = false;
26+
var name;
27+
var setup_radius1 = 20;
28+
var setup_radius2 = 500;
29+
var setup_space = 20;
30+
var scale;
31+
var Add_QImage = "No";
32+
var Method_Choice0 = "Classic ";
33+
var Method_Choice = "1 ";
34+
35+
var URL = "https://github.com/Guyon-J/Cancer_Feature_Analysis/wiki/Welcome-to-the-Cancer-Feature-Analysis-wiki!";
36+
var URL_Witcher = "https://raw.githubusercontent.com/Guyon-J/Image_segmentation/main/Images/Tool_icons/Witcher.png";
37+
var URL_Core = "https://upload.wikimedia.org/wikipedia/commons/7/74/Cercle_dessin_indus.png";
38+
var URL_Sk = "https://raw.githubusercontent.com/Guyon-J/Image_segmentation/main/Images/Tool_icons/Sk.png";
39+
40+
41+
42+
// ______________________________________________________________________________________________________________________
43+
// ----------------------------------------------------------------------------------------------------------------------
44+
// Action Tools and options
45+
// ______________________________________________________________________________________________________________________
46+
// ----------------------------------------------------------------------------------------------------------------------
47+
48+
// -----------------------------------------------------
49+
// HELP button Tool
50+
// -----------------------------------------------------
51+
52+
macro "HELP Action Tool - Cf00D15D16D17D18D19D27D35D36D37D38D39D55D56D57D58D59D65D67D69D75D79D95D96D97D98D99Da9Dc5Dc6Dc7Dc8Dc9Dd5Dd7De5De6De7CbffD00D01D0cD23D4dD4fD5fD63D7bD82D9bDacDc2Dd0DefDf3DfdDffCff8D0bD1bD1dD1fD20D32D33D3cD4bD51D53D7eD8cD8dD90D9cD9fDbdDcdDcfDe2DecDfbCfffD04D05D06D07D08D09D0aD14D1aD24D25D26D28D29D2aD34D3aD44D45D46D47D48D49D4aD54D5aD64D66D68D6aD74D76D77D78D7aD84D85D86D87D88D89D8aD94D9aDa4Da5Da6Da7Da8DaaDb4Db5Db6Db7Db8Db9DbaDc4DcaDd4Dd6Dd8Dd9DdaDe4De8De9DeaDf4Df5Df6Df7Df8Df9DfaCcccD03D0eD22D2dD50D6bD6eD80D8fDafDb1DbeDbfDdbDe0De3Df2DfeCfffD2cD3bD9dDa3Db3DbcDc1CeeeD0dD12D1cD2bD3dD42D43D4cD5cD5dD6cD72D73D7cD7dD83D92D93D9eDa1Da2DadDb2Dc3DccDceDd1Dd3DedC666D8bCdddD02D13D2eD2fD3eD40D41D4eD52D5eD62D6dD70D71D7fD81D8eD91Da0DaeDc0Dd2DdcDddDdeDdfDebCbbbD21D31D3fD61D6fDb0DeeDf1DfcC999DbbC888D0fD30D5bDabCaaaD10D11D1eD60De1C777DcbDf0"{
53+
showMessage("1/3", "<html>"
54+
+"<h1><font color=red>Image segmentation</h1><br>"
55+
+"<font size=-2><font color=black> <br>"
56+
+"<img src="+URL_Witcher+" height="+64+" width="+64+"><br>"
57+
+"<font size=-2><font color=black> <br>"
58+
+"<font color=red>Left click:<font color=black> Apply the choosen segmentation algorithm to delineate contourn <br>"
59+
+"<font color=red>Right click:<font color=black> Open a dialog box to change parameters <br>"
60+
);
61+
62+
showMessage("2/3", "<html>"
63+
+"<h1><font color=red>Core segmentation</h1><br>"
64+
+"<font size=-2><br>"
65+
+"<img src="+URL_Core+" height="+64+" width="+64+"><br>"
66+
+"<font size=-2><font color=black> <br>"
67+
+"<font color=red>Left click:<font color=black> Apply the segmentation algorithm to delineate core contourn<br>"
68+
+"<font color=red>Right click:<font color=black> Open a dialog box to choose one algorithm and change parameters <br>"
69+
+"</b>"
70+
+"<h2><font color=red>In Progress...</h2><br>"
71+
);
72+
73+
showMessage("3/3", "<html>"
74+
+"<h1><font color=red>Vortex</h1><br>"
75+
+"<font size=-2><font color=black> <br>"
76+
+"<img src="+URL_Sk+" height="+64+" width="+64+"><br>"
77+
+"<font size=-2><font color=black> <br>"
78+
+"<font color=red>Left click:<font color=black> Skeletonize from a binary ROI (Requires having the ROI of the total area in the last position in the ROI manager)<br>"
79+
+"<font color=red>Right click:<font color=black> Direct image processing via <b>Alternative Algorithm</b> <br>"
80+
+"<font size=-2><br>"
81+
+"<font color=black> Reduce binary total area to 1 pixel wide representations <br>"
82+
+"It preserves the extent and connectivity of the original object<br>"
83+
+"Useful for feature extraction and representing object's topology<br>"
84+
+"You can dilate the skeleton with <b>Process > Binary > Dilate</b> for a better visualtion<br>"
85+
+"</b>"
86+
+"<h2><font color=red>In Progress...</h2><br>"
87+
);
88+
89+
}
90+
91+
macro "HELP Action Tool Options" {
92+
run('URL...', 'url='+URL);
93+
}
94+
95+
// -----------------------------------------------------
96+
// Main segmentation tool
97+
// -----------------------------------------------------
98+
99+
macro "Image segmentation Action Tool - Cff0D75D79D89D8aD95D99Dd6De5De6De7Df6C801D24D32D33D36D41D47D51D58D59D5eD6bD6eD81D8dD92D9eDa3DaeDb9DbaDc8Dc9Dd7Dd8CcccDc5Dc6Dc7Dd4Dd5De4De8Df4Df5Df7Df8C400D14D15D16D23D26D2cD2dD3cD4bD5aD61D67D69D6aD71D78D88D98Da6Da7DabDacDb5CeebD00D01D02D03D07D08D09D0aD0bD0cD0dD0eD0fD10D11D12D18D19D1aD1bD1eD1fD20D21D28D29D2aD2bD2fD30D38D39D3aD3fD40D4fD7fD8fD90Da0Db0Db1Db2Db7Db8DbfDc0Dc1Dc2Dc3Dc4DcaDcbDccDcdDceDcfDd0Dd1Dd2Dd3Dd9DdaDdbDdcDddDdeDdfDe0De1De2De3De9DeaDebDecDedDeeDefDf0Df1Df2Df3Df9DfaDfbDfcDfdDfeDffCb75D25D34D35D3dD42D43D44D45D46D4cD4dD52D53D54D5bD5cD5dD62D6cD6dD72D7bD7cD7dD82D8cD9bD9cC200D04D05D06D13D17D1cD1dD22D27D2eD31D37D3bD3eD48D49D4aD4eD50D5fD60D68D6fD70D7aD7eD80D8bD8eD91D9aD9dD9fDa1Da2Da8Da9DaaDadDafDb3Db4DbbDbcDbdDbeC202D55D56D63D64D65D66D73D74D76D77D83D84D85D86D87D93D94D96D97Da4Da5"{
100+
Deselect_ROI();
101+
name = getTitle();
102+
run("Set Measurements...", "area perimeter shape redirect=None decimal=3");
103+
104+
if (Method_Choice0 == "Classic ") {
105+
Thresholding();
106+
Create_selection();
107+
}
108+
109+
if (Method_Choice0 == "Alternative ") {
110+
Image_calculator();
111+
Preprocessing();
112+
Binarisation();
113+
Postprocessing();
114+
Create_selection();
115+
}
116+
117+
nROI_1 = roiManager("count")-1;
118+
roiManager("Select", nROI_1);
119+
roiManager("rename", name+"_Total_Area");
120+
close();
121+
setTool("freehand");
122+
roiManager("Select", nROI_1);
123+
}
124+
125+
macro "Image segmentation Action Tool Options" {
126+
_choix = newArray("Classic ","Alternative ");
127+
Dialog.create("Image segmentation Options");
128+
Dialog.addRadioButtonGroup("Algorythm choice", _choix, 1, 2, Method_Choice0);
129+
Dialog.addMessage("Unsharp Mask parameters");
130+
Dialog.addNumber("Radius", unsharp_radius);
131+
Dialog.addNumber("Weight", unsharp_weight);
132+
Dialog.addMessage("Median filter");
133+
Dialog.addNumber("Radius", med_filter_radius);
134+
Dialog.addMessage("Particle Sift");
135+
Dialog.addNumber("Min weight (px)", sift_weight);
136+
Dialog.addCheckbox("Invert Selection", invert_selection);
137+
Dialog.show();
138+
Method_Choice0 = Dialog.getRadioButton();
139+
unsharp_radius = Dialog.getNumber();
140+
unsharp_weight = Dialog.getNumber();
141+
med_filter_radius = Dialog.getNumber();
142+
sift_weight = Dialog.getNumber();
143+
invert_selection = Dialog.getCheckbox();
144+
}
145+
146+
147+
// -----------------------------------------------------
148+
// Core segmentation tool
149+
// -----------------------------------------------------
150+
151+
macro "Core Area Action Tool - C000D16D17D18D25D29D35D39D56D57D58D65D69D76D77D78D96D97D98D99Da5Da7Da8Db6Db7Db9Dd5Dd6Dd7Dd8Dd9De5De7De9CfffD03D04D05D06D07D08D09D0aD0bD13D14D15D19D1aD1bD23D24D26D27D28D2aD2bD33D34D36D37D38D3aD3bD43D44D45D46D47D48D49D4aD4bD53D54D55D59D5aD5bD63D64D66D67D68D6aD6bD73D74D75D79D7aD7bD83D84D85D86D87D88D89D8aD8bD93D94D95D9aD9bDa3Da4Da6Da9DaaDabDb3Db4Db5Db8DbaDbbDc3Dc4Dc5Dc6Dc7Dc8Dc9DcaDcbDd3Dd4DdaDdbDe3De4De6De8DeaDebDf3Df4Df5Df6Df7Df8Df9DfaDfbC0aeD00D0eD11D1fD20D22D2dD3dD7eD82D8fD9eDaeDc0Dc2DcdDeeDf2DfdCeebD01D0cD0fD12D1cD1eD21D2cD30D3cD3eD41D42D4cD4eD4fD51D52D5cD5dD5eD60D61D6cD6eD72D7cD7dD7fD80D81D8cD90D92D9cD9dDa1Da2DacDafDb0Db2DbcDbeDccDd1DdcDddDdeDe1De2DecDfcDffCcccDf0Cbe1D02D10D1dD2eD31D4dD50D6dD6fD71D8eD91DadDbfDc1DdfDe0DedDf1C2b4D0dD2fD32D3fD40D5fD62D70D8dD9fDa0Db1DbdDceDcfDd0Dd2DefDfe"{
152+
Deselect_ROI();
153+
name = getTitle();
154+
run("Duplicate...", "title=Process");
155+
run("16-bit");
156+
if (Method_Choice == "1 ") {
157+
Image_calculator();
158+
Preprocessing();
159+
Core_Method1();
160+
}
161+
if (Method_Choice == "2 ") {
162+
Core_Method2();
163+
}
164+
if (Method_Choice == "3 ") {
165+
Core_Method3();
166+
}
167+
}
168+
radio
169+
170+
macro "Core Area Action Tool Options" {
171+
_choix = newArray("1 ","2 ","3 ");
172+
Dialog.create("Core Area parameters");
173+
Dialog.addRadioButtonGroup("Algorythm choice", _choix, 1, 2, Method_Choice);
174+
Dialog.addMessage("--------------------------------------");
175+
Dialog.addMessage("Radius set up: ");
176+
Dialog.addNumber("Minimum:", minimum_radius);
177+
Dialog.addNumber("Maximum:", maximum_radius);
178+
Dialog.addNumber("Median:", med_filter_radius2);
179+
Dialog.addMessage("--------------------------------------");
180+
Dialog.addNumber("Min weight (px):", sift_weight2);
181+
Dialog.show();
182+
Method_Choice = Dialog.getRadioButton();
183+
minimum_radius = Dialog.getNumber();
184+
maximum_radius = Dialog.getNumber();
185+
med_filter_radius2 = Dialog.getNumber();
186+
sift_weight2 = Dialog.getNumber();
187+
}
188+
189+
190+
// -----------------------------------------------------
191+
// Skeleton tools
192+
// -----------------------------------------------------
193+
194+
macro "Skeletonize Action Tool - C000D13D15D18D1aD1cD23D25D28D2aD2cD33D35D38D3aD3cD43D45D48D4aD4cD53D55D58D59D5aD5bD5cD63D64D65D68D75D76D77D78D87D96D97D98D99Da4Da5Da6Da9Db4Db6Db9DbaDbbDc4Dc6Dc9DcbDd4Dd6Dd9DdbDe4De6De9DebC000C111C222C333C444C555C666C777C888C999CaaaCbbbCcccCdddCeeeCfffD00D01D02D03D04D05D06D07D08D09D0aD0bD0cD0dD0eD0fD10D11D12D14D16D17D19D1bD1dD1eD1fD20D21D22D24D26D27D29D2bD2dD2eD2fD30D31D32D34D36D37D39D3bD3dD3eD3fD40D41D42D44D46D47D49D4bD4dD4eD4fD50D51D52D54D56D57D5dD5eD5fD60D61D62D66D67D69D6aD6bD6cD6dD6eD6fD70D71D72D73D74D79D7aD7bD7cD7dD7eD7fD80D81D82D83D84D85D86D88D89D8aD8bD8cD8dD8eD8fD90D91D92D93D94D95D9aD9bD9cD9dD9eD9fDa0Da1Da2Da3Da7Da8DaaDabDacDadDaeDafDb0Db1Db2Db3Db5Db7Db8DbcDbdDbeDbfDc0Dc1Dc2Dc3Dc5Dc7Dc8DcaDccDcdDceDcfDd0Dd1Dd2Dd3Dd5Dd7Dd8DdaDdcDddDdeDdfDe0De1De2De3De5De7De8DeaDecDedDeeDefDf0Df1Df2Df3Df4Df5Df6Df7Df8Df9DfaDfbDfcDfdDfeDff"{
195+
run("Set Measurements...", "area perimeter shape redirect=None decimal=3");
196+
getDimensions(width, height, channels, slices, frames);
197+
newImage("Skeleton_of_"+name, "8-bit white", width, height, 1);
198+
Skeletonization();
199+
200+
}
201+
202+
macro "Skeletonize Action Tool Options"{
203+
Deselect_ROI();
204+
name = getTitle();
205+
run("Set Measurements...", "area perimeter shape redirect=None decimal=3");
206+
Image_calculator();
207+
Preprocessing();
208+
Binarisation();
209+
Postprocessing();
210+
run("Skeletonize");
211+
Create_selection();
212+
nROI_2 = roiManager("count")-1;
213+
roiManager("Select", nROI_2);
214+
roiManager("rename", name+"_Skeleton");
215+
rename("Skeleton_of_"+name);
216+
}
217+
218+
219+
// ______________________________________________________________________________________________________________________
220+
// ----------------------------------------------------------------------------------------------------------------------
221+
// Functions
222+
// ______________________________________________________________________________________________________________________
223+
// ----------------------------------------------------------------------------------------------------------------------
224+
225+
function Deselect_ROI(){
226+
roiManager("deselect");
227+
roiManager("Show All");
228+
roiManager("Show None");
229+
}
230+
231+
232+
function Image_calculator(){
233+
// Duplicate
234+
run("Duplicate...", "title=ORI");
235+
selectWindow("ORI");
236+
// Convolved image
237+
run("Duplicate...", "title=CONV");
238+
run("Convolve...", "text1=[1 1 1\n1 1 1 \n1 1 1\n] normalize");
239+
// Sharped image
240+
selectWindow("ORI");
241+
run("Duplicate...", "title=SHARP");
242+
run("Unsharp Mask...", "radius="+unsharp_radius+" mask="+unsharp_weight+"");
243+
// Image calculator: CONV = CONV - SHARP
244+
imageCalculator("Subtract create 32-bit", "CONV","SHARP");
245+
selectWindow("CONV");
246+
close();
247+
selectWindow("SHARP");
248+
close();
249+
selectWindow("ORI");
250+
close();
251+
selectWindow("Result of CONV");
252+
rename("CONV-SHARP");
253+
}
254+
255+
256+
function Preprocessing(){
257+
selectWindow("CONV-SHARP");
258+
// Lissage - reduction du bruit de fond (simple convolution en général)
259+
// Différenciation - calcul des dérivées pour mettre en évidence le contour
260+
run("Find Edges");
261+
run("Invert");
262+
}
263+
264+
265+
function Binarisation(){
266+
selectWindow("CONV-SHARP");
267+
setAutoThreshold("Triangle");
268+
run("Convert to Mask");
269+
run("Close-");
270+
run("Fill Holes");
271+
run("Dilate");
272+
run("Median...", "radius="+med_filter_radius+"");
273+
run("Erode");
274+
}
275+
276+
277+
function Postprocessing(){
278+
// Elimination of small particles and on edge
279+
run("Analyze Particles...", "size="+sift_weight+"-Infinity pixel show=Masks exclude in_situ");
280+
}
281+
282+
283+
function Create_selection(){
284+
// Add to ROI manager
285+
run("Create Selection");
286+
if (invert_selection == true) run("Make Inverse");
287+
roiManager("Add");
288+
}
289+
290+
291+
function Skeletonization(){
292+
nROI_1 = roiManager("count")-1;
293+
roiManager("Select", nROI_1);
294+
roiManager("Fill");
295+
run("Convert to Mask");
296+
// Line formation
297+
run("Skeletonize");
298+
Create_selection();
299+
nROI_2 = roiManager("count")-1;
300+
roiManager("Select", nROI_2);
301+
roiManager("rename", name+"_Skeleton");
302+
}
303+
304+
305+
function Core_Method1(){
306+
run("Invert");
307+
run("Median...", "radius=5");
308+
setAutoThreshold("Minimum dark no-reset");
309+
run("Convert to Mask");
310+
run("Close-");
311+
run("Invert");
312+
313+
run("Analyze Particles...", "size=50000-1000000 pixel show=Masks in_situ");
314+
run("Median...", "radius="+med_filter_radius2);
315+
run("Create Selection");
316+
run("Fit Ellipse");
317+
roiManager("Add");
318+
nROI = roiManager("count")-1;
319+
roiManager("Select", nROI);
320+
roiManager("Rename", name+"_Core");
321+
close();
322+
close();
323+
roiManager("Select", nROI);
324+
}
325+
326+
function Core_Method2(){
327+
run("Maximum...", "radius="+maximum_radius);
328+
run("Minimum...", "radius="+minimum_radius);
329+
run("Median...", "radius="+med_filter_radius2);
330+
run("Subtract Background...", "rolling=25 light create");
331+
run("Median...", "radius="+med_filter_radius2);
332+
run("Convert to Mask");
333+
run("Analyze Particles...", "size="+sift_weight2+"-Infinity pixel circularity=0.4-1.00 show=Masks exclude in_situ");
334+
run("Fill Holes");
335+
run("Create Selection");
336+
roiManager("Add");
337+
nROI = roiManager("count")-1;
338+
roiManager("Select", nROI);
339+
roiManager("Rename", name+"_Core");
340+
close();
341+
roiManager("Select", nROI);
342+
}
343+
344+
function Core_Method3(){
345+
run("Convolve...", "text1=[1 1 1\n1 1 1\n1 1 1\n] normalize");
346+
run("Median...", "radius="+med_filter_radius2);
347+
run("Subtract Background...", "rolling=25 light create");
348+
run("Maximum...", "radius="+maximum_radius);
349+
setAutoThreshold("MinError no-reset"); //Otsu
350+
setOption("BlackBackground", true);
351+
run("Convert to Mask");
352+
run("Median...", "radius="+med_filter_radius2);
353+
run("Analyze Particles...", "size="+sift_weight2+"-Infinity pixel circularity=0.40-1.00 show=Masks exclude in_situ");
354+
run("Fill Holes");
355+
run("Create Selection");
356+
roiManager("Add");
357+
nROI = roiManager("count")-1;
358+
roiManager("Select", nROI);
359+
roiManager("Rename", name+"_Core");
360+
close();
361+
roiManager("Select", nROI);
362+
}
363+
364+
function TableFormat(){
365+
Table.deleteRows(0, 1);
366+
Plot.create("Plot of Results", "x", "Mean");
367+
Plot.add("Connected Circles", Table.getColumn("Mean", "Results"));
368+
Plot.setStyle(0, "blue,#a0a0ff,2.0,Connected Circles");
369+
Plot.setLimits(0.0,50.0,0,60000);
370+
}
371+
372+
function Thresholding(){
373+
run("Duplicate...", " ");
374+
run("8-bit");
375+
run("Subtract Background...", "rolling=20");
376+
run("Find Edges");
377+
setAutoThreshold("Otsu dark");
378+
setOption("BlackBackground", true);
379+
run("Convert to Mask");
380+
run("Close-");
381+
run("Fill Holes");
382+
run("Median...", "radius="+med_filter_radius);
383+
run("Analyze Particles...", "size="+sift_weight+"-Infinity pixel show=Masks exclude in_situ");
384+
}

0 commit comments

Comments
 (0)