Most informative max projection

Hi,

I have z-stacks of tube-like structures in all orientations. I would like to make max projections of individual tubes on the axis that loses the least information. For example if I have a vertical tube and I make a max pro on Z axis the projection is a disk but if I project orthogonaly then I get a side view of the tube.

So my question is whether there is a way of making max projections on the axis that keeps the most information sort of automatically ? In other words what would be the best way of projecting 3D structures to a single plane losing the least structural information.

Thanks a lot

@LPUoO Interesting question. What constitutes “loss of information” here? Here are a couple of possibilities:

  1. The number of samples that are collapsed into one? This is easy to know; just project over the shortest axis. E.g. in a 512 x 512 x 50 image stack, Z-projection will lose the fewest number of pixels, since you will end up with a 512 x 512 image—whereas an X or Y projection will result in a 512 x 50 image.

  2. The contrast of the samples being collapsed? This can be computed. For example, you could create a line through the projected axis for each sample, then measure standard deviation, which IIUC corresponds to RMS contrast, a popular way of measuring image contrast. Sum the standard deviation value over all samples for a given projection, and then compare versus the other potential projections you are considering, to see which projection wins.

  3. Some other metric of “lossiness” that doesn’t occur to me off the top of my head.

Implementing (1) would be a very short macro. Implementing (2) would be a little more involved, but certainly doable.

@ctrueden, thanks for the reply. So basically I would like to project a 3D object in a way that creates the biggest 2D object.

So projecting over the shortest axis of the bounding box is probably a good idea under the condition that the bounding box is actually as small as possible. As far as I know the “standard” bounding box is always as in (1) wile the optimal might be like (2)
image image.

So, if it is possible to make 3D bounding boxes like in (2) then projection over the shortest axis in probably a good option.

But is it possible to make 3D bounding boxes like in (2) ?

Thanks a lot

Yes. What you are talking about is the “minimum bounding rectangle” or “smallest enclosing rectangle” in 3D:

The ImageJ Ops library has an implementation of this routine as geom.smallestEnclosingBoundingBox. You must first convert your image to a mesh using geom.marchingCubes, then compute the minimum bounding rectangle on that. Once you have the smallest enclosing rectangle, you can do your projection along the shortest of the three rectangle axes. The ImgLib2 libraries make this much more feasible.

I started trying to write a script demonstrating this end-to-end. However, there is a big problem: the ImageJ Ops geom.smallestEnclosingBoundingBox routine was never actually implemented! :man_facepalming:

So I fear we need to use some other implementation. ImageJ is good at doing this in 2D—see e.g. here:

@mdoube @tibuch @kephale @gabriel @ThomasBoudier Do any of you know if there is an easily usable way in ImageJ to do 3D rotating calipers to get the 3D minimum bounding box?

3 Likes

Hello @LPUoO ,

what you want to do looks to me very similar to a principal component analysis, in which you reduce the dimensionnality of a set of points while preserving its variability as much as possible. In doing so, all the points are taken into account in the calculation. The minimal bounding box, on the other hand, is based on the extremal points of your shape. So, if you’re not lucky, the minimal bounding box may not provide the axis with the highest amount of information - although I’m pretty sure it works well with regular/smooth tube-like structures.

If I were you, I would use the parameters of the 3D equivalent ellipsoid provided by the 3D roi suite of @ThomasBoudier. I don’t know the details of the computation, but the results should be close to those of a PCA, with the first two axes defining the plane maximizing the variability of your points. Then you can rotate your shape according to the axes angles and project it along the Z axis, or project the points directly on the plane (though I’m not saying it’s straightforward to program).

If you want to stick to the bounding box solution, though, you can find convenient to replace it with the Feret diameter, which gives you the longest line segment between two points at the border of your shape.

Good luck!

Nicolas

Sorry no - sounds hard, but fun if one had time.

Thanks @Nicolas for the suggestion,
I’ve been looking into the possibility of using the ellipse and I came up with the following:

id=getImageID();
run("Convert to Mask", "method=Default background=Dark black");

run("3D Ellipsoid Fitting", " ");

XY= getResult("XY0(deg)", 0);
XZ= getResult("XZ0(deg)", 0);
YZ= getResult("YZ0(deg)", 0);

selectImage(id);
run("TransformJ Rotate", "z-angle="+XZ+" y-angle="+XY+" x-angle="+YZ+" interpolation=Linear background=0.0 adjust"); //angles in here are incorrect
rename("Rotated");

run("Z Project...", "projection=[Max Intensity]");
//run("Clear Results");

But I am unsure about which angles of the ellipse to use because the results table provides all the following:
XY0(deg)
XZ0(deg)
YZ0(deg)
XY1(deg)
XZ1(deg)
YZ1(deg)
XY2(deg)
XZ2(deg)
YZ2(deg)

What is the difference between the values 0, 1 and 2 ?

Thank you very much

Hi @LPUoO and @Nicolas,

The oriented bounding box is implemented in the 3D ellipsoid fitting plugin. The idea is to rotate all border points of the object so that the object is aligned with the X-axis, then the bounding box is computed. I did not fully test it, but the volume of this oriented bounding box is available in the plugin as Vbb0.

The values 0,1,2 refer to the eigen vectors of the ellipsoid, the vector 2 will correspond to the main axis of the ellipsoid. I guess you then need to align this vector to the X axis.

Hope this helps and do not hesitate if you have more questions or comments.

Thomas

1 Like

Thank you @ThomasBoudier.
@LPUoO, you now have most the information you need. Just be careful that the rotation conventions for TransformJ may not be the same as the ones in 3D Image suite. I suggest you define a simple 3D shape with known orientation (e.g. an 2D ellipse repeated over a series of images with center translating along x or y), then play with it until you find out which angle you need.