octree-nn / ocnn-pytorch

Octree-based Sparse Convolutional Neural Networks
MIT License
150 stars 16 forks source link

Why is nnum and nnum_nempty updated identically in octree_grow_full? #21

Closed raoshashank closed 1 year ago

raoshashank commented 1 year ago

@wang-ps, Referring to the following lines in octree.py code (in function octree_grow_full):

self.nnum[depth] = num * self.batch_size
self.nnum_nempty[depth] = num * self.batch_size

I was wondering why the number of non-empty nodes is updated when the octree is grown fully at a certain depth.. The number of non-empty nodes should depend on only the points input right? As I understand it, the number of nodes (nnum) are the total number of nodes expanded/initialized at a particular depth and nnum_nempty is the number of non-empty nodes at a particular depth. If I run the following code (adds just 1 point to octree at the center of a cube at resolution 4),

oct = ocnn.octree.Octree(4,4)
pts = np.array([[0,0,0]],dtype=np.float32)
pts+=0.5
pts*=1/(2**4)
points = ocnn.octree.Points(torch.from_numpy(pts))
oct.build_octree(points)
print(oct.nnum)
print(oct.nnum_nempty)

I would expect to see only 1 non-empty node at each depth, but instead I observe the following:

tensor([   1,    8,   64,  512, 4096], dtype=torch.int32)
tensor([  1,   8,  64, 512,   1], dtype=torch.int32)

As such, I am quite confused as to what the difference between nnum and nnum_nempty is.. Similarly, I also see that the number of children at depth d is 8^d. I would expect the number of nodes at depth d to be 8^d and the number of children to be 8^(d+1). Please let me know if I'm misunderstanding something. Thanks in advance!

wang-ps commented 1 year ago

I was wondering why the number of non-empty nodes is updated when the octree is grown fully at a certain depth

The function octree_grow_full is used when predicting octree in the decoder. The code self.nnum_nempty[depth] = num * self.batch_size is just for initialization. It will be updated according the prediction.

As I understand it, the number of nodes (nnum) are the total number of nodes expanded/initialized at a particular depth and nnum_nempty is the number of non-empty nodes at a particular depth.

Yes.

I would expect to see only 1 non-empty node at each depth, but instead I observe the following:

This is because you initialize oct = ocnn.octree.Octree(4,4). The second parameter is used to force the octree to be full for depth <= 4.

raoshashank commented 1 year ago

Am I correct in saying in that an octree can have a non-empty node even if there are no points from the point cloud occupying that node or any of its children in deeper layers? Thus, 'emptiness' is merely an indication of initialization/existence of the octree node itself rather than the presence of at least one point from the point cloud in it? For example, growing the octree fully until depth 4 means there are 8^4 non-empty nodes in the 4th layer, even though I have built the octree with single point (corresponding to one voxel) as the input point cloud?

wang-ps commented 1 year ago

an octree can have a non-empty node even if there are no points from the point cloud occupying that node or any of its children in deeper layers

An non-empty node must contains at least one points OR have children in deeper layers.

growing the octree fully until depth 4 means there are 8^4 non-empty nodes in the 4th layer

If growing the octree fully until depth 4, there are 16^3 nodes in total, in which not non-empty nodes are determined by whether it contains points or has children in deeper layers.