Closed TobiasKletter closed 3 years ago
@TobiasKletter
Did you maybe mix up volume and surface? I get:
Cell_Surface_um2 = 1602.875
Cell_Volume_um3 = 2488.75
Oops, yes I did!
But I still get a different one:
Are you measuring at the original resolution or at 0.25 um isotropic?
Measuring surfaces is highly non-trivial and depends a lot on the scaling: https://en.wikipedia.org/wiki/Coastline_paradox
Measuring at 0.25 isotropic
Amazing and very scary (see below), but I think that is what I said, this is not trivial.
spindleAligned 0.25 um isotropic:
dnaAligned 0.25 um isotropic:
original orientation 0.25 um isotropic
Oh wow this is indeed amazing and scary 👀 Should we then stick to original orientation?
Should we then stick to original orientation?
Not sure, that could also introduce a nasty bias...
@mcib3d do you have any suggestions for how to get a more stable Surface measurement? Just rotating the image we are getting up to 30% differences...
Hi @tischi,
Usually I only use surface measurements to estimate shape parameters such as compactness, and I noticed quite good results when using corrected surface. This measurement will try to smooth a bit the effect of binary blocs, but it is only available as pixel measurement. I guess if you want to improve your surface measurements, maybe you need to resample your image to be isotropic.
I guess if you want to improve your surface measurements, maybe you need to resample your image to be isotropic.
It is already isotropic 😃 Could we then just multiply the "corrected" surface with the (pixel_width)^2?
yes, use the corrected surface measurement and multiply by the pixel size² :) . In the 3D ImageJ Suite the method is then getAreaPixelsCorrected
within the Object3DVoxels
class.
@mcib3d I am not sure how to instantiate the Object3DVoxels
and how to use it. The way I did it right now I am getting a way too large surface:
Hi @tischi,
Actually, the meaning of the value to build Objects3DPopulation
and Object3DVoxels
is different. For population, it will effectively refer to the threshold, but for objectVoxel it will refer to the actual label value of the object.
Since you already have a population, that is a list of generic Object3D
, but since actually behind it is a list of Object3DVoxels
, you can simply cast your object to Object3DVoxels
: object3DVoxels = (Object3DVoxels) object;
Or, if you want to build the object directly from the image, you need its label id inside this image and build it :
object3DVoxels = new Object3DVoxels(id);
Thanks @mcib3d,
I used this code:
final ImageByte imageByte = new ImageByte( asImagePlus( mask, "", calibration ) );
Objects3DPopulation objects3DPopulation = new Objects3DPopulation( imageByte, 0 );
final Object3D object = objects3DPopulation.getObject( 0 );
final double areaPixels = object.getAreaPixels();
final double areaUnit = object.getAreaUnit();
final double areaPixelsCorrected = ((Object3DVoxels) object).getAreaPixelsCorrected();
final double areaUnitCorrected = areaPixelsCorrected * calibration.pixelWidth * calibration.pixelWidth;
final double volumeUnit = object.getVolumeUnit();
And applied it to the same three images as above (same binary data but rotated).
This seems to indicate:
In MorpholibJ they have two methods: Crofton (3 dirs.) and Crofton (13 dirs.); do you think that would be also worth checking out?
Hi @tischi ,
Ok, looks interesting, yes the corrected surface is expected to be smaller as it is a kind of smoothing of the voxels faces.
I do not know much about Crofton measurement, it seems to be a method to approximate the surface area, as it relies on planes cutting the surface, as I understand, it may be more robust to rotation, worth trying then.
@mcib3d @dlegland
I now also tried the Crofton13 method from MLJ (surfaceAreas
), and it so far is the method that gives the least varying results....
...however I also realized the during the image transformations the object boundary gets smoother and smoother (from left to right).
It is not obvious to me why this happens as I am using a nearest neighbor interpolation.
Maybe this is some known effect, i.e. smoothing during resampling after transformations???
hmmm, not so surprising: whatever the interpolation method, it will result in a loss of details. If you iterate transforms, you will obtain smoothing...
An alternative would be to compute the concatenation of the transforms, and apply it to the original image. Then the interpolation (and smoothin) appears only once.
If you iterate transforms, you will obtain smoothing...
This is very interesting and very good to know, indeed! I did not know it and don't find it obvious, is it?
For this particular project it is not an issue because we can simply measure the surface in the un-transformed image. But it worried me on general grounds that the results were so different.
@TobiasKletter I would then tend to implement the Corrected Area from 3D Image Suite (in order not to have MLJ as an additional dependency in our current code) and apply this to the untransformed cell mask. OK? Can one access the Corrected Area from the Fiji UI?
@tischi Yes agreed! I haven't spotted the Corrected Area measurement so far!
Should I anyway do it?
Yes Or is there a drawback if it's not accessible through the GUI?
Not for me. I will do it.
The corrected area value is available within the 3D Manager.
@TobiasKletter I pushed to the update site. Does it work?
@tischi It works, but it's not giving the value for the untransformed but for the spindle-aligned cell mask (1089 um2) in the sample image.
I changed it. Better now?
Yes 👍
Hi @tischi
for testing: spindle: https://www.dropbox.com/s/p93vqd3dbzw2d0p/20190227_HighZoom--W0000--P0001-T0004--0001.tif?dl=0
cell mask: https://www.dropbox.com/s/7qq0rau685xfgwg/20190227_HighZoom--W0000--P0001-T0004--0001_CellMask.tif?dl=0
Expected value: 2488.859 µm2