mirror of
https://github.com/wassname/PointCNN.git
synced 2026-09-11 11:51:29 +08:00
Significantly clean and document code base. Project approximately complete.
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||
|
||||
import pointcnn
|
||||
@@ -0,0 +1,82 @@
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
from torch.autograd import Variable
|
||||
import numpy as np
|
||||
|
||||
from PointCNN import XConv, RandPointCNN, knn_indices_func_cpu
|
||||
from PointCNN.tests.util_funcs import plot_pts_and_fts
|
||||
|
||||
np.random.seed(0)
|
||||
|
||||
class BasicTests(unittest.TestCase):
|
||||
""" Basic test cases """
|
||||
|
||||
def test_xconv_shape(self):
|
||||
self.assertTrue(True)
|
||||
|
||||
N = 4
|
||||
D = 3
|
||||
C_in = 8
|
||||
C_out = 32
|
||||
N_neighbors = 100
|
||||
|
||||
model = XConv(C_in, C_out, D, N_neighbors).cuda()
|
||||
p = Variable(torch.from_numpy(np.random.rand(N,D).astype(np.float32))).cuda()
|
||||
P = Variable(torch.from_numpy(np.random.rand(N,N_neighbors,D).astype(np.float32))).cuda()
|
||||
F = Variable(torch.from_numpy(np.random.rand(N,N_neighbors,C_in).astype(np.float32))).cuda()
|
||||
out = model(p, P, F)
|
||||
self.assertEqual(out.size(), (N, C_out))
|
||||
|
||||
def test_knn(self):
|
||||
P = np.array([[[0,0],
|
||||
[0,0.95],
|
||||
[1,0],
|
||||
[1,1]]])
|
||||
ps = P[:,[0,3],:]
|
||||
|
||||
P = Variable(torch.from_numpy(P))
|
||||
ps = Variable(torch.from_numpy(ps))
|
||||
|
||||
out = knn_indices_func_cpu(ps, P, 2).numpy()
|
||||
target = np.array([[[1,2],
|
||||
[2,1]]])
|
||||
|
||||
self.assertTrue(np.array_equal(target, out))
|
||||
|
||||
def test_pointcnn_shape(self):
|
||||
N = 1
|
||||
num_points = 1000
|
||||
dims = 2
|
||||
C_in = 4
|
||||
K = 10
|
||||
D = 1
|
||||
|
||||
layer1 = RandPointCNN(C_in, 8, dims, K, D, 1000, knn_indices_func_cpu).cuda()
|
||||
layer2 = RandPointCNN( 8, 16, dims, K, D, 500, knn_indices_func_cpu).cuda()
|
||||
layer3 = RandPointCNN( 16, 32, dims, K, D, 250, knn_indices_func_cpu).cuda()
|
||||
layer4 = RandPointCNN( 32, 64, dims, K, D, 125, knn_indices_func_cpu).cuda()
|
||||
layer5 = RandPointCNN( 64, 128, dims, K, D, 50, knn_indices_func_cpu).cuda()
|
||||
|
||||
pts = np.random.rand(N,num_points,dims).astype(np.float32)
|
||||
fts = np.random.rand(N,num_points,C_in).astype(np.float32)
|
||||
pts = Variable(torch.from_numpy(pts)).cuda()
|
||||
fts = Variable(torch.from_numpy(fts)).cuda()
|
||||
|
||||
if True:
|
||||
pts, fts = layer1((pts, fts))
|
||||
else:
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer1((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer2((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer3((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer4((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer5((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,10 +0,0 @@
|
||||
import unittest
|
||||
|
||||
class AdvancedTests(unittest.TestCase):
|
||||
""" Basic test cases """
|
||||
|
||||
def test_example(self):
|
||||
self.assertTrue(True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+38
-3
@@ -4,14 +4,16 @@ import torch
|
||||
from torch.autograd import Variable
|
||||
import numpy as np
|
||||
|
||||
from pointcnn.core import XConv, knn_indices_func
|
||||
from PointCNN import XConv, RandPointCNN, knn_indices_func_cpu
|
||||
from PointCNN.tests import plot_pts_and_fts
|
||||
|
||||
np.random.seed(0)
|
||||
|
||||
class BasicTests(unittest.TestCase):
|
||||
""" Basic test cases """
|
||||
|
||||
def test_xconv_shape(self):
|
||||
self.assertTrue(True)
|
||||
np.random.seed(0)
|
||||
|
||||
N = 4
|
||||
D = 3
|
||||
@@ -36,12 +38,45 @@ class BasicTests(unittest.TestCase):
|
||||
P = Variable(torch.from_numpy(P))
|
||||
ps = Variable(torch.from_numpy(ps))
|
||||
|
||||
out = knn_indices_func(ps, P, 2).numpy()
|
||||
out = knn_indices_func_cpu(ps, P, 2).numpy()
|
||||
target = np.array([[[1,2],
|
||||
[2,1]]])
|
||||
|
||||
self.assertTrue(np.array_equal(target, out))
|
||||
|
||||
def test_pointcnn_shape(self):
|
||||
N = 1
|
||||
num_points = 1000
|
||||
dims = 2
|
||||
C_in = 4
|
||||
K = 10
|
||||
D = 1
|
||||
|
||||
layer1 = RandPointCNN(C_in, 8, dims, K, D, 1000, knn_indices_func_cpu).cuda()
|
||||
layer2 = RandPointCNN( 8, 16, dims, K, D, 500, knn_indices_func_cpu).cuda()
|
||||
layer3 = RandPointCNN( 16, 32, dims, K, D, 250, knn_indices_func_cpu).cuda()
|
||||
layer4 = RandPointCNN( 32, 64, dims, K, D, 125, knn_indices_func_cpu).cuda()
|
||||
layer5 = RandPointCNN( 64, 128, dims, K, D, 50, knn_indices_func_cpu).cuda()
|
||||
|
||||
pts = np.random.rand(N,num_points,dims).astype(np.float32)
|
||||
fts = np.random.rand(N,num_points,C_in).astype(np.float32)
|
||||
pts = Variable(torch.from_numpy(pts)).cuda()
|
||||
fts = Variable(torch.from_numpy(fts)).cuda()
|
||||
|
||||
if True:
|
||||
pts, fts = layer1((pts, fts))
|
||||
else:
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer1((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer2((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer3((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer4((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
pts, fts = layer5((pts, fts))
|
||||
plot_pts_and_fts(pts, fts)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# External Modules
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Internal Modules
|
||||
from PointCNN.core import UFloatTensor
|
||||
|
||||
def plot_pts_and_fts(pts : UFloatTensor, # (N, x, dims)
|
||||
fts : UFloatTensor # (N, x, y)
|
||||
) -> None:
|
||||
"""
|
||||
Visualization function. Shows points and number of features, represented by
|
||||
the size of the point.
|
||||
:param pts: Point cloud such that fts[:,p_idx,:] is the feature associated
|
||||
with pts[:,p_idx,:].
|
||||
:param fts: Features such that pts[:,p_idx,:] is the feature associated
|
||||
with fts[:,p_idx,:].
|
||||
"""
|
||||
if pts.is_cuda:
|
||||
pts = pts.cpu()
|
||||
num_F = fts.size()[2]
|
||||
pts = pts[0].data.numpy()
|
||||
plt.scatter(pts[:,0], pts[:,1], s = num_F, c = "k")
|
||||
plt.show()
|
||||
plt.cla()
|
||||
|
||||
def plot_neighborhood(pts : UFloatTensor, # (N, x, dims)
|
||||
rep_pts : UFloatTensor, # (N, P, dims)
|
||||
pts_regional : UFloatTensor # (N, P, dims)
|
||||
) -> None:
|
||||
"""
|
||||
Visualization function. Shows neighborhood points around a randomly
|
||||
selected representative.
|
||||
:param pts: Point cloud.
|
||||
:param rep_pts: Representative points.
|
||||
:param pts_regional: Regional neighborhoods around representative points.
|
||||
"""
|
||||
if rep_pts.is_cuda:
|
||||
rep_pts = rep_pts.cpu()
|
||||
pts_regional = pts_regional.cpu()
|
||||
n = np.randint(0, rep_pts.shape[0])
|
||||
t = np.randint(0, rep_pts.shape[1])
|
||||
test_point = rep_pts[n,t,:].data.numpy()
|
||||
neighborhood = pts_regional[n,t,:,:].data.numpy()
|
||||
plt.scatter(pts[n][:,0], pts[n][:,1])
|
||||
plt.scatter(test_point[0], test_point[1], s = 100, c = 'green')
|
||||
plt.scatter(neighborhood[:,0], neighborhood[:,1], s = 100, c = 'red')
|
||||
plt.show()
|
||||
plt.cla()
|
||||
Reference in New Issue
Block a user