def test_bounds(self):
     points = np.array([[0.6, 0.1, -0.1], [1.1, 2.1, 3.1], [1.3, 2.2, 3.4]])
     min_corner = Vector3f(-1, -2, -3)
     vg = VoxelGrid(0.5, min_corner=min_corner, points=points)
     bounds = vg.bounds()
     expected_bounds = Box3d(Vector3f(0.5, 0, -0.5),
                             Vector3f(1.5, 2.5, 3.5))
     self.assertAlmostEquals(bounds, expected_bounds)
 def test_min_corner_offset(self):
     """
     Test with a non-zero min_corner.
     """
     points = np.array([[0.1, 0.1, 0.1], [1.1, 2.1, 3.1], [1.3, 2.2, 3.4]])
     vg = VoxelGrid(1, min_corner=Vector3f(-1, -2, -3), points=points)
     centers = vg.voxel_centers()
     expected_centers = np.array([[0.5, 0.5, 0.5], [1.5, 2.5, 3.5]])
     np.testing.assert_array_almost_equal(centers, expected_centers)
 def test_constructor_with_points(self):
     """
     Tests voxel_centers.  Verifies that multiple points in the same voxel
     are deduplicated.
     """
     points = np.array([[0.1, 0.1, 0.1], [1.1, 1.1, 1.1], [1.3, 1.2, 1.4]])
     vg = VoxelGrid(0.5, min_corner=Vector3f(0, 0, 0), points=points)
     centers = vg.voxel_centers()
     expected_centers = np.array([[0.25, 0.25, 0.25], [1.25, 1.25, 1.25]])
     np.testing.assert_array_almost_equal(centers, expected_centers)
    def test_add_points(self):
        """
        Add additional points to an initial set.  Checks that redundant
        voxels are counted only once.
        """

        points = np.array([[0.1, 0.1, 0.1], [1.1, 2.1, 3.1], [1.3, 2.2, 3.4]])
        vg = VoxelGrid(1, min_corner=Vector3f(-1, -2, -3), points=points)
        points2 = np.array([[0.2, 0.2, 0.3], [2, 2, 2], [4, 4, 4]])
        vg.add_points(points2)
        centers = vg.voxel_centers()
        expected_centers = np.array([[0.5, 0.5, 0.5], [2.5, 2.5, 2.5],
                                     [1.5, 2.5, 3.5], [4.5, 4.5, 4.5]])
        np.testing.assert_array_almost_equal(centers, expected_centers)
 def test_constructor(self):
     """
     Creates a simple voxel grid and checks its attributes.
     """
     expected_min_corner = Vector3f(-5.1, -6.2, -7.5)
     vg = VoxelGrid(0.2, expected_min_corner)
     self.assertAlmostEqual(vg.voxel_size, 0.2)
     np.testing.assert_array_equal(vg.min_corner, expected_min_corner)
示例#6
0
    def setUp(self):
        # create sample bounding box, meshes, and voxel grid objects
        self.bounds = Box3d([-1.5, -2.2, 3], [4, 4.1, 6.5])
        textured_mesh = self.bounds.to_textured_mesh()
        self.meshes = GltfModel.from_textured_mesh(textured_mesh)
        points = np.array([[0.1, 0.1, 0.1], [1.1, 1.1, 1.1], [1.3, 1.2, 1.4]])
        self.voxels = VoxelGrid(0.5,
                                min_corner=Vector3f(0, 0, 0),
                                points=points)

        # and pose
        rot = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]], dtype=float)
        trans = Vector3f(1, 1, 1)
        self.pose = Pose3(rot, trans)

        # Create temporary outout directory.
        self.temp_directory = tempfile.mkdtemp()
示例#7
0
    def load(cls, project_type, base_elem, path=None):
        """
        Factory method to create a ProjectObject by reading it from disk and
        xml.
        Note: If <project_type> is bounding_box, no file is read and <path>
        is not relevant.

        Inputs:
        project_type (string) - Specifies the project type to construct (valid
            values are "bounding_box", "voxels", or "meshes")
        base_elem (ET.Element) - An Element with tag "element" and appropriate
            sub-elements.
        path (string) - path to project directory (only required if project_type
            is voxels or mesh).

        Return:
        New ProjectObject

        Exceptions:
        ValueError - If base_elem is not <element> or if none of its children is <id>.
        ValueError - If project_type is not valid.
        IOError - if file cannot be read.
        """
        (id, pose, category, bounds, symmetry, score, evaluated) = \
            cls._parse_xml(base_elem)

        # load file-based attributes and return the constructed object
        if project_type == "bounding_box":
            return ProjectObject.gen_bounding_box_object(id=id,
                                                         bounds=bounds,
                                                         pose=pose,
                                                         category=category,
                                                         symmetry=symmetry,
                                                         score=score,
                                                         evaluated=evaluated)
        elif project_type == "voxels":
            voxels = VoxelGrid.from_file(os.path.join(path, id + ".h5"))
            return ProjectObject.gen_voxels_object(id=id,
                                                   bounds=bounds,
                                                   voxels=voxels,
                                                   pose=pose,
                                                   category=category,
                                                   symmetry=symmetry,
                                                   score=score,
                                                   evaluated=evaluated)
        elif project_type == "meshes":
            meshes = GltfModel.load_from_glb(os.path.join(path, id + ".glb"))
            return ProjectObject.gen_meshes_object(id=id,
                                                   bounds=bounds,
                                                   meshes=meshes,
                                                   pose=pose,
                                                   category=category,
                                                   symmetry=symmetry,
                                                   score=score,
                                                   evaluated=evaluated)
        else:
            raise ValueError("Invalid project_type: " + project_type)
    def test_file_io(self):
        """
        Test round trip writing and reading a simple h5 file.
        """
        temp_directory = tempfile.mkdtemp()
        filename = os.path.join(temp_directory, "test.h5")

        points = np.array([[0.1, 0.1, 0.1], [1.1, 2.1, 3.1], [1.3, 2.2, 3.4]])
        voxel_size = 0.5
        min_corner = Vector3f(-1, -2, -3)
        vg = VoxelGrid(voxel_size, min_corner=min_corner, points=points)

        # test writing
        vg.save(filename)
        self.assertTrue(os.path.isfile(filename))

        # test reading
        vg2 = VoxelGrid.from_file(filename)
        self.assertAlmostEquals(voxel_size, vg2.voxel_size)
        np.testing.assert_array_almost_equal(vg.min_corner, vg2.min_corner)
        shutil.rmtree(temp_directory)
示例#9
0
    def test_voxel_io(self):
        """Test reading and writing voxel objects."""
        points = np.array([[0.1, 0.1, 0.1], [1.1, 1.1, 1.1], [1.3, 1.2, 1.4]])
        vg = VoxelGrid(0.5, min_corner=Vector3f(0, 0, 0), points=points)
        po = ProjectObject.gen_voxels_object(id="foobar",
                                             voxels=vg,
                                             pose=self.pose,
                                             category="chair")
        self.assertIsInstance(self.temp_directory, str)
        po_xml = po.save(self.temp_directory)
        po2 = ProjectObject.load("voxels", po_xml, self.temp_directory)

        self.assertTrue(po2.almost_equal(po))
示例#10
0
class TestProjectObject(unittest.TestCase):
    """Unit tests for ProjectObject class"""
    def setUp(self):
        # create sample bounding box, meshes, and voxel grid objects
        self.bounds = Box3d([-1.5, -2.2, 3], [4, 4.1, 6.5])
        textured_mesh = self.bounds.to_textured_mesh()
        self.meshes = GltfModel.from_textured_mesh(textured_mesh)
        points = np.array([[0.1, 0.1, 0.1], [1.1, 1.1, 1.1], [1.3, 1.2, 1.4]])
        self.voxels = VoxelGrid(0.5,
                                min_corner=Vector3f(0, 0, 0),
                                points=points)

        # and pose
        rot = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]], dtype=float)
        trans = Vector3f(1, 1, 1)
        self.pose = Pose3(rot, trans)

        # Create temporary outout directory.
        self.temp_directory = tempfile.mkdtemp()

    def tearDown(self):
        """Clean up: remove temporary outout directory."""
        shutil.rmtree(self.temp_directory)

    def test_constructor(self):
        """
        Test constructor.
        """
        po = ProjectObject(id="1",
                           project_type="bounding_box",
                           bounds=self.bounds)

        self.assertTrue(isinstance(po.pose, Pose3))
        self.assertTrue(isinstance(po.category, "".__class__))
        po.pose.assert_almost_equal(Pose3())
        self.assertTrue(po.bounds.almost_equal(self.bounds))
        self.assertIs(po.meshes, None)
        self.assertIs(po.voxels, None)
        self.assertTrue(po.category == "unknown")
        self.assertEqual(po.id, "1")
        self.assertEqual(po.symmetry, ObjectSymmetry())
        self.assertAlmostEqual(po.score, -1)
        self.assertEqual(po.evaluated, True)

    def test_almost_equal(self):
        object1 = ProjectObject.example(id="foobar")
        self.assertTrue(object1.almost_equal(object1))
        object2 = ProjectObject.example(id="not_foobar")
        self.assertFalse(object1.almost_equal(object2))

    def test_init(self):
        """Test common construction."""
        po = ProjectObject.example()

        self.assertTrue(isinstance(po.pose, Pose3))
        self.assertTrue(isinstance(po.meshes, GltfModel))
        self.assertEqual(po.meshes.num_primitive_meshes(), 1)
        self.assertEqual(po.meshes.num_nodes(), 1)
        self.assertEqual(po.meshes.num_buffers(), 1)
        self.assertEqual(po.meshes.num_images(), 2)
        self.assertTrue(isinstance(po.category, "".__class__))
        self.assertTrue(isinstance(po.symmetry, ObjectSymmetry))
        self.assertEqual(po.category, "chair")
        self.assertEqual(po.id, "1")
        self.assertAlmostEqual(po.score, 0.57)
        self.assertEqual(po.evaluated, False)

    def test_factory_methods(self):
        """Test the gen_<X> methods for the 3 project_types"""

        po = ProjectObject.gen_bounding_box_object(id="1", bounds=self.bounds)
        self.assertEqual(po.project_type, "bounding_box")
        self.assertAlmostEqual(po.bounds, self.bounds)
        self.assertEqual(po.id, "1")

        po = ProjectObject.gen_voxels_object(id="2", voxels=self.voxels)
        self.assertEqual(po.project_type, "voxels")
        self.assertAlmostEqual(po.voxels.bounds(), self.voxels.bounds())
        self.assertEqual(po.id, "2")

        po = ProjectObject.gen_meshes_object(id="3", meshes=self.meshes)
        self.assertEqual(po.project_type, "meshes")
        self.assertEqual(po.meshes.num_primitive_meshes(),
                         self.meshes.num_primitive_meshes())
        self.assertEqual(po.id, "3")

    def test_setting(self):
        """Test setting elements."""

        po = ProjectObject.gen_meshes_object(id="-1", meshes=self.meshes)
        po.pose = self.pose
        po.category = "table"
        po.symmetry = ObjectSymmetry.example()
        po.score = 0.23
        po.evaluated = True

        self.assertTrue(isinstance(po.pose, Pose3))
        self.assertAlmostEqual(po.pose, self.pose)
        self.assertTrue(isinstance(po.meshes, GltfModel))
        self.assertTrue(isinstance(po.category, "".__class__))
        self.assertTrue(isinstance(po.symmetry, ObjectSymmetry))
        self.assertEqual(po.category, "table")
        self.assertEqual(po.id, "-1")
        self.assertEqual(po.symmetry, ObjectSymmetry.example())
        self.assertAlmostEqual(po.score, 0.23)
        self.assertEqual(po.evaluated, True)

    def test_xml(self):
        """Test converting to and from xml."""

        s = """<element><id>floor1</id><category>floor</category><bounds>\
<corner1>0., 0., 0.</corner1><corner2>0., 0., 0.</corner2></bounds>\
<pose><translation>-131.596614 ,  -39.9279011,   92.1260558</translation>\
<rotation><c1>1., 0., 0.</c1><c2>0., 1., 0.</c2><c3>0., 0., 1.</c3></rotation>\
</pose><symmetry><x>twoFold</x><y>twoFold</y><z>fourFold</z></symmetry>\
<detectionScore>0.23</detectionScore><evaluated>True</evaluated></element>"""
        object_xml = ET.fromstring(s)
        (id, pose, category, bounds, symmetry, score, evaluated) = \
            ProjectObject._parse_xml(object_xml)
        project_object = ProjectObject.gen_bounding_box_object(
            id, bounds, pose, category, symmetry, score, evaluated)
        object_xml2 = project_object._to_xml()
        self.assertEqual(ET.tostring(object_xml2, encoding="unicode"), s)

    def test_meshes_io(self):
        """Test reading and writing gltf objects."""
        po = ProjectObject(
            id="foobar",
            project_type="meshes",
            meshes=self.meshes,
            pose=self.pose,
            category="chair",
        )

        object_xml = po.save(self.temp_directory)
        po2 = ProjectObject.load("meshes", object_xml, self.temp_directory)
        self.assertTrue(po2.almost_equal(po))

    def test_bounding_box_io(self):
        """
        Test reading and writing a bounding_box object.
        """

        s = """<element><id>floor1</id><category>floor</category><bounds>\
<corner1>0., 0., 0.</corner1><corner2>0., 0., 0.</corner2></bounds>\
<pose><translation>-131.596614 ,  -39.9279011,   92.1260558</translation>\
<rotation><c1>1., 0., 0.</c1><c2>0., 1., 0.</c2><c3>0., 0., 1.</c3></rotation>\
</pose><symmetry><x>twoFold</x><y>twoFold</y><z>fourFold</z></symmetry>\
<detectionScore>0.23</detectionScore><evaluated>True</evaluated></element>"""
        object_xml = ET.fromstring(s)
        project_object = ProjectObject.load("bounding_box", object_xml)
        object_xml2 = project_object.save("bounding_box")
        self.assertEqual(ET.tostring(object_xml2, encoding="unicode"), s)

    def test_voxel_io(self):
        """Test reading and writing voxel objects."""
        points = np.array([[0.1, 0.1, 0.1], [1.1, 1.1, 1.1], [1.3, 1.2, 1.4]])
        vg = VoxelGrid(0.5, min_corner=Vector3f(0, 0, 0), points=points)
        po = ProjectObject.gen_voxels_object(id="foobar",
                                             voxels=vg,
                                             pose=self.pose,
                                             category="chair")
        self.assertIsInstance(self.temp_directory, str)
        po_xml = po.save(self.temp_directory)
        po2 = ProjectObject.load("voxels", po_xml, self.temp_directory)

        self.assertTrue(po2.almost_equal(po))

    def test_transform_pose(self):
        po = ProjectObject(id="1", bounds=self.bounds, pose=Pose3())
        po2 = po.transform_pose(self.pose)
        self.assertTrue(po2.pose.almost_equal(self.pose))