mirror of
https://github.com/facebookresearch/pytorch3d.git
synced 2025-08-02 11:52:50 +08:00
fix self assign for normals est
Summary: Fix self assignment of normals when estimating normals Reviewed By: nikhilaravi Differential Revision: D21315980 fbshipit-source-id: 2aa5864c3f066e39e07343f192cc6423ce1ae771
This commit is contained in:
parent
686c8666d3
commit
e64e0d17ef
@ -382,11 +382,9 @@ class Pointclouds(object):
|
|||||||
if self._normals_padded is None:
|
if self._normals_padded is None:
|
||||||
# No normals provided so return None
|
# No normals provided so return None
|
||||||
return None
|
return None
|
||||||
self._normals_list = []
|
self._normals_list = struct_utils.padded_to_list(
|
||||||
for i in range(self._N):
|
self._normals_padded, self.num_points_per_cloud().tolist()
|
||||||
self._normals_list.append(
|
)
|
||||||
self._normals_padded[i, : self.num_points_per_cloud()[i]]
|
|
||||||
)
|
|
||||||
return self._normals_list
|
return self._normals_list
|
||||||
|
|
||||||
def features_list(self):
|
def features_list(self):
|
||||||
@ -400,11 +398,9 @@ class Pointclouds(object):
|
|||||||
if self._features_padded is None:
|
if self._features_padded is None:
|
||||||
# No features provided so return None
|
# No features provided so return None
|
||||||
return None
|
return None
|
||||||
self._features_list = []
|
self._features_list = struct_utils.padded_to_list(
|
||||||
for i in range(self._N):
|
self._features_padded, self.num_points_per_cloud().tolist()
|
||||||
self._features_list.append(
|
)
|
||||||
self._features_padded[i, : self.num_points_per_cloud()[i]]
|
|
||||||
)
|
|
||||||
return self._features_list
|
return self._features_list
|
||||||
|
|
||||||
def points_packed(self):
|
def points_packed(self):
|
||||||
@ -887,9 +883,14 @@ class Pointclouds(object):
|
|||||||
|
|
||||||
# assign to self
|
# assign to self
|
||||||
if assign_to_self:
|
if assign_to_self:
|
||||||
self._normals_list, self._normals_padded, _ = self._parse_auxiliary_input(
|
_, self._normals_padded, _ = self._parse_auxiliary_input(normals_est)
|
||||||
normals_est
|
self._normals_list, self._normals_packed = None, None
|
||||||
)
|
if self._points_list is not None:
|
||||||
|
# update self._normals_list
|
||||||
|
self.normals_list()
|
||||||
|
if self._points_packed is not None:
|
||||||
|
# update self._normals_packed
|
||||||
|
self._normals_packed = torch.cat(self._normals_list, dim=0)
|
||||||
|
|
||||||
return normals_est
|
return normals_est
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import unittest
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import torch
|
import torch
|
||||||
from common_testing import TestCaseMixin
|
from common_testing import TestCaseMixin
|
||||||
|
from pytorch3d.structures import utils as struct_utils
|
||||||
from pytorch3d.structures.pointclouds import Pointclouds
|
from pytorch3d.structures.pointclouds import Pointclouds
|
||||||
|
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ class TestPointclouds(TestCaseMixin, unittest.TestCase):
|
|||||||
lists_to_tensors: bool = False,
|
lists_to_tensors: bool = False,
|
||||||
with_normals: bool = True,
|
with_normals: bool = True,
|
||||||
with_features: bool = True,
|
with_features: bool = True,
|
||||||
|
min_points: int = 0,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Function to generate a Pointclouds object of N meshes with
|
Function to generate a Pointclouds object of N meshes with
|
||||||
@ -36,12 +38,13 @@ class TestPointclouds(TestCaseMixin, unittest.TestCase):
|
|||||||
tensors (=True) of points/normals/features.
|
tensors (=True) of points/normals/features.
|
||||||
with_normals: bool whether to include normals
|
with_normals: bool whether to include normals
|
||||||
with_features: bool whether to include features
|
with_features: bool whether to include features
|
||||||
|
min_points: Min number of points per cloud
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Pointclouds object.
|
Pointclouds object.
|
||||||
"""
|
"""
|
||||||
device = torch.device("cuda:0")
|
device = torch.device("cuda:0")
|
||||||
p = torch.randint(max_points, size=(num_clouds,))
|
p = torch.randint(low=min_points, high=max_points, size=(num_clouds,))
|
||||||
if lists_to_tensors:
|
if lists_to_tensors:
|
||||||
p.fill_(p[0])
|
p.fill_(p[0])
|
||||||
|
|
||||||
@ -893,6 +896,35 @@ class TestPointclouds(TestCaseMixin, unittest.TestCase):
|
|||||||
with self.assertRaisesRegex(ValueError, "Input box must be of shape"):
|
with self.assertRaisesRegex(ValueError, "Input box must be of shape"):
|
||||||
clouds.inside_box(invalid_box)
|
clouds.inside_box(invalid_box)
|
||||||
|
|
||||||
|
def test_estimate_normals(self):
|
||||||
|
for with_normals in (True, False):
|
||||||
|
for run_padded in (True, False):
|
||||||
|
for run_packed in (True, False):
|
||||||
|
|
||||||
|
clouds = TestPointclouds.init_cloud(
|
||||||
|
3,
|
||||||
|
100,
|
||||||
|
with_normals=with_normals,
|
||||||
|
with_features=False,
|
||||||
|
min_points=60,
|
||||||
|
)
|
||||||
|
nums = clouds.num_points_per_cloud()
|
||||||
|
if run_padded:
|
||||||
|
clouds.points_padded()
|
||||||
|
if run_packed:
|
||||||
|
clouds.points_packed()
|
||||||
|
|
||||||
|
normals_est_padded = clouds.estimate_normals(assign_to_self=True)
|
||||||
|
normals_est_list = struct_utils.padded_to_list(
|
||||||
|
normals_est_padded, nums.tolist()
|
||||||
|
)
|
||||||
|
self.assertClose(clouds.normals_padded(), normals_est_padded)
|
||||||
|
for i in range(len(clouds)):
|
||||||
|
self.assertClose(clouds.normals_list()[i], normals_est_list[i])
|
||||||
|
self.assertClose(
|
||||||
|
clouds.normals_packed(), torch.cat(normals_est_list, dim=0)
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def compute_packed_with_init(
|
def compute_packed_with_init(
|
||||||
num_clouds: int = 10, max_p: int = 100, features: int = 300
|
num_clouds: int = 10, max_p: int = 100, features: int = 300
|
||||||
|
Loading…
x
Reference in New Issue
Block a user