Skip to content
Snippets Groups Projects
Commit 82223b7d authored by Olivier Bertrand's avatar Olivier Bertrand
Browse files

Add viewing dir table to save viewing direction

parent 1b7add8a
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,7 @@ import navipy.maths.constants as mconst
from navipy.trajectories import Trajectory
from navipy.scene import __spherical_indeces__
import logging
import numbers
def adapt_array(arr):
......@@ -121,7 +122,6 @@ class DataBase():
filename, channels))
self.filename = filename
self.channels = channels
self.viewing_directions = None
self.normalisation_columns = list()
for chan_n in self.channels:
self.normalisation_columns.append(str(chan_n) + '_max')
......@@ -139,11 +139,10 @@ class DataBase():
self.tablecolumns['position_orientation']['q_3'] = 'real'
self.tablecolumns['position_orientation']['frame_i'] = 'real'
self.tablecolumns['position_orientation']['rotconv_id'] = 'string'
self.tablecolumns['viewing_directions'] = dict()
self.tablecolumns['viewing_directions']['data'] = 'real'
self.tablecolumns['image'] = dict()
self.tablecolumns['image']['data'] = 'array'
# self.tablecolumns['viewing_directions'] = dict()
# self.tablecolumns['viewing_directions']['elevation'] = 'array'
# self.tablecolumns['viewing_directions']['azimuth'] = 'array'
self.tablecolumns['normalisation'] = dict()
for col in self.normalisation_columns:
self.tablecolumns['normalisation'][col] = 'real'
......@@ -181,13 +180,52 @@ class DataBase():
self.db_cursor.execute(
"create table {} {}".format(key, columns))
self.db.commit()
self.__nbaz = None
self.__nbel = None
self.__viewing_dir = None
azimuth = np.deg2rad(np.linspace(-180, 180, 360))
elevation = np.deg2rad(np.linspace(-90, 90, 180))
[ma, me] = np.meshgrid(azimuth, elevation)
self.viewing_directions = np.zeros((ma.shape[0], ma.shape[1], 2))
self.viewing_directions[..., __spherical_indeces__['elevation']] = me
self.viewing_directions[..., __spherical_indeces__['azimuth']] = ma
@property
def viewing_directions(self):
if self.__viewing_dir is None:
rowid = 1
tablename = 'viewing_directions'
self.db_cursor.execute(
"""
SELECT data
FROM {}
WHERE (rowid=?)
""".format(tablename), (rowid,))
self.__viewing_dir = self.db_cursor.fetchone()[0]
return self.__viewing_dir.copy()
@viewing_directions.setter
def viewing_directions(self, viewdir):
"""Get the viewing direction from images
:param az_lim: (min,max) of the azimuth angles
:param el_lim: (min,max) of the elevation angles
:returns: viewing direction of every pixels
:rtype: np.array
"""
if self.__viewing_dir is None:
msg = 'write viewing direction'
self._logger.info(msg)
if isinstance(viewdir, np.ndarray):
tablename = 'viewing_directions'
params = dict()
params['rowid'] = 1
params['data'] = viewdir
self.insert_replace(tablename, params)
else:
msg = 'viewdir should be a numpy nd.array'
msg += ' and not {}'.format(type(viewdir))
self._logger.exception(msg)
raise TypeError(msg)
else:
msg = 'viewing direction has already been set'
self._logger.exception(msg)
raise Exception(msg)
def table_exist(self, tablename):
"""
......@@ -293,8 +331,10 @@ class DataBase():
raise Exception(msg)
found_convention = False
index = posorient.index
if isinstance(posorient.name, int):
msg = 'posorient.name should give the frame #'
if not isinstance(posorient.name, numbers.Number):
msg = 'posorient.name should give the frame #\n'
msg += ' posorient.name: {}\n'.format(posorient.name)
msg += ' type(posorient.name): {}'.format(type(posorient.name))
self._logger.exception(msg)
raise Exception(msg)
frame_i = posorient.name
......
......@@ -16,6 +16,7 @@ import yaml # Used to load config files
import pkg_resources
from navipy.maths.homogeneous_transformations import compose_matrix
from navipy.maths.quaternion import matrix as quatmatrix
from navipy.scene import spherical_indeces
import navipy.maths.constants as constants
from navipy.trajectories import Trajectory
from PIL import Image
......@@ -48,6 +49,11 @@ class AbstractRender():
""" worldlimit"""
self.__worldlimit = worldlimit
@property
def viewing_directions(self):
""" Need to be implemented by children classes """
return None
def render_trajectory(self, outputfile,
trajectory, imformat='.jpg'):
"""
......@@ -84,6 +90,8 @@ class AbstractRender():
mode='a',
channels=['R', 'G', 'B', 'D'],
arr_dtype=np.uint8)
self._logger.debug('database created')
dataloger.viewing_directions = self.viewing_directions
# We now can render
self._logger.info('Start rendering')
for frame_i, posorient in trajectory.iterrows():
......@@ -96,6 +104,7 @@ class AbstractRender():
# Avoid rerendering by checking if data already
# exist
if mode == 'database':
self._logger.warning(posorient)
rowid = dataloger.get_posid(posorient)
if dataloger.check_data_validity(rowid):
msg = 'frame_i: {} data is valid rowid {}'
......@@ -356,8 +365,8 @@ class BlenderRender(AbstractRender):
def cycle_samples(self):
"""get the samples for rendering with cycle
:returns: the number of samples used for the rendering
:rtype: int
: returns: the number of samples used for the rendering
: rtype: int
"""
return bpy.context.scene.cycles.samples
......@@ -366,8 +375,8 @@ class BlenderRender(AbstractRender):
def cycle_samples(self, samples=30):
"""change the samples for rendering with cycle
:param samples: the number of samples to use when rendering images
:type samples: int
: param samples: the number of samples to use when rendering images
: type samples: int
"""
if not isinstance(samples, int):
......@@ -378,11 +387,11 @@ class BlenderRender(AbstractRender):
def camera_fov(self):
"""get fov of camera
:returns: the field of view of the camera as \
: returns: the field of view of the camera as \
[[minimum latitude, maximum latitude],
[minimum longitude, maximum longitude]]
(in deg)
:rtype: np.array
: rtype: np.array
..todo Change assert to if -> raise TypeError/KeyError
......@@ -402,10 +411,10 @@ class BlenderRender(AbstractRender):
def camera_fov(self, resolution):
"""change the field of view of the panoramic camera
:param resolution: [[minimum latitude, maximum latitude],
: param resolution: [[minimum latitude, maximum latitude],
[minimum longitude, maximum longitude]]
(in deg)
:type latmin: 2x2 float array or list
: type latmin: 2x2 float array or list
"""
if not (isinstance(resolution, tuple) or
isinstance(resolution, list) or
......@@ -428,8 +437,8 @@ class BlenderRender(AbstractRender):
def camera_gaussian_width(self):
"""get width of the gaussian spatial filter
:returns: the width of the gaussian filter
:rtype: float
: returns: the width of the gaussian filter
: rtype: float
"""
return bpy.context.scene.cycles.filter_width
......@@ -438,9 +447,8 @@ class BlenderRender(AbstractRender):
def camera_gaussian_width(self, gauss_w):
"""change width of the gaussian spatial filter
:param gauss_w: width of the gaussian filter
:type gauss_w: float
: param gauss_w: width of the gaussian filter
: type gauss_w: float
"""
if not (isinstance(gauss_w, int) or isinstance(gauss_w, float)):
......@@ -449,10 +457,10 @@ class BlenderRender(AbstractRender):
@property
def camera_resolution(self):
"""return camera resolution (x,y)
"""return camera resolution(x, y)
:returns: the resolution of the camera along (x-axis,y-axis)
:rtype: (int,int)
: returns: the resolution of the camera along(x-axis, y-axis)
: rtype: (int, int)
"""
resolution_x = bpy.context.scene.render.resolution_x
......@@ -461,12 +469,12 @@ class BlenderRender(AbstractRender):
@camera_resolution.setter
def camera_resolution(self, resolution):
"""change the camera resolution (nb of pixels)
"""change the camera resolution(nb of pixels)
:param resolution_x: number of pixels along the x-axis of the camera
:type resolution_x: int
:param resolution_y: number of pixels along the y-axis of the camera
:type resolution_y: int
: param resolution_x: number of pixels along the x-axis of the camera
: type resolution_x: int
: param resolution_y: number of pixels along the y-axis of the camera
: type resolution_y: int
"""
if not (isinstance(resolution, list) or
isinstance(resolution, np.ndarray)):
......@@ -475,12 +483,25 @@ class BlenderRender(AbstractRender):
bpy.context.scene.render.resolution_y = resolution[1]
bpy.context.scene.render.resolution_percentage = 100
@property
def viewing_directions(self):
self._logger.info('get viewdir')
rx, ry = self.camera_resolution
fov = self.camera_fov
az = np.linspace(fov[1, 0], fov[1, 1], rx)
el = np.linspace(fov[0, 0], fov[0, 1], ry)
[ma, me] = np.meshgrid(az, el)
view_dir = np.zeros((ma.shape[0], ma.shape[1], 2))
view_dir[..., spherical_indeces()['elevation']] = me
view_dir[..., spherical_indeces()['azimuth']] = ma
return view_dir
@property
def image(self):
"""return the last rendered image as a numpy array
:returns: the image (height,width,nchannel)
:rtype: a double numpy array
: returns: the image(height, width, nchannel)
: rtype: a double numpy array
.. note: A temporary file will be written on the harddrive,
due to API blender limitation
......@@ -509,8 +530,8 @@ class BlenderRender(AbstractRender):
def distance(self):
"""return the last rendered distance map as a numpy array
:returns: the distance map (height, width)
:rtype: a double numpy array
: returns: the distance map(height, width)
: rtype: a double numpy array
.. note: A temporary file will be written on the harddrive,
due to API blender limitation
......@@ -543,7 +564,7 @@ class BlenderRender(AbstractRender):
def update(self, posorient):
"""assign the position and the orientation of the camera.
:param posorient: is a 1x6 vector containing:
: param posorient: is a 1x6 vector containing:
*in case of euler angeles the index should be
['location']['x']
['location']['y']
......@@ -565,7 +586,7 @@ class BlenderRender(AbstractRender):
quaternion
here the angles are euler rotation around the axis
specified by scene.camera.rotation_mode
:type posorient: pandas Series with multi-index
: type posorient: pandas Series with multi-index
"""
self._logger.info('update posorient to {}'.format(posorient))
if isinstance(posorient, pd.Series):
......@@ -613,14 +634,14 @@ class BlenderRender(AbstractRender):
def scene(self, posorient):
""" update position orientation and return a RGBD image
:param posorient: is a 1x6 vector containing:
x,y,z, angle_1, angle_2, angle_3,
: param posorient: is a 1x6 vector containing:
x, y, z, angle_1, angle_2, angle_3,
here the angles are euler rotation around the axis
specified by scene.camera.rotation_mode
:type posorient: 1x6 double array
:returns: a (height,width, channel) array here the last channel \
: type posorient: 1x6 double array
: returns: a(height, width, channel) array here the last channel \
is the distance.
:rtype: a double numpy array
: rtype: a double numpy array
"""
self._logger.info('get a scene')
self.update(posorient)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment