Skip to content

PerspectiveCameras issue with PulsarPointsRenderer #1352

Open
@maximeraafat

Description

@maximeraafat

Hi, thank you for this amazing work!

I've been running into some issues with pulsar rendering, and would appreciate your help. I am loading some parameters from calibrated cameras into a PerspectiveCameras object, and render the scene with both the default PointsRenderer and the PulsarPointsRenderer classes. The default renderer works perfectly and the image is calibrated as expected, but I fail to do the same with pulsar, and my rendered scene is empty.

A previous issue seem to address this problem (#772), but doesn't explain how to handle the focal length and principal points in the absence of K. I've tried to convert them into a 4x4 intrinsics matrix K (and then follow the advise in #772), but this didn't resolve the issue.

In another attend, I used the pytorch3d.utils.pulsar_from_cameras_projection function as suggested in #590 and #734, but there doesn't seem to be a direct way to provide the converted parameters to an object of the PulsarPointsRenderer class. The conversion function outputs translation, rotation, focal length, sensor width, and principal point parameters in pulsar convention, but the PulsarPointsRenderer forward doesn't use a sensor width as input. Even when omitting sensor width in the forward, pulsar still doesn't render the scene from the desired view. Could you please explain how to use the mentioned camera parameters with pulsar?

Below is a code example in which I first initialise the default point and pulsar renders, then render the scene with the default renderer (no problem here), and finally experiment with different scenarios for pulsar, which all resulted in a fully black and empty render.

# modules
import torch
from pytorch3d.structures import Pointclouds
from pytorch3d.renderer import PerspectiveCameras
from pytorch3d.transforms import rotation_6d_to_matrix
from pytorch3d.utils.camera_conversions import pulsar_from_cameras_projection
from pytorch3d.renderer import (
    PointsRasterizationSettings,
    PointsRasterizer,
    PointsRenderer,
    PulsarPointsRenderer,    
    AlphaCompositor
)

# default synsin point renderer
def point_renderer(cameras, image_size, radius=0.005, points_per_pixel=50):
    raster_settings = PointsRasterizationSettings(
        image_size=image_size,
        radius=radius,
        points_per_pixel=points_per_pixel
    )

    rasterizer = PointsRasterizer(cameras=cameras, raster_settings=raster_settings)
    renderer = PointsRenderer(rasterizer=rasterizer, compositor=AlphaCompositor())

    return renderer

# pulsar renderer
def pulsar_renderer(cameras, image_size, radius=0.005, points_per_pixel=10):
    raster_settings = PointsRasterizationSettings(
        image_size=image_size,
        radius=radius,
        points_per_pixel=points_per_pixel
    )

    rasterizer = PointsRasterizer(cameras=cameras, raster_settings=raster_settings)
    renderer = PulsarPointsRenderer(rasterizer=rasterizer)

    return renderer

# given are R, T, focal_length and principal_point parameters

image_size = torch.Tensor( [[1080, 1920]] )
resolution = (540, 960) # also tried with (1080, 1920)

# perspectivce camera for default renderer
cam_default = PerspectiveCameras(focal_length=focal_length, R=R, T=T, principal_point=principal_point, in_ndc=False, image_size=image_size)

# camera conversion
pulsar_cam = pulsar_from_cameras_projection(cam_default, image_size)
pulsarT = pulsar_cam[:, :3]
pulsarR = rotation_6d_to_matrix( pulsar_cam[:, 3:9] )
pulsar_focal_length = pulsar_cam[:, 9]
pulsar_sensor_width = pulsar_cam[:, 10]
pulsar_principal_point = pulsar_cam[:, 11:]

# perspective camera attempts for pulsar renderer
cam_pulsar1 = PerspectiveCameras()
cam_pulsar2 = PerspectiveCameras(focal_length=pulsar_focal_length, R=pulsarR, T=pulsarT, principal_point=pulsar_principal_point, in_ndc=False, image_size=image_size)
cam_pulsar3 = PerspectiveCameras(focal_length=pulsar_focal_length, R=pulsarR, T=pulsarT, principal_point=pulsar_principal_point, in_ndc=True, image_size=image_size)

# xyz and rgb are given position and color tensors
pcl = Pointclouds(points=[xyz], features=[rgb])

# default rendering : no problems, image properly calibrated
default = point_renderer(cam_default, resolution, radius=0.1)
img_default = default(pcl)[0]

# pulsar renderer attempts : problems
pulsar1 = pulsar_renderer(cam_pulsar1, resolution, radius=0.1)
pulsar2 = pulsar_renderer(cam_pulsar2, resolution, radius=0.1)
pulsar3 = pulsar_renderer(cam_pulsar3, resolution, radius=0.1)

# pulsar rendering attempts with pulsar1 renderer
img_pulsar1 = pulsar1(pcl, focal_length=pulsar_focal_length, R=pulsarR, T=pulsarT, principal_point=pulsar_principal_point, gamma=(1e-5,), znear=(0.1,), zfar=(100.0,))[0]

# pulsar rendering attempts with pulsar2 renderer
img_pulsar2 = pulsar2(pcl, focal_length=pulsar_focal_length, gamma=(1e-5,), znear=(0.1,), zfar=(100.0,))[0] # if focal length is not passed, pulsar will complain about single focal length needed
img_pulsar3 = pulsar2(pcl, focal_length=pulsar_focal_length, R=pulsarR, T=pulsarT, principal_point=pulsar_principal_point, gamma=(1e-5,), znear=(0.1,), zfar=(100.0,))[0]

# pulsar rendering attempts with pulsar3 renderer
img_pulsar4 = pulsar3(pcl, focal_length=pulsar_focal_length, gamma=(1e-5,), znear=(0.1,), zfar=(100.0,))[0] # if focal length is not passed, pulsar will complain about single focal length needed
img_pulsar5 = pulsar3(pcl, focal_length=pulsar_focal_length, R=pulsarR, T=pulsarT, principal_point=pulsar_principal_point, gamma=(1e-5,), znear=(0.1,), zfar=(100.0,))[0]

Thank you in advance!

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions