Make binary with inhibiting factors

Hi,

I’m working on a project with nickel-based samples. I’m using the Focused Ion Beam (FIB) to analyze the samples slice by slice. My goal is to measure the density of a recreated 3D-model. In theory I want to:

1 - binarize every slice and determine the size of the etched precipitations
2 - recreate a 3D-model with the binarized images

At the moment I stuck at the “make binary” or “threshold” part. The images containing different grayscale’s, edges are highlighted and the inside of the etched areas are sometimes black, sometimes grey.

My first attempt was to correct the different grayscale’s in the image. I started with the SEM picture as following:
gp-001 - 001.tif (489.2 KB)
I used gaussian blur with a radius of 50 to divide the result with the SEM image and the result with the blurred one
gp-001 - 001_blur.tif (489.2 KB) is Result of gp-001 - 001.tif (489.2 KB).

But then every attempt to get a useful binary is not successful.

I would be very happy for any kind of advise since I’m not sure if its possible to work this out without marking every interesting section by hand.

Thanks!!

Something you need to work out, but this is the gist: rotate the image by 90 degrees, select all, then plot the profile. You can infer the average background from that line. This is what the graph looks like:


Subtract the fitted line as background value from the image and see if that allows you to do your thresholding in a proper way.

1 Like

Thank you @eljonco!
But how to subtract it? I just have the subtract background option.

Hi @biaxialerzug,

You also have image math (Process>Image Calculator...) that allows you to subtract, add, divide, multiply etc. two images pixel by pixel.
Fit the line, create an image with same size as your original, fill it with a ramp that follows the line logic (ie. is about 52 on one size, about 150 on the other side) then perform image math, choose subtract, have the first image being your original, the second image the ramp image, create new window.

From the resulting window it should be relatively easy to have a proper thresholding. Use the thresholded image as a mask to the original and get the measuring values from the original.
I think there is quite an opportunity for getImageID() and selectImage()…

Maybe the subtraction is not the proper method here, that depends on the physical nature of your image acquisition method. Then try to use the values in the ramp image to normalise the original image by dividision and multiplication.

Thanks a lot!
I tried my best but I cant get it working. Background substraction seems to be the wrong way to solve this problem. Any other suggestions?

The fact that you “cant get it working” doesn’t necessarily mean that it is the wrong way to solve this problem. :wink:

What did you try? Why did it not work? What was the problem you encountered? How did you create the background image to be subtracted? What did the image look like after you subtracted the (linear) background?

Yeah thats correct!

I tried the profile plot. I tried to fit it with different functions, 4th degree polynomial looks good. I tried to create a ramp image but cant figure out how to transfer the result from the fit to a ramp image. So I tried a ramp image with a linear profile.
ramp.tif (484.8 KB)
The result looked like this Result of gp-001 - 001.tif (484.7 KB)
If I flip the ramp and use average in image calculation I get this result Result of gp-001 - 001_2.tif (484.7 KB)

Biggest problems are the bright edges and fact that the inside of the etched areas is black too. So if I would be able to get a binary I will get just white edges.

I can download all of the files @eljonco

It says server is down but when I click on the files I can download them.

It works with a different browser, so I withdrew my question to the team, but it remains odd that the server cannot be reached.

Hi @biaxialerzug, the result of a first attempt using

this macro
inImgID=getImageID();
run("Rotate 90 Degrees Right");
rename("original");
getDimensions(width, height, channels, slices, frames)
run("Select All");
profileValues=getProfile();
newImage("preRamp", "8-bit white", 500, 1, 1);
preRampID=getImageID();

for(vLine=0;vLine<width;vLine++){
	setPixel(vLine,0, profileValues[vLine]);
}
run("Scale...", "x=1 y="+height+" width="+width+" height="+height+"interpolation=None create");
rampID=getImageID();
rename("ramp");
imageCalculator("Subtract create 32-bit", "original","ramp");
run("8-bit");

was this image which allows for Image>Adjust>Threshold 'ing to reasonably separate the objects:


or in tiff format:
Result of original.tif and this ramp: (1.9 MB) ramp.tif (484.8 KB)

This is one way, ie. using the average value across the vertical of the rotated image. You can also obtain the minimum or maximum value per vertical line (reslice the image in Z, the do z-project using min or max). As in the result above there are also horizontal constant values, you can repeat the trick in the other direction.

Another thing you might want to try is not to subtract or add the ramp, but to use it as a normalising image, by dividing by the ramp and multiplying by 255.

Thank you very much! That looks promising!
but unfortunaly I cant get it working. When I try to run the macro I get an error:

Error: Undefined variable in line 2:
run ( <“Rotate> 90 Degrees Right” ) ;

Tried different macro languages but it wont work.

Upon close inspection I notice that there are typographical quotes used the error message. My bad. I forgot to enclose the macro code in </> in the forum editor. I have just corrected that omission, so if you could grab the macro again and see if it works?