CLIJ: Dilate Binary

@haesleinhuepf

For a binary dilation with a radius larger 1, I did it like this:

Ext.CLIJ_push("image");
Ext.CLIJ_dilateSphere("image", "dilated0");
for (i = 0; i < numDilations; i++) {
	Ext.CLIJ_dilateSphere("dilated"+i, "dilated"+(i+1));
}
Ext.CLIJ_pull("dilated"+ numDilations);

Is this best practice or would you recommend something else?

1 Like

Hey @Christian_Tischer,

this strategy is good, but a bit memory consumptive, because it allocates a new image with every iteration. You can measure/trace memory consumption using Ext.CLIJ_reportMemory().. To spare memory in your case, you might at least put it a modulo operator:


numDilations = 10;

// init GPU
run("CLIJ Macro Extensions", "cl_device=");
Ext.CLIJ_clear();

// push an example image to the GPU and make a binary image from it
run("Blobs (25K)");
blobs = getTitle();
Ext.CLIJ_push(blobs);
image = "image";
Ext.CLIJ_automaticThreshold(blobs, image, "Otsu");

// iterative dilation
Ext.CLIJ_dilateSphere(image, "dilated0");
for (i = 0; i < numDilations; i++) {
	Ext.CLIJ_dilateSphere("dilated"+(i) % 2, "dilated"+(i+1) % 2);
}
Ext.CLIJ_reportMemory();
Ext.CLIJ_pull("dilated"+ ((i+1) % 2));

Alternatively, you can use the maximum-filter which has radius parameters. In that way you can reduce the for loop to a single line. Note: Iterative exectution of dilateSphere results in a diamond neighborhood while maximumSphere leads to a sphere.

Furthermore, we realized during a discussion here on the forum, that iterative execution of such filters may be faster than a single maximum filter depending on radius and GPU-hardware. If you want to test CLIJ2 (alpha release, not fully tested yet :wink: ), there is a built-in iterative maximum filter using sphere and box neighborhoods alternating. The resulting neighborhood looks like an octagon. This might be the fastest approximation of a sphere available in CLIJ.

Let me know if this helps!

Cheers,
Robert

1 Like

Dear Robert,
thanks for the suggestion of the alternative of the maximum filter. The data that I would like to dilate is a 3D stack. Do I understand it correctly, that for such a case the maximum-filter sphere would not be ideal, as it is for the 2D scenario only?
Ideally I would like to have a sphere like shape (so a 3D sphere not a 2D circle). Is for a 3D stack the dilate sphere the closest that I come to a circle with reasonable timing? (I first tried the normal MorphoLibJ dilate-ball and for a radius of 20, this took 36h!) Also my file is 650 MB large, so the suggestion regarding memory is definitely appreciated! :wink:

Thanks a lot. I will try if your code now does not cash my memory any more.
Best,
Andrea

1 Like

Hey @Andrea,

Depends. If you have isotropic voxels, you can use all of these filters. If your voxel-size in X/Y is very different from the size in Z (ratio > 2), you should spend some time on thinking about it. In cases where the X/Y to Z ratio is very large (e.g. 5 or more) I would do the dilation in X/Y only anyway.

To make a long story short: maximum3DSphere does the job for your scenario. It will just need 1300 MB memory in case of 650 MB input images. It also has three parameters for the radius in X,Y and Z:

run("CLIJ Macro Extensions", "cl_device=");
Ext.CLIJ_push(source);
Ext.CLIJ_maximum3DSphere(source, destination, radiusX, radiusY, radiusZ);
Ext.CLIJ_pull(destination);

Furthermore, if it’s still to slow, I recommend downsampling the dataset. This would help you with MorpholibJ as well :wink: I could assume that the lost precision because of the downsampling is negligible depending on what you are doing with the result :wink:

Let me know how it goes! I would be happy to hear how fast your final workflow is compared to the original :wink:

Cheers,
Robert

Hi Robert,
that are great suggestions. Thank you so much. I will try them and once I got it, I will feedback on how the timings went.
:v:
Best,
Andrea

1 Like

Dear Robert,
some feedback on the maximum 3D sphere:
On my originally sized data (700 MB) Fiji crashed every time I tried the maximum 3D sphere. The same if I used my non-isotropic data (150 MB) but adjusted the radii in in the maximum 3D.
However, and most importantly, it works beautifully on my downsampled data (so instead of upscaling, downscaling to obtain isotropic pixel). That data is about 7.4 MB in size and for my purpose the downscaling works just fine.
Also it is really fast and runs very smoothly.

Thank you so much for your help.

All the best,
Andrea

1 Like

:wink: Downscaling is one of the best and most under-used image analysis operations!

1 Like

Hi Andrea,

I’m glad to hear that.

Was there by chnce an error message you could provide? If Fiji crashed entirely, it sometimes leaves log files in its folder behind. On Windows, they are called something like “hs_err_pid26180.log”. If there is a file of that kind from the right time, I’d be happy to take a look at it :wink:

Thanks!

Cheers,
Robert

Hi Robert,
does this tell you anything?
Fiji Crash.txt (125.6 KB)

Have a nice day.
Cheers,
Andrea

1 Like

Somewhere in there it says

Application Specific Signatures:\
Graphics hardware encountered an error and was reset: 0x00000813\

So, yes, it helps. Thanks!

Have a nice day as well :slight_smile:

Cheers,
Robert