/** * */ package inra.ijpb.measure.region3d; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.junit.Test; import ij.IJ; import ij.ImagePlus; import ij.ImageStack; import ij.measure.Calibration; import inra.ijpb.geometry.Ellipsoid; /** * @author dlegland * */ public class EquivalentEllipsoidTest { /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testEquivalentEllipsoids() { String fileName = getClass().getResource("/files/ellipsoid_A30_B20_C10_T00_P00.tif").getFile(); ImagePlus imagePlus = IJ.openImage(fileName); assertNotNull(imagePlus); ImageStack image = imagePlus.getStack(); Calibration calib = imagePlus.getCalibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals(30, elli.radius1(), .1); assertEquals(20, elli.radius2(), .1); assertEquals(10, elli.radius3(), .1); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testEquivalentEllipsoid2() { String fileName = getClass().getResource("/files/ellipsoid_A30_B20_C10_T30_P30.tif").getFile(); ImagePlus imagePlus = IJ.openImage(fileName); assertNotNull(imagePlus); ImageStack image = imagePlus.getStack(); Calibration calib = imagePlus.getCalibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals(30, elli.radius1(), .1); assertEquals(20, elli.radius2(), .1); assertEquals(10, elli.radius3(), .1); assertEquals(30, elli.theta(), .1); assertEquals(30, elli.phi(), .1); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testEquivalentEllipsoid3() { String fileName = getClass().getResource("/files/ellipsoid_A45_B35_C25_T30_P20_R10.tif").getFile(); ImagePlus imagePlus = IJ.openImage(fileName); assertNotNull(imagePlus); ImageStack image = imagePlus.getStack(); Calibration calib = imagePlus.getCalibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals(45, elli.radius1(), .1); assertEquals(35, elli.radius2(), .1); assertEquals(25, elli.radius3(), .1); assertEquals(30, elli.phi(), 1.0); assertEquals(20, elli.theta(), 1.0); assertEquals(10, elli.psi(), 1.0); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testRandomProlateEllipsoid3() { String fileName = getClass().getResource("/files/random_prolate_ellipsoid_01.tif").getFile(); ImagePlus imagePlus = IJ.openImage(fileName); assertNotNull(imagePlus); ImageStack image = imagePlus.getStack(); Calibration calib = imagePlus.getCalibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; // Compare with values obtained with Matlab equivalent function // https://github.com/mattools/matImage/blob/master/matImage/imMeasures/imEquivalentEllipsoid.m assertEquals(25, elli.center().getX(), .5); assertEquals(25, elli.center().getY(), .5); assertEquals(25, elli.center().getZ(), .5); assertEquals(20, elli.radius1(), .5); assertEquals(5, elli.radius2(), .5); assertEquals(5, elli.radius3(), .5); assertEquals(-32.97, elli.phi(), .2); assertEquals(-51.98, elli.theta(), .2); assertEquals(163.05, elli.psi(), .2); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testCuboid_X30_Y20_Z10() { ImageStack image = createCenteredCuboid(50, 50, 50, 30, 20, 10); Calibration calib = new Calibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals( 0, ensureAngleWithin0And180(elli.phi()), 1.0); assertEquals( 0, ensureAngleWithin0And180(elli.theta()), 1.0); assertEquals( 0, ensureAngleWithin0And180(elli.psi() ), 1.0); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testCuboid_X30_Y10_Z20() { ImageStack image = createCenteredCuboid(50, 50, 50, 30, 10, 20); Calibration calib = new Calibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals( 0, ensureAngleWithin0And180(elli.phi()), 1.0); assertEquals( 0, ensureAngleWithin0And180(elli.theta()), 1.0); assertEquals(90, ensureAngleWithin0And180(elli.psi() ), 1.0); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testCuboid_X20_Y30_Z10() { ImageStack image = createCenteredCuboid(50, 50, 50, 20, 30, 10); Calibration calib = new Calibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals(90, ensureAngleWithin0And180(elli.phi()), 1.0); assertEquals( 0, ensureAngleWithin0And180(elli.theta()), 1.0); assertEquals( 0, ensureAngleWithin0And180(elli.psi() ), 1.0); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testCuboid_X10_Y30_Z20() { ImageStack image = createCenteredCuboid(50, 50, 50, 10, 30, 20); Calibration calib = new Calibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals(90, ensureAngleWithin0And180(elli.phi()), 1.0); assertEquals( 0, ensureAngleWithin0And180(elli.theta()), 1.0); assertEquals(90, ensureAngleWithin0And180(elli.psi() ), 1.0); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testCuboid_X10_Y20_Z30() { ImageStack image = createCenteredCuboid(50, 50, 50, 10, 20, 30); Calibration calib = new Calibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals( 0, ensureAngleWithin0And180(elli.phi()), 1.0); assertEquals(90, ensureAngleWithin0And180(elli.theta()), 1.0); assertEquals( 0, ensureAngleWithin0And180(elli.psi() ), 1.0); } /** * Test method for {@link inra.ijpb.measure.region3d.EquivalentEllipsoid#equivalentEllipsoids(ij.ImageStack, int[], ij.measure.Calibration)}. */ @Test public final void testCuboid_X20_Y10_Z30() { ImageStack image = createCenteredCuboid(50, 50, 50, 20, 10, 30); Calibration calib = new Calibration(); Ellipsoid elli = EquivalentEllipsoid.equivalentEllipsoids(image, new int[] {255}, calib)[0]; assertEquals( 0, ensureAngleWithin0And180(elli.phi()), 1.0); assertEquals(90, ensureAngleWithin0And180(elli.theta()), 1.0); assertEquals(90, ensureAngleWithin0And180(elli.psi() ), 1.0); } private ImageStack createCenteredCuboid(int dimX, int dimY, int dimZ, int sizeX, int sizeY, int sizeZ) { ImageStack image = ImageStack.create(dimX, dimY, dimZ, 8); int hwx = sizeX / 2; int hwy = sizeY / 2; int hwz = sizeZ / 2; for (int z = dimZ/2 - hwz; z < dimZ/2 + hwz; z++) { for (int y = dimY/2 - hwy; y < dimY/2 + hwy; y++) { for (int x = dimX/2 - hwx; x < dimX/2 + hwx; x++) { image.setVoxel(x, y, z, 255); } } } return image; } private static final double ensureAngleWithin0And180(double angleInDegrees) { return ((angleInDegrees % 180) + 180 ) % 180; } }