def test_ellipsoid_stats(): # Test comparison values generated by Wolfram Alpha vol, surf = ellipsoid_stats(6, 10, 16) assert_allclose(1280 * np.pi, vol, atol=1e-4) assert_allclose(1383.28, surf, atol=1e-2) # Test when a <= b <= c does not hold vol, surf = ellipsoid_stats(16, 6, 10) assert_allclose(1280 * np.pi, vol, atol=1e-4) assert_allclose(1383.28, surf, atol=1e-2) # Larger test to ensure reliability over broad range vol, surf = ellipsoid_stats(17, 27, 169) assert_allclose(103428 * np.pi, vol, atol=1e-4) assert_allclose(37426.3, surf, atol=1e-1)
def test_ellipsoid_stats(): # Test comparison values generated by Wolfram Alpha vol, surf = ellipsoid_stats(6, 10, 16) assert(round(1280 * np.pi, 4) == round(vol, 4)) assert(1383.28 == round(surf, 2)) # Test when a <= b <= c does not hold vol, surf = ellipsoid_stats(16, 6, 10) assert(round(1280 * np.pi, 4) == round(vol, 4)) assert(1383.28 == round(surf, 2)) # Larger test to ensure reliability over broad range vol, surf = ellipsoid_stats(17, 27, 169) assert(round(103428 * np.pi, 4) == round(vol, 4)) assert(37426.3 == round(surf, 1))
def test_ellipsoid_stats(): # Test comparison values generated by Wolfram Alpha vol, surf = ellipsoid_stats(6, 10, 16) assert (round(1280 * np.pi, 4) == round(vol, 4)) assert (1383.28 == round(surf, 2)) # Test when a <= b <= c does not hold vol, surf = ellipsoid_stats(16, 6, 10) assert (round(1280 * np.pi, 4) == round(vol, 4)) assert (1383.28 == round(surf, 2)) # Larger test to ensure reliability over broad range vol, surf = ellipsoid_stats(17, 27, 169) assert (round(103428 * np.pi, 4) == round(vol, 4)) assert (37426.3 == round(surf, 1))
def test_marching_cubes_anisotropic(): # test spacing as numpy array (and not just tuple) spacing = np.array([1., 10 / 6., 16 / 6.]) ellipsoid_anisotropic = ellipsoid(6, 10, 16, spacing=spacing, levelset=True) _, surf = ellipsoid_stats(6, 10, 16) # Classic verts, faces = marching_cubes_classic(ellipsoid_anisotropic, 0., spacing=spacing) surf_calc = mesh_surface_area(verts, faces) # Test within 1.5% tolerance for anisotropic. Will always underestimate. assert surf > surf_calc and surf_calc > surf * 0.985 # Lewiner verts, faces = marching_cubes_lewiner(ellipsoid_anisotropic, 0., spacing=spacing)[:2] surf_calc = mesh_surface_area(verts, faces) # Test within 1.5% tolerance for anisotropic. Will always underestimate. assert surf > surf_calc and surf_calc > surf * 0.985 # Test spacing together with allow_degenerate=False marching_cubes_lewiner(ellipsoid_anisotropic, 0, spacing=spacing, allow_degenerate=False)
def test_marching_cubes_isotropic(): ellipsoid_isotropic = ellipsoid(6, 10, 16, levelset=True) _, surf = ellipsoid_stats(6, 10, 16) verts, faces = marching_cubes(ellipsoid_isotropic, 0.) surf_calc = mesh_surface_area(verts, faces) # Test within 1% tolerance for isotropic. Will always underestimate. assert surf > surf_calc and surf_calc > surf * 0.99
def test_marching_cubes_anisotropic(): spacing = (1.0, 10 / 6.0, 16 / 6.0) ellipsoid_anisotropic = ellipsoid(6, 10, 16, spacing=spacing, levelset=True) _, surf = ellipsoid_stats(6, 10, 16) verts, faces = marching_cubes(ellipsoid_anisotropic, 0.0, spacing=spacing) surf_calc = mesh_surface_area(verts, faces) # Test within 1.5% tolerance for anisotropic. Will always underestimate. assert surf > surf_calc and surf_calc > surf * 0.985
def test_marching_cubes_anisotropic(): sampling = (1., 10 / 6., 16 / 6.) ellipsoid_anisotropic = ellipsoid(6, 10, 16, sampling=sampling, levelset=True) _, surf = ellipsoid_stats(6, 10, 16, sampling=sampling) verts, faces = marching_cubes(ellipsoid_anisotropic, 0., sampling=sampling) surf_calc = mesh_surface_area(verts, faces) # Test within 1.5% tolerance for anisotropic. Will always underestimate. assert surf > surf_calc and surf_calc > surf * 0.985
def test_marching_cubes_anisotropic(): spacing = (1., 10 / 6., 16 / 6.) ellipsoid_anisotropic = ellipsoid(6, 10, 16, spacing=spacing, levelset=True) _, surf = ellipsoid_stats(6, 10, 16) # Classic verts, faces = marching_cubes_classic(ellipsoid_anisotropic, 0., spacing=spacing) surf_calc = mesh_surface_area(verts, faces) # Test within 1.5% tolerance for anisotropic. Will always underestimate. assert surf > surf_calc and surf_calc > surf * 0.985 # Lewiner verts, faces = marching_cubes_lewiner(ellipsoid_anisotropic, 0., spacing=spacing)[:2] surf_calc = mesh_surface_area(verts, faces) # Test within 1.5% tolerance for anisotropic. Will always underestimate. assert surf > surf_calc and surf_calc > surf * 0.985 # Test spacing together with allow_degenerate=False marching_cubes_lewiner(ellipsoid_anisotropic, 0, spacing=spacing, allow_degenerate=False)
def gen3d(shape, r_range, h_range, n_ell=1, noise=False, label=False, ell_stats=False): ''' 3-dimensional image generator for hsi images :param shape: :param r_range: :param h_range: :param n_ell: :param noise: :return: ''' data = np.zeros(shape) if noise: data = random_noise(data) data *= 200 ells = [] r1 = np.random.randint(r_range[0], r_range[1], n_ell) r2 = np.random.randint(r_range[0], r_range[1], n_ell) h = np.random.randint(h_range[0], h_range[1], n_ell) # assuming shape is 240, 200, 200 # and r_range max val < 30 # and h_range max val < 240 # and 1 <= n_ell <= 6 centers = [ [120, 40, 40], [120, 40, 80], [120, 40, 120], [120, 80, 40], [120, 80, 80], [120, 80, 120], [120, 120, 40], [120, 120, 80], [120, 120, 120], ] for i in range(0, n_ell): ell = ellipsoid(h[i], r1[i], r2[i], levelset=True) ell *= -500 ell += 500 # c = centers[i] # xL = c[1] - r1[i] - 3 # xR = c[1] + r1[i] - 3 # yL = c[1] - r2[i] - 3 # yR = c[1] + r2[i] - 3 # bL = c[0] - h[i] # bR = c[0] + h[i] # data[bL:bR, xL:xR, yL:yR] += ell # ells.append(ell) data = add_ell(data, ell) if ell_stats: stats = [] for i in range(0, n_ell): stat = ellipsoid_stats(h[i], r1[i], r2[i]) stats.append(stat) return data
def add_ellipsoid(self, center, a, b, c, scale, bands=None, rot=0.0, cut=None, stats=False, name=None): ''' Adds ellipsoid structure in simulated HSI. :param center: tuple of 2 ints centering structure in image :param a: length of ellipsoid semi-major x-axis - currently used for bands :param b: length of ellipsoid semi-major y-axis - currently used for x-axis in image :param c: length of ellipsoid semi-major z-axis - currently used for y-axis in image - will be switching to kwargs or other method of creating ellipsoids :param scale: tuple of 2 ints/floats to alter reflectance of structure across pixels/bands - typically (-a, b) such that levelset of ellipsoid is flipped by X *= (-a) - and raised by X += b :param bands: tuple of 2 ints the band range to add structure :param rot: rotation elliptical structures in image - currently only multiples of pi/2 accepted for rotations :param cut: cut a subsection of ellipsoid structure - not implemented at the moment :param stats: bool (T/F) of whether or not to collect ellipsoid stats :param name: unique string for dict key of ellipsoid stats - must have valid string if stats==True :return: None, alters base image from self ''' ell = ellipsoid( a, b, c, levelset=True, ) ell *= scale[0] ell += scale[1] d1, d2, d3 = self._s ed1, ed2, ed3 = ell.shape c1 = int(ed2 / 2) + 1 c2 = int(ed3 / 2) + 1 rr, cc = ellipse(c1, c2, b, c, shape=(ed2, ed3)) rr1, cc1 = ellipse(center[0], center[1], b, c, shape=(d2, d3), rotation=rot) if d1 < ed1: self._img[:d1, rr1, cc1] += ell[:d1, rr, cc] else: self._img[:ed1, rr1, cc1] += ell[:ed1, rr, cc] if stats: stat = ellipsoid_stats(a, b, c) try: self.obs[name] = [center, stat] except ValueError: raise Exception( "if stats=True, name must be a unique string not in self.obs" )
def gen_ell_stats(self): a, b, c = self.axes self.stats = ellipsoid_stats(a, b, c)
def gen_ellipsoid(self, a, b, c, stats=False, **kwargs): self.axes = (a, b, c) self.structure = ellipsoid(a, b, c, **kwargs, levelset=True) if stats: self.stats = ellipsoid_stats(a, b, c)