Skip to content

Commit

Permalink
Add fisheye cameras
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Korthals <[email protected]>
  • Loading branch information
tik0 committed May 31, 2024
1 parent 928127c commit 40fc9e8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 18 deletions.
55 changes: 38 additions & 17 deletions syclops/blender/sensors/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ class Camera(SensorInterface):

def setup_sensor(self):
self.create_camera() # Create self.objs
for obj in self.objs:
if obj.get().type == "CAMERA":
cam = obj.get()
cam = self.get_camera()
cam["name"] = self.config["name"]
if "depth_of_field" in self.config:
cam.data.dof.use_dof = True
Expand All @@ -30,9 +28,7 @@ def create_frustum_pyramid(self):
"""Create sensor's frustum as pyramid"""

# Get cam object
for obj in self.objs:
if obj.get().type == "CAMERA":
cam = obj.get()
cam = self.get_camera()

cam_matrix = cam.matrix_world.normalized()
scene = bpy.context.scene
Expand Down Expand Up @@ -131,6 +127,11 @@ def create_frustum(self):
"""Create sensor's frustum"""
if "frustum" in self.config:
if self.config["frustum"]["enabled"]:
if self.get_camera() != "PERSP":
logging.warning(
"Camera: create_frustum not supported for non-perspective cameras"
)
return
if self.config["frustum"]["type"] == "pyramid":
self.create_frustum_pyramid()
else:
Expand All @@ -150,9 +151,7 @@ def render_outputs(self):
scene.render.resolution_x = self.config["resolution"][0]
scene.render.resolution_y = self.config["resolution"][1]
# Set camera as active camera
for obj in self.objs:
if obj.get().type == "CAMERA":
cam = obj.get()
cam = self.get_camera()
scene.camera = cam

if cam.data.dof.use_dof:
Expand Down Expand Up @@ -215,7 +214,23 @@ def create_camera(self):
camera_data = bpy.data.cameras.new(name=self.config["name"])

# Initial camera settings
camera_data.lens = utility.eval_param(self.config["focal_length"])

lense_type = utility.eval_param(self.config["lense_type"])
if lense_type == "PERSPECTIVE":
camera_data.type = "PERSP"
camera_data.lens = utility.eval_param(self.config["focal_length"])
elif lense_type == "FISHEYE_EQUIDISTANT":
camera_data.type = "PANO"
camera_data.cycles.panorama_type = "FISHEYE_EQUIDISTANT"
camera_data.fisheye_fov = utility.eval_param(self.config["fisheye_fov"])
elif lense_type == "FISHEYE_EQUISOLID":
camera_data.type = "PANO"
camera_data.cycles.panorama_type = "FISHEYE_EQUISOLID"
camera_data.lens = utility.eval_param(self.config["focal_length"])
camera_data.fisheye_fov = utility.eval_param(self.config["fisheye_fov"])
else:
raise ValueError("Camera: not supported lense type \"%s\"", lense_type)

camera_data.sensor_width = utility.eval_param(self.config["sensor_width"])

camera_object = bpy.data.objects.new(self.config["name"], camera_data)
Expand Down Expand Up @@ -274,7 +289,11 @@ def get_camera_matrix(self, camera):
numpy.array: The camera matrix
"""
if camera.type != "PERSP":
raise ValueError("Non-perspective cameras not supported")
logging.warning(
"Camera: get_camera_matrix not supported for non-perspective cameras"
)
return Matrix(((1, 0, 0), (0, 1, 0), (0, 0, 1)))

scene = bpy.context.scene
f_in_mm = camera.lens
resolution_x_in_px = self.config["resolution"][0]
Expand Down Expand Up @@ -324,9 +343,7 @@ def get_camera_pose(camera):

def write_intrinsics(self):
"""Write the camera intrinsics to a file"""
for obj in self.objs:
if obj.get().type == "CAMERA":
cam = obj.get()
cam = self.get_camera()
curr_frame = bpy.context.scene.frame_current
cam_name = cam["name"]
calibration_folder = (
Expand Down Expand Up @@ -370,9 +387,7 @@ def write_intrinsics(self):

def write_extrinsics(self):
"""Write the camera extrinsics to a file"""
for obj in self.objs:
if obj.get().type == "CAMERA":
cam = obj.get()
cam = self.get_camera()

curr_frame = bpy.context.scene.frame_current
cam_name = cam["name"]
Expand Down Expand Up @@ -415,3 +430,9 @@ def write_extrinsics(self):
writer.data["expected_steps"] = utility.get_job_conf()["steps"]
writer.data["sensor"] = cam_name
writer.data["id"] = cam_name + "_extrinsics"

def get_camera(self):
for obj in self.objs:
if obj.get().type == "CAMERA":
return obj.get()
raise Exception("'self' has no object 'CAMERA'.")
8 changes: 7 additions & 1 deletion syclops/blender/sensors/schema/camera.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@ items:
type: integer
maxItems: 2
minItems: 2
lense_type:
description: Lense type (PERSPECTIVE [default],FISHEYE_EQUISOLID,FISHEYE_EQUIDISTANT)
type: string
focal_length:
description: Focal length of the camera in mm.
description: Focal length of the camera in mm. Only effects lense_type=(PERSPECTIVE,FISHEYE_EQUISOLID).
$ref: "#/definitions/number_evaluation"
sensor_width:
description: Width of the sensor in mm.
$ref: "#/definitions/number_evaluation"
fisheye_fov:
description: Horizontal angular field of view in rad. Only effects lense_type=(FISHEYE_EQUIDISTANT,FISHEYE_EQUISOLID).
type: number
exposure:
description: Exposure offset in stops.
$ref: "#/definitions/number_evaluation"
Expand Down

0 comments on commit 40fc9e8

Please sign in to comment.