Threshold looping

Hello,
I am a beginner on Fiji and I have a project, let me try to explain it simply.
I have a set of CT scan images, and I wish to have the number of pixels segmented after I applied a threshold:
-Threshold(i,255) for i=i+1
WaitForUser
-Find connected regions from the starting point selected by the user
In the end I have a table containing the number of pixels segmented, for each value of threshold.

for (i = 0; i<255; i=i+1) {
setThreshold(i, 255)
\waitForUser
run(“Find Connected Regions”, “allow_diagonal display_one_image display_results start_from_point regions_for_values_over=0 minimum_number_of_points=1 stop_after=1”);
}

But since I have little experience in programming, I cannot make it work.
Thank you, Pierre

Hi @pfehlen,
Do I understand correctly that you want the user to set the thresholds, then click a button, upon which your macro fetches the threshold values and applies them to something? Try this macro:

run("CT (420K, 16-bit DICOM)");
setAutoThreshold("Default dark");
waitForUser("Please set thresholds 1");
getThreshold(lower,upper);
print("lower: " + lower + " upper: "+upper);
waitForUser("Please set thresholds 2");
getThreshold(lower,upper);
print("lower: " + lower + " upper: "+upper);

(and from here on, do the detection of connected regions)

Thank you for your answer it helps a bit
But what I want is the number of segmented pixels from the find connected region (starting from a point selected by the user) for every value of thresholding : i;255 with i=i+1.

Your code suggests you want to pick a starting pixel every time a new value for the lower threshold is selected, for each of the values i. That is: set i, pick a pixel, show all threshold values i=[chosen…255], so requiring the user to (255-chosen) times pick a pixel.

Is that what you want, or do you want to let the user set the initial threshold, set the one pixel that needs to be scrutinised for all values of i above the chosen threshold and then have (a graph of) the number of pixels for each of the values i, i=[userChosen…255]?

I made some progress, still I do have 2 issues:

  • when selecting a point on the image, it disappears when i apply threshold, so is there any way to keep in memory the slice, x & y position of my point selected
  • when Find Connected Regions for each threshold values, the table of results does not display all the results, it only display the first one, so is there any way to keep in memory the first result, close the result table and go to the next threshold value

Hi,

To keep in memory position, you can combine Roi.getPosition(channel, slice, frame) and Roi.getBounds(x, y, width, height) or Roi.getCoordinates(xpoints, ypoints)

It is strange that only one region appears. Are you sure that you are mesuaring the objects and not the background ?

Nico

Thank you,
Here is the code updated:run(“Median…”, “radius=1 stack”);
//setTool(“multipoint”);
waitForUser;
getSelectionBounds(x, y, width, height)
a=x
b=y
z=getSliceNumber();
for(i=10; i<230; i+10)
setThreshold(i, 230);
setOption(“BlackBackground”, false);
run(“Convert to Mask”, “method=Otsu background=Dark black”);
setSlice(z);
makePoint(a, b, “small yellow hybrid”);
run(“Find Connected Regions”, “allow_diagonal display_one_image display_results start_from_point regions_for_values_over=0 minimum_number_of_points=1 stop_after=1”);

So, what I want is a table of results which displays the number of segmented pixels from the FCR function for every threshold value (here starting at 10+S;255 where S is the step) at the selected point on the original image.

The main problems I have now are making the loop work pretty much and keep in memory the number of segmented pixels.

First of all, dont forget the { } inside your for loop.
Then to get values from Result window, you can use getResult(“Column”, row)

Nico

Thank you very much, now the only obstacle left (I think) is to make a table out of these results, so I consider two vectors, one for the value of the threshold and one for the number of segmented pixels, do you know the syntax for this ?

You could use the File functions (see https://imagej.nih.gov/ij/macros/SaveTextFileDemo.txt for example) to save your results, later openable in any spreadsheets.

Nico

I’m sorry I don’t understand how this works, here is the code updated :
setTool(“point”);
waitForUser(“choisir un vaisseau”);
getSelectionBounds(x, y, width, height)
a=x
b=y
z=getSliceNumber();
C=newArray()
D=newArray()

run(“Median…”, “radius=2 stack”);
for (i = 10; i < 200; i=i+10) {
selectWindow(“liver_07.liver.norm.hdr”);
run(“Duplicate…”, “duplicate”);
setThreshold(i, 232);
setOption(“BlackBackground”, false);
run(“Convert to Mask”, “method=Otsu background=Dark black”);
setSlice(z);
makePoint(a,b);
run(“Find Connected Regions”, “allow_diagonal display_results start_from_point regions_for_values_over=0 minimum_number_of_points=1 stop_after=1”);
close();
D=Table.save(“filePath”)
//D = nResults();
C=i
};
Table.showArrays(“titleAndOptions”, C, D,)

The question is how do I save D on the same table for each value of C.

Are you looking for the setResult(“Column”, row, value) function @pfehlen?

You can call this with C and D consecutively. That way, you fill the Results table with the numbers C and D in row 0…4 in the example below. The index ‘row’ should start at 0 and shall be no more than the nResults (ie. you can’t fill the fourth row (that is row = 3!!) if there are not at least 3 results in the table) but you can change values of existing rows. Try this macro:

for(i=0;i<5;i=i+1){
	setResult("the Threshold",i,i+60);
	setResult("C",i,i+60);
	setResult("D",i,(i+60)*3);
	updateResults();	
}
setResult("D",2,0);
//setResult("D",7,0); would cause a 'Row(7) out of range in line 8' error
updateResults();

Or is it your intention to build a table with file paths?
Or do you keep a number in D (but commented that out?)

You don’t use the arrays C and D that you declared. Also, if you don’t specify the size of the arrays at declaration time, you need to activate the expandable array option if you want to enter values into the arbitrarily sized array.