facebookresearch/pytorch3d

Unexpected result when rendering a non-square image

bowieshi opened this issue · 1 comments

I use pytorch3d PerspectiveCameras, MeshRenderer to render a non-square image. When I set the image_size of PerspectiveCameras to be sqaure like (max(H, W), max(H, W)) but set the image_size of RasterizationSettings to be (H, W), I can get the desirable results, the rendered human shape is in the middle. However, when I set the image_size of PerspectiveCameras to be (H, W), the results become strange. The human shape goes up and right a little and seems scaling up a little. The reason why I want to set the camera image_size to be (H, W) is that I want to use cameras.unproject_points((xy_depth, world_coordinates=True)) to reproject screen points to 3D world. When the screen has (H, W) shape, it becomes convenient to directly use the rendered images's x and y coordinates to construct xy_depth.
when image_size = (max(H, W), max(H, W)), the rendered result is here, which is desirable:
sample_image
when image_size = (H, W), the rendered result is here, which is not right:
sample_image2
My full code to render is here:

            cameras = PerspectiveCameras(
                focal_length=[[1800 / 7.5]], 
                image_size=[(max(H, W), max(H, W))], 
                principal_point=[(max(H, W) / 2.0, max(H, W) / 2.0)],
                in_ndc=False,
                R=R, 
                T=t, 
                device=device
            )
            raster_settings = RasterizationSettings(
                image_size=(max(H, W), max(H, W)), 
                blur_radius=0.0, 
                faces_per_pixel=1
            )
            verts_rgb = torch.ones_like(verts)[None]  # (1, V, 3)
            textures = TexturesVertex(verts_features=verts_rgb)
            meshes = Meshes(
                verts=[verts], 
                faces=[self.faces.to(device)], 
                textures=textures
            )
            rasterizer = MeshRasterizer(
                cameras=cameras, 
                raster_settings=raster_settings
            )
            renderer = MeshRenderer(
                rasterizer=MeshRasterizer(cameras=cameras, raster_settings=raster_settings),
                shader=HardPhongShader(cameras=cameras, device=device), 
            )

            image = renderer(meshes_world=meshes, R=R, T=t)
            image = image.cpu().detach().numpy()
            print(image.shape)
            import cv2
            cv2.imwrite('sample_image.png', image[0] * 255)
            print("image saved")

PyTorch3D has particular conventions for non-Square images and you need to follow them otherwise, you will be surprised by things like this. Please take a look at the documentation starting at https://github.com/facebookresearch/pytorch3d/blob/main/docs/notes/cameras.md