diff --git a/navipy/comparing/test.py b/navipy/comparing/test.py index 660cb0f7a07d7be6f8284096a7f1254d1d595e70..b7ac159edc44b7a7f82c6d10d82a70e9d64b3f35 100644 --- a/navipy/comparing/test.py +++ b/navipy/comparing/test.py @@ -14,8 +14,8 @@ class TestCase(unittest.TestCase): self.mydb = database.DataBaseLoad(self.mydb_filename) def test_imagediff_curr(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) curr2 = curr.copy() curr2[3, 5, 2, 0] = np.nan curr3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -40,8 +40,8 @@ class TestCase(unittest.TestCase): self.assertTrue(is_numeric_array(diff)) def test_imagediff_memory(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) mem2 = curr.copy() mem2[3, 5, 2, 0] = np.nan mem3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -65,8 +65,8 @@ class TestCase(unittest.TestCase): self.assertTrue(is_numeric_array(diff)) def test_rot_imagediff_curr(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) curr2 = curr.copy() curr2[3, 5, 2, 0] = np.nan curr3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -90,8 +90,8 @@ class TestCase(unittest.TestCase): self.assertTrue(is_numeric_array(diff)) def test_rotimagediff_memory(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) mem2 = curr.copy() mem2[3, 5, 2, 0] = np.nan mem3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -115,8 +115,8 @@ class TestCase(unittest.TestCase): self.assertTrue(is_numeric_array(diff)) def test_simple_imagediff_curr(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) curr2 = curr.copy() curr2[3, 5, 2, 0] = np.nan curr3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -142,8 +142,8 @@ class TestCase(unittest.TestCase): self.assertTrue(diff.shape[3] == 1) def test_simple_imagediff_mem(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) mem2 = curr.copy() mem2[3, 5, 2, 0] = np.nan mem3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -169,8 +169,8 @@ class TestCase(unittest.TestCase): self.assertTrue(diff.shape[3] == 1) def test_diff_optic_flow_memory(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) mem2 = curr.copy() mem2[3, 5, 2, 0] = np.nan mem3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -193,8 +193,8 @@ class TestCase(unittest.TestCase): self.assertTrue(is_numeric_array(vec)) def test_diff_optic_flow_curr(self): - curr = pcode.scene(self.mydb, rowid=1) - mem = pcode.scene(self.mydb, rowid=2) + curr = self.mydb.scene(rowid=1) + mem = self.mydb.scene(rowid=2) curr2 = curr.copy() curr2[3, 5, 2, 0] = np.nan curr3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] diff --git a/navipy/database/__init__.py b/navipy/database/__init__.py index ac02d211d334f4698852cf97a69ebe0d72200fe7..814069643f410a072f5c0a98f0de6ccd7f41a4b8 100644 --- a/navipy/database/__init__.py +++ b/navipy/database/__init__.py @@ -210,7 +210,7 @@ It creates three sql table on initialisation. valid = valid and bool(self.db_cursor.fetchone()[0]) return valid - def get_posid(self, posorient): + def posid(self, posorient): assert isinstance(posorient, pd.Series),\ 'posorient should be a pandas Series' where = """x>=? and x<=?""" @@ -318,7 +318,7 @@ database assert (posorient is None) or (rowid is None),\ 'posorient and rowid can not be both None' if posorient is not None: - rowid = self.get_posid(posorient) + rowid = self.posid(posorient) # Read images tablename = 'position_orientation' toreturn = pd.read_sql_query( @@ -333,20 +333,55 @@ database toreturn = toreturn.astype(float) return toreturn - def read_image(self, posorient=None, rowid=None): - """Read an image at a given position-orientation or given id of row in the \ - database. + def scene(self, posorient=None, rowid=None): + """ Return a scene at a position orientation or given rowid \ + in a given database. - :param posorient: a pandas Series with index \ - ['x','y','z','alpha_0','alpha_1','alpha_2'] - :param rowid: an integer - :returns: an image - :rtype: numpy.ndarray + :param database: a DataBaseLoad class \ + :param posorient: a pandas Series with index: \ + ['x','y','z','alpha_0,'alpha_1,'alpha_2'] (default None, i.e. not used) + :param rowid: a row identification integer for directly reading \ + in the database (default None, i.e. not used). + :returns: a scene [elevation, azimuth, channel, 1] or \ + [ommatidia,channel,1]. + :rtype: np.ndarray + + .. literalinclude:: example/database/scene.py + :lines: 14-15 + + .. plot:: example/database/scene.py """ - assert (posorient is None) or (rowid is None),\ - 'posorient and rowid can not be both None' + if (posorient is None) and (rowid is None): + raise ValueError('posorient and rowid can not be both None') if posorient is not None: - rowid = self.get_posid(posorient) + if not isinstance(posorient, pd.Series): + raise TypeError('posorient should be a pandas Series') + if posorient.empty: + raise Exception('position must not be empty') + if 'x' not in posorient.index: + raise ValueError('missing index x') + if 'y' not in posorient.index: + raise ValueError('missing index y') + if 'z' not in posorient.index: + raise ValueError('missing index z') + if 'alpha_0' not in posorient.index: + raise ValueError('missing index alpha_0') + if 'alpha_1' not in posorient.index: + raise ValueError('missing index alpha_1') + if 'alpha_2' not in posorient.index: + raise ValueError('missing index alpha_2') + if not ~np.any(pd.isnull(posorient)): + raise ValueError('posorient must not contain nan') + rowid = self.posid(posorient) + + if rowid is not None: + if not isinstance(rowid, int): + raise TypeError('rowid must be of type integer') + if rowid <= 0: + raise ValueError('rowid must be greater zero') + if rowid is np.nan: + raise ValueError('rowid must not be nan') + # Read images tablename = 'image' self.db_cursor.execute( @@ -370,7 +405,9 @@ database cmaxminrange.name = cmaxminrange.id cmaxminrange.drop('id') cmaxminrange = cmaxminrange.astype(float) - return self.denormalise_image(image, cmaxminrange) + scene = self.denormalise_image(image, cmaxminrange) + scene = scene[..., np.newaxis] + return scene def denormalise_image(self, image, cmaxminrange): assert len(image.shape) == 3,\ @@ -416,7 +453,7 @@ class DataBaseSave(DataBase): def write_image(self, posorient, image): normed_im, cmaxminrange = self.normalise_image(image, self.arr_dtype) - rowid = self.get_posid(posorient) + rowid = self.posid(posorient) # Write image tablename = 'image' params = dict() diff --git a/navipy/moving/agent.py b/navipy/moving/agent.py index f9d429a9a45761dec7195e0630c7651fd406343c..d34306b4f362676dcda263db84fa6b4e0f5b4426 100644 --- a/navipy/moving/agent.py +++ b/navipy/moving/agent.py @@ -30,7 +30,7 @@ class AbstractAgent(): if memory_friendly: self.__posorients = None else: - self.__posorients = self.db.get_posorients() + self.__posorients = self.db.posorients # set mode of motion mode_move = {'mode': 'on_cubic_grid', 'param': {'grid_spacing': @@ -217,7 +217,7 @@ class Multi(AbstractAgent): super().__init__(database_filename, False) # Init the graph self.__graph = nx.DiGraph() - for row_id, posor in self.db.get_posorients().iterrows(): + for row_id, posor in self.db.posorients.iterrows(): posor.name = row_id self.__graph.add_node(row_id, posorient=posor) diff --git a/navipy/moving/test_agent.py b/navipy/moving/test_agent.py index d088cb777db19799b8c825a0a0e1d846d223b13f..8775361fbcede6c9ee87feb54c9d41bd8ca496c5 100644 --- a/navipy/moving/test_agent.py +++ b/navipy/moving/test_agent.py @@ -84,7 +84,7 @@ class TestNavipyMovingAgent(unittest.TestCase): def test_init(self): agent = naviagent.Multi(self.mydb_filename) self.assertEqual(sorted(agent.graph.nodes), - sorted(list(self.mydb.get_posorients().index)), + sorted(list(self.mydb.posorients.index)), 'Init of graph failed. Node missmatch') def test_graph_setter(self): diff --git a/navipy/processing/pcode.py b/navipy/processing/pcode.py index 2059413f4fdffffefb5ee6620335e4817940a4c7..24bea9c826059f1edfbc21ef6728588c324f87bb 100644 --- a/navipy/processing/pcode.py +++ b/navipy/processing/pcode.py @@ -1,8 +1,7 @@ """ -place code +place code derived from scene """ import numpy as np -import pandas as pd from scipy.ndimage import maximum_filter, minimum_filter from .constants import __spherical_indeces__ from .constants import __ibpc_indeces__ @@ -14,64 +13,6 @@ from .tools import check_scene from .tools import check_viewing_direction -def scene(database, posorient=None, rowid=None): - """ Return a scene at a position orientation or given rowid \ - in a given database. - - :param database: a DataBaseLoad class \ - :param posorient: a pandas Series with index: \ - ['x','y','z','alpha_0,'alpha_1,'alpha_2'] (default None, i.e. not used) - :param rowid: a row identification integer for directly reading \ - in the database (default None, i.e. not used). - :returns: a scene [elevation, azimuth, channel, 1] or \ - [ommatidia,channel,1]. - :rtype: np.ndarray - - .. literalinclude:: example/processing/scene.py - :lines: 14-15 - - .. plot:: example/processing/scene.py - """ - # where to check if db is okay? in database? - - if posorient is not None: - if not isinstance(posorient, pd.Series): - raise TypeError('posorient should be a pandas Series') - if posorient.empty: - raise Exception('position must not be empty') - if 'x' not in posorient.index: - raise ValueError('missing index x') - if 'y' not in posorient.index: - raise ValueError('missing index y') - if 'z' not in posorient.index: - raise ValueError('missing index z') - if 'alpha_0' not in posorient.index: - raise ValueError('missing index alpha_0') - if 'alpha_1' not in posorient.index: - raise ValueError('missing index alpha_1') - if 'alpha_2' not in posorient.index: - raise ValueError('missing index alpha_2') - if not ~np.any(pd.isnull(posorient)): - raise ValueError('posorient must not contain nan') - if rowid is not None: - if not isinstance(rowid, int): - raise TypeError('rowid must be of type integer') - if rowid <= 0: - raise ValueError('rowid must be greater zero') - if rowid is np.nan: - raise ValueError('rowid must not be nan') - # assert rowid in database.index#?? - if rowid is not None or posorient is not None: - scene = database.read_image(posorient=posorient, - rowid=rowid) - # print(np.array(scene).shape) - scene = scene[..., np.newaxis] - # print(np.array(scene).shape) - return scene - else: - raise ValueError('either rowid or posoriend must be given') - - def skyline(scene): """Return the average along the elevation of a scene :param scene: the scenery at a given location (a 4d numpy array) diff --git a/navipy/processing/test.py b/navipy/processing/test.py index c8af1a99b51fa6aad3caad8022b72404891d1bf9..39b75415a3eb68f4996ba9419ebbb451c24ccc60 100644 --- a/navipy/processing/test.py +++ b/navipy/processing/test.py @@ -28,7 +28,7 @@ class TestCase(unittest.TestCase): posorient.alpha_0 = rows[3] posorient.alpha_1 = rows[2] posorient.alpha_2 = rows[4] - image = pcode.scene(self.mydb, posorient=posorient) + image = self.mydb.scene(posorient=posorient) self.assertIsNotNone(image) self.assertFalse(sum(image.shape) == 0) # print("shape",image.shape) @@ -44,7 +44,7 @@ class TestCase(unittest.TestCase): posorient2.alpha_1 = posorient.alpha_1 posorient2.alpha_2 = posorient.alpha_2 with self.assertRaises(Exception): - image = pcode.scene(self.mydb, posorient=posorient2) + image = self.mydb.scene(posorient=posorient2) # incorrect case None posorient2 = pd.Series(index=['x', 'y', 'z', @@ -56,7 +56,7 @@ class TestCase(unittest.TestCase): posorient2.alpha_1 = posorient.alpha_1 posorient2.alpha_2 = posorient.alpha_2 with self.assertRaises(ValueError): - image = pcode.scene(self.mydb, posorient=posorient2) + image = self.mydb.scene(posorient=posorient2) # incorrect case nan posorient2 = pd.Series(index=['x', 'y', 'z', @@ -68,7 +68,7 @@ class TestCase(unittest.TestCase): posorient2.alpha_1 = posorient.alpha_1 posorient2.alpha_2 = posorient.alpha_2 with self.assertRaises(ValueError): - image = pcode.scene(self.mydb, posorient=posorient2) + image = self.mydb.scene(posorient=posorient2) # incorrect case no pandas series but dict posorient2 = {} @@ -79,17 +79,17 @@ class TestCase(unittest.TestCase): posorient2['alpha_1'] = posorient.alpha_1 posorient2['alpha_2'] = posorient.alpha_2 with self.assertRaises(TypeError): - image = pcode.scene(self.mydb, posorient=posorient2) + image = self.mydb.scene(posorient=posorient2) # not working case empty posorient2 = pd.Series(index=['x', 'y', 'z', 'alpha_0', 'alpha_1', 'alpha_2']) with self.assertRaises(Exception): - image = pcode.scene(self.mydb, posorient=posorient2) + image = self.mydb.scene(posorient=posorient2) def test_skyline_scene(self): - scene = pcode.scene(self.mydb, rowid=1) + scene = self.mydb.scene(rowid=1) scene2 = scene.copy() scene2[3, 5, 2, 0] = np.nan scene3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] @@ -121,18 +121,18 @@ class TestCase(unittest.TestCase): for rowid in [0, -2]: with self.assertRaises(ValueError): # print("rowid",rowid) - pcode.scene(self.mydb, rowid=rowid) + self.mydb.scene(rowid=rowid) with self.assertRaises(TypeError): - pcode.scene(self.mydb, rowid='T') + self.mydb.scene(rowid='T') with self.assertRaises(ValueError): - pcode.scene(self.mydb, rowid=None) + self.mydb.scene(rowid=None) with self.assertRaises(TypeError): - pcode.scene(self.mydb, rowid=np.nan) + self.mydb.scene(rowid=np.nan) with self.assertRaises(TypeError): - pcode.scene(self.mydb, rowid=4.5) + self.mydb.scene(rowid=4.5) for rowid in [1, 2, 3, 4, 5]: - image = pcode.scene(self.mydb, rowid=rowid) + image = self.mydb.scene(rowid=rowid) # image=np.array(image) self.assertIsNotNone(image) self.assertFalse(sum(image.shape) == 0) @@ -144,7 +144,7 @@ class TestCase(unittest.TestCase): self.assertTrue(image.shape[1] > 0) def test_distance_channel(self): - scene = pcode.scene(self.mydb, rowid=1) + scene = self.mydb.scene(rowid=1) # should not be working for d in ['g', None, np.nan, 8.4]: with self.assertRaises(TypeError): @@ -165,7 +165,7 @@ class TestCase(unittest.TestCase): self.assertEqual(weighted_scene.shape, scene.shape) def test_contr_weight_scene(self): - scene = pcode.scene(self.mydb, rowid=1) + scene = self.mydb.scene(rowid=1) # working cases contrast = pcode.contrast_weighted_nearness(scene) @@ -193,7 +193,7 @@ class TestCase(unittest.TestCase): contrast = pcode.contrast_weighted_nearness(scene4) def test_contr_weight_contrast(self): - scene = pcode.scene(self.mydb, rowid=1) + scene = self.mydb.scene(rowid=1) for size in [9.4, 'g', None, np.nan]: with self.assertRaises(TypeError): contrast = pcode.contrast_weighted_nearness( @@ -220,7 +220,7 @@ class TestCase(unittest.TestCase): def test_pcv(self): # working case rowid = 1 - my_scene = pcode.scene(self.mydb, rowid=rowid) + my_scene = self.mydb.scene(rowid=rowid) directions = self.mydb.viewing_directions my_pcv = pcode.pcv(my_scene, directions) self.assertIsNotNone(my_pcv) @@ -261,7 +261,7 @@ class TestCase(unittest.TestCase): def test_apcv(self): # working case rowid = 1 - my_scene = pcode.scene(self.mydb, rowid=rowid) + my_scene = self.mydb.scene(rowid=rowid) # print("scene shape",my_scene.shape) directions = self.mydb.viewing_directions # print("directions",directions.shape) @@ -304,7 +304,7 @@ class TestCase(unittest.TestCase): def test_size(self): # not working cases: - scene = pcode.scene(self.mydb, rowid=1) + scene = self.mydb.scene(rowid=1) for size in [8, 1, 0, -4]: with self.assertRaises(ValueError): contrast = pcode.michelson_contrast( @@ -328,7 +328,7 @@ class TestCase(unittest.TestCase): def test_michelsoncontrast_scene(self): - scene = pcode.scene(self.mydb, rowid=1) + scene = self.mydb.scene(rowid=1) # working cases contrast = pcode.michelson_contrast(scene) diff --git a/navipy/rendering/bee_sampling.py b/navipy/rendering/bee_sampling.py index c1f388a237d0dfa1eb4ac24c3de2256202aab837..817ae03ec11cb75bbb7208238190feb7800023d7 100644 --- a/navipy/rendering/bee_sampling.py +++ b/navipy/rendering/bee_sampling.py @@ -41,18 +41,21 @@ harddrive space, as each image is composed of 4 channels of 180x360 pixels. :param alpha2: the 2nd euler angles :param alpha3: the 3rd euler angles """ - if not (isinstance(x, int) or isinstance(x, float)): - raise TypeError('x must be integer') - if not (isinstance(y, int) or isinstance(y, float)): - raise TypeError('y must be integer') - if not (isinstance(z, int) or isinstance(z, float)): - raise TypeError('z must be integer') - if not (isinstance(alpha1, float) or isinstance(alpha1, int)): - raise TypeError('alpha1 must be float') - if not (isinstance(alpha2, float) or isinstance(alpha2, int)): - raise TypeError('alpha2 must be float') - if not (isinstance(alpha3, float) or isinstance(alpha3, int)): - raise TypeError('alpha3 must be float') + if not (isinstance(x, np.ndarray) or isinstance(x, list)): + raise TypeError('x must be list or np.array') + if not (isinstance(y, np.ndarray) or isinstance(y, list)): + raise TypeError('y must be list or np.array') + if not (isinstance(z, np.ndarray) or isinstance(z, list)): + raise TypeError('z must be list or np.array') + if not (isinstance(alpha1, np.ndarray) or + isinstance(alpha1, list)): + raise TypeError('alpha1 must be list or np.array') + if not (isinstance(alpha2, np.ndarray) or + isinstance(alpha2, list)): + raise TypeError('alpha2 must be list or np.array') + if not (isinstance(alpha3, np.ndarray) or + isinstance(alpha3, list)): + raise TypeError('alpha3 must be list or np.array') [mx, my, mz, ma1, ma2, ma3] = np.meshgrid(x, y, z, diff --git a/navipy/rendering/cyber_bee.py b/navipy/rendering/cyber_bee.py index ac7a2d8e165c6c0ec091028ff68fabe898c218b0..9c203e55a30fae9d6fdc3189894cf868aa336e1f 100644 --- a/navipy/rendering/cyber_bee.py +++ b/navipy/rendering/cyber_bee.py @@ -13,6 +13,7 @@ import bpy import numpy as np import tempfile import os +import pandas as pd class Cyberbee(): @@ -199,17 +200,22 @@ class Cyberbee(): ..todo Change assert to if -> raise TypeError()/KeyError() """ - if not (isinstance(resolution, list) or + if not (isinstance(resolution, tuple) or + isinstance(resolution, list) or isinstance(resolution, np.ndarray)): - raise TypeError('resolution must be list or array') + raise TypeError('resolution must be list, array, or tuple') if not self.camera.data.type == 'PANO': raise Exception('Camera is not panoramic') if not self.camera.data.cycles.panorama_type == 'EQUIRECTANGULAR': raise Exception('Camera is not equirectangular') - self.camera.data.cycles.latitude_min = np.deg2rad(resolution[0, 0]) - self.camera.data.cycles.latitude_max = np.deg2rad(resolution[0, 1]) - self.camera.data.cycles.longitude_min = np.deg2rad(resolution[1, 0]) - self.camera.data.cycles.longitude_max = np.deg2rad(resolution[1, 1]) + self.camera.data.cycles.latitude_min = np.deg2rad( + resolution[0][0]) + self.camera.data.cycles.latitude_max = np.deg2rad( + resolution[0][1]) + self.camera.data.cycles.longitude_min = np.deg2rad( + resolution[1][0]) + self.camera.data.cycles.longitude_max = np.deg2rad( + resolution[1][1]) @property def camera_gaussian_width(self, gauss_w=1.5): @@ -260,7 +266,7 @@ class Cyberbee(): return resolution_x, resolution_y @camera_resolution.setter - def set_camera_resolution(self, resolution=[360, 180]): + def camera_resolution(self, resolution=[360, 180]): """change the camera resolution (nb of pixels) @@ -299,13 +305,21 @@ class Cyberbee(): specified by scene.camera.rotation_mode :type posorient: 1x6 double array """ - if len(posorient) != 6: - raise Exception('posorient should be a 1x6 double array') - if not (isinstance(posorient, np.ndarray) or + print(posorient) + if (isinstance(posorient, np.ndarray) or isinstance(posorient, list)): - raise TypeError('posorient must be of type array or list') - self.camera.location = posorient[:3] - self.camera.rotation_euler = posorient[3:] + + if len(posorient) != 6: + raise Exception('posorient should be a 1x6 double array') + self.camera.location = posorient[:3] + self.camera.rotation_euler = posorient[3:] + elif isinstance(posorient, pd.Series): + self.camera.location = posorient.loc[['x', 'y', 'z']].values + self.camera.rotation_euler = \ + posorient.loc[['alpha_0', 'alpha_1', 'alpha_2']].values + else: + raise TypeError( + 'posorient must be of type array, list, or pandas Series') # Render bpy.ops.render.render()