我测试了我的代码,但有些地方出错了。我使用Pytork加载数据和测试ICP,并使用“cuda()”向GPU添加一些变量。但是,pycharm显示了错误信息“RuntimeError:预期的对象为设备类型cuda,但在调用_th_bmm_out时为参数#0'result'获得了设备类型cpu”。我真的不知道如何解决这个问题。 这是ICP代码
import numpy as np
from sklearn.neighbors import NearestNeighbors
def best_fit_transform(A, B):
'''
Calculates the least-squares best-fit transform that maps corresponding points A to B in m spatial dimensions
Input:
A: Nxm numpy array of corresponding points
B: Nxm numpy array of corresponding points
Returns:
T: (m+1)x(m+1) homogeneous transformation matrix that maps A on to B
R: mxm rotation matrix
t: mx1 translation vector
'''
assert A.shape == B.shape #条件为true正常执行,条件为false触发异常
# get number of dimensions
m = A.shape[1]
# translate points to their centroids
#计算点云质心
centroid_A = np.mean(A, axis=0)
centroid_B = np.mean(B, axis=0)
#源、目标点云计算去质心
AA = A - centroid_A
BB = B - centroid_B
# rotation matrix
H = np.dot(AA.T, BB)
#SVD分解H协方差矩阵
U, S, Vt = np.linalg.svd(H)
R = np.dot(Vt.T, U.T)
# special reflection case
if np.linalg.det(R) < 0:
Vt[m-1,:] *= -1
R = np.dot(Vt.T, U.T)
# translation
#t:3X1
t = centroid_B.T - np.dot(R,centroid_A.T)
# homogeneous transformation
#T为m+1维的对角矩阵
T = np.identity(m+1)
T[:m, :m] = R
T[:m, m] = t
return T, R, t
def nearest_neighbor(src, dst):
'''
Find the nearest (Euclidean) neighbor in dst for each point in src
Input:
src: Nxm array of points
dst: Nxm array of points
Output:
distances: Euclidean distances of the nearest neighbor
indices: dst indices of the nearest neighbor
'''
assert src.shape == dst.shape
neigh = NearestNeighbors(n_neighbors=1)
neigh.fit(dst)
distances, indices = neigh.kneighbors(src, return_distance=True)
return distances.ravel(), indices.ravel()
def icp(A, B, init_pose=None, max_iterations=20, tolerance=0.001):
'''
The Iterative Closest Point method: finds best-fit transform that maps points A on to points B
Input:
A: Nxm numpy array of source mD points
B: Nxm numpy array of destination mD point
init_pose: (m+1)x(m+1) homogeneous transformation
max_iterations: exit algorithm after max_iterations
tolerance: convergence criteria
Output:
T: final homogeneous transformation that maps A on to B
distances: Euclidean distances (errors) of the nearest neighbor
i: number of iterations to converge
'''
assert A.shape == B.shape
# get number of dimensions
m = A.shape[1]
# make points homogeneous, copy them to maintain the originals
src = np.ones((m+1,A.shape[0]))
# print(type(src))
dst = np.ones((m+1,B.shape[0]))
# print(dst.shape)
src[:m,:] = np.copy(A.T)
dst[:m,:] = np.copy(B.T)
# apply the initial pose estimation
if init_pose is not None:
src = np.dot(init_pose, src)
prev_error = 0
for i in range(max_iterations):
# find the nearest neighbors between the current source and destination points
distances, indices = nearest_neighbor(src[:m,:].T, dst[:m,:].T)
# compute the transformation between the current source and nearest destination points
T,_,_ = best_fit_transform(src[:m,:].T, dst[:m,indices].T)
# update the current source
src = np.dot(T, src)
# check error
mean_error = np.mean(distances)
if np.abs(prev_error - mean_error) < tolerance:
break
prev_error = mean_error
# calculate final transformation
T,_,_ = best_fit_transform(A, src[:m,:].T)
return T, distances, i
这是testICP代码
import numpy as np
import time
from ICP import icp
from data import ModelNet40
from tqdm import tqdm
from util import transform_point_cloud, npmat2euler
from torch.utils.data import DataLoader
from tensorboardX import SummaryWriter
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.optim.lr_scheduler import MultiStepLR
def test_one_epoch(test_loader):
mse_ab = 0
mae_ab = 0
mse_ba = 0
mae_ba = 0
total_loss = 0
total_cycle_loss = 0
num_examples = 0
rotations_ab = []
translations_ab = []
rotations_ab_pred = []
translations_ab_pred = []
rotations_ba = []
translations_ba = []
rotations_ba_pred = []
translations_ba_pred = []
eulers_ab = []
eulers_ba = []
for src, target, rotation_ab, translation_ab, rotation_ba, translation_ba, euler_ab, euler_ba in tqdm(test_loader):
src = src.cuda()
src1 = src.cpu().numpy()
src1 = np.reshape(src1,(-1,1024))
src1 = src1.T
# print(src.shape)
target = target.cuda()
target1 = target.cpu().numpy()
target1 = np.reshape(target1,(-1,1024))
target1 = target1.T
rotation_ab = rotation_ab.cuda()
translation_ab = translation_ab.cuda()
# rotation_ba = rotation_ba.cuda()
# translation_ba = translation_ba.cuda()
batch_size = 1
num_examples += batch_size
# rotation_ab_pred, translation_ab_pred, rotation_ba_pred, translation_ba_pred = net(src, target)
T, distances, iterations= icp.icp(src1, target1, tolerance=0.000001)
rotation_ab_pred = T[0:3,0:3]
rotation_ab_pred = np.reshape(rotation_ab_pred,(1,3,3))
rotation_ab_pred = torch.from_numpy(rotation_ab_pred)
rotation_ab_pred = rotation_ab_pred.cuda()
rotation_ab_pred = torch.tensor(rotation_ab_pred, dtype=torch.float32)
translation_ab_pred = T[0:3,3]
translation_ab_pred = np.reshape(translation_ab_pred,(1,3))
translation_ab_pred = torch.from_numpy(translation_ab_pred)
translation_ab_pred = translation_ab_pred.cuda()
translation_ab_pred = torch.tensor(translation_ab_pred,dtype=torch.float32)
## save rotation and translation
rotations_ab.append(rotation_ab.detach().cpu().numpy())
translations_ab.append(translation_ab.detach().cpu().numpy())
rotations_ab_pred.append(rotation_ab_pred.detach().cpu().numpy())
translations_ab_pred.append(translation_ab_pred.detach().cpu().numpy())
eulers_ab.append(euler_ab.numpy())
##
# rotations_ba.append(rotation_ba.detach().cpu().numpy())
# translations_ba.append(translation_ba.detach().cpu().numpy())
# rotations_ba_pred.append(rotation_ba_pred.detach().cpu().numpy())
# translations_ba_pred.append(translation_ba_pred.detach().cpu().numpy())
# eulers_ba.append(euler_ba.numpy())
transformed_src = transform_point_cloud(src, rotation_ab_pred, translation_ab_pred)
# transformed_src = transformed_src.cuda()
# transformed_target = transform_point_cloud(target, rotation_ba_pred, translation_ba_pred)
###########################
identity = torch.eye(3).cuda().unsqueeze(0).repeat(batch_size, 1, 1)
loss = F.mse_loss(torch.matmul(rotation_ab_pred.transpose(2, 1), rotation_ab), identity) \
+ F.mse_loss(translation_ab_pred, translation_ab)
# if args.cycle:
# rotation_loss = F.mse_loss(torch.matmul(rotation_ba_pred, rotation_ab_pred), identity.clone())
# translation_loss = torch.mean((torch.matmul(rotation_ba_pred.transpose(2, 1),
# translation_ab_pred.view(batch_size, 3, 1)).view(batch_size, 3)
# + translation_ba_pred) ** 2, dim=[0, 1])
# cycle_loss = rotation_loss + translation_loss
#
# loss = loss + cycle_loss * 0.1
total_loss += loss.item() * batch_size
# if args.cycle:
# total_cycle_loss = total_cycle_loss + cycle_loss.item() * 0.1 * batch_size
mse_ab += torch.mean((transformed_src - target) ** 2, dim=[0, 1, 2]).item() * batch_size
mae_ab += torch.mean(torch.abs(transformed_src - target), dim=[0, 1, 2]).item() * batch_size
# mse_ba += torch.mean((transformed_target - src) ** 2, dim=[0, 1, 2]).item() * batch_size
# mae_ba += torch.mean(torch.abs(transformed_target - src), dim=[0, 1, 2]).item() * batch_size
rotations_ab = np.concatenate(rotations_ab, axis=0)
translations_ab = np.concatenate(translations_ab, axis=0)
rotations_ab_pred = np.concatenate(rotations_ab_pred, axis=0)
translations_ab_pred = np.concatenate(translations_ab_pred, axis=0)
# rotations_ba = np.concatenate(rotations_ba, axis=0)
# translations_ba = np.concatenate(translations_ba, axis=0)
# rotations_ba_pred = np.concatenate(rotations_ba_pred, axis=0)
# translations_ba_pred = np.concatenate(translations_ba_pred, axis=0)
eulers_ab = np.concatenate(eulers_ab, axis=0)
# eulers_ba = np.concatenate(eulers_ba, axis=0)
return total_loss * 1.0 / num_examples, \
mse_ab * 1.0 / num_examples, mae_ab * 1.0 / num_examples, \
rotations_ab, \
translations_ab, rotations_ab_pred, translations_ab_pred, eulers_ab
def test(test_loader):
test_loss, \
test_mse_ab, test_mae_ab, test_rotations_ab, test_translations_ab, \
test_rotations_ab_pred, \
test_translations_ab_pred, \
test_eulers_ab = test_one_epoch(test_loader)
test_rmse_ab = np.sqrt(test_mse_ab)
test_rotations_ab_pred_euler = npmat2euler(test_rotations_ab_pred)
test_r_mse_ab = np.mean((test_rotations_ab_pred_euler - np.degrees(test_eulers_ab)) ** 2)
test_r_rmse_ab = np.sqrt(test_r_mse_ab)
test_r_mae_ab = np.mean(np.abs(test_rotations_ab_pred_euler - np.degrees(test_eulers_ab)))
test_t_mse_ab = np.mean((test_translations_ab - test_translations_ab_pred) ** 2)
test_t_rmse_ab = np.sqrt(test_t_mse_ab)
test_t_mae_ab = np.mean(np.abs(test_translations_ab - test_translations_ab_pred))
# test_rotations_ba_pred_euler = npmat2euler(test_rotations_ba_pred, 'xyz')
# test_r_mse_ba = np.mean((test_rotations_ba_pred_euler - np.degrees(test_eulers_ba)) ** 2)
# test_r_rmse_ba = np.sqrt(test_r_mse_ba)
# test_r_mae_ba = np.mean(np.abs(test_rotations_ba_pred_euler - np.degrees(test_eulers_ba)))
# test_t_mse_ba = np.mean((test_translations_ba - test_translations_ba_pred) ** 2)
# test_t_rmse_ba = np.sqrt(test_t_mse_ba)
# test_t_mae_ba = np.mean(np.abs(test_translations_ba - test_translations_ba_pred))
print('==FINAL TEST==')
print('A--------->B')
print('EPOCH:: %d, Loss: %f, MSE: %f, RMSE: %f, MAE: %f, rot_MSE: %f, rot_RMSE: %f, '
'rot_MAE: %f, trans_MSE: %f, trans_RMSE: %f, trans_MAE: %f'
% (-1, test_loss, test_mse_ab, test_rmse_ab, test_mae_ab,test_r_mse_ab, test_r_rmse_ab,
test_r_mae_ab, test_t_mse_ab, test_t_rmse_ab, test_t_mae_ab))
# textio.cprint('B--------->A')
# textio.cprint('EPOCH:: %d, Loss: %f, MSE: %f, RMSE: %f, MAE: %f, rot_MSE: %f, rot_RMSE: %f, '
# 'rot_MAE: %f, trans_MSE: %f, trans_RMSE: %f, trans_MAE: %f'
# % (-1, test_loss, test_mse_ba, test_rmse_ba, test_mae_ba, test_r_mse_ba, test_r_rmse_ba,
# test_r_mae_ba, test_t_mse_ba, test_t_rmse_ba, test_t_mae_ba))
def main():
test_loader = DataLoader(
ModelNet40(num_points=1024, partition='test', gaussian_noise=False,
unseen=False, factor=4),
batch_size=1, shuffle=False, drop_last=False)
test(test_loader)
print('FINISH')
if __name__ == '__main__':
main()
这是data.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import glob
import h5py
import numpy as np
from scipy.spatial.transform import Rotation
from torch.utils.data import Dataset
# Part of the code is referred from: https://github.com/charlesq34/pointnet
def download():
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(BASE_DIR, 'data')
if not os.path.exists(DATA_DIR):
os.mkdir(DATA_DIR)
if not os.path.exists(os.path.join(DATA_DIR, 'modelnet40_ply_hdf5_2048')):
www = 'https://shapenet.cs.stanford.edu/media/modelnet40_ply_hdf5_2048.zip'
zipfile = os.path.basename(www)
os.system('wget %s; unzip %s' % (www, zipfile))
os.system('mv %s %s' % (zipfile[:-4], DATA_DIR))
os.system('rm %s' % (zipfile))
def load_data(partition):
download()
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(BASE_DIR, 'data')
all_data = []
all_label = []
for h5_name in glob.glob(os.path.join(DATA_DIR, 'modelnet40_ply_hdf5_2048', 'ply_data_%s*.h5' % partition)):
f = h5py.File(h5_name)
data = f['data'][:].astype('float32')
label = f['label'][:].astype('int64')
f.close()
all_data.append(data)
all_label.append(label)
all_data = np.concatenate(all_data, axis=0)
all_label = np.concatenate(all_label, axis=0)
return all_data, all_label
def translate_pointcloud(pointcloud):
xyz1 = np.random.uniform(low=2. / 3., high=3. / 2., size=[3])
xyz2 = np.random.uniform(low=-0.2, high=0.2, size=[3])
translated_pointcloud = np.add(np.multiply(pointcloud, xyz1), xyz2).astype('float32')
return translated_pointcloud
def jitter_pointcloud(pointcloud, sigma=0.01, clip=0.05):
N, C = pointcloud.shape
pointcloud += np.clip(sigma * np.random.randn(N, C), -1 * clip, clip)
return pointcloud
class ModelNet40(Dataset):
def __init__(self, num_points, partition='train', gaussian_noise=False, unseen=False, factor=4):
self.data, self.label = load_data(partition)
self.num_points = num_points
self.partition = partition
self.gaussian_noise = gaussian_noise
self.unseen = unseen
self.label = self.label.squeeze()
self.factor = factor
if self.unseen:
######## simulate testing on first 20 categories while training on last 20 categories
if self.partition == 'test':
self.data = self.data[self.label>=20]
self.label = self.label[self.label>=20]
elif self.partition == 'train':
self.data = self.data[self.label<20]
self.label = self.label[self.label<20]
def __getitem__(self, item):
pointcloud = self.data[item][:self.num_points]
if self.gaussian_noise:
pointcloud = jitter_pointcloud(pointcloud)
if self.partition != 'train':
np.random.seed(item)
anglex = np.random.uniform() * np.pi / self.factor
angley = np.random.uniform() * np.pi / self.factor
anglez = np.random.uniform() * np.pi / self.factor
cosx = np.cos(anglex)
cosy = np.cos(angley)
cosz = np.cos(anglez)
sinx = np.sin(anglex)
siny = np.sin(angley)
sinz = np.sin(anglez)
Rx = np.array([[1, 0, 0],
[0, cosx, -sinx],
[0, sinx, cosx]])
Ry = np.array([[cosy, 0, siny],
[0, 1, 0],
[-siny, 0, cosy]])
Rz = np.array([[cosz, -sinz, 0],
[sinz, cosz, 0],
[0, 0, 1]])
R_ab = Rx.dot(Ry).dot(Rz)
R_ba = R_ab.T
translation_ab = np.array([np.random.uniform(-0.5, 0.5), np.random.uniform(-0.5, 0.5),
np.random.uniform(-0.5, 0.5)])
translation_ba = -R_ba.dot(translation_ab)
pointcloud1 = pointcloud.T
rotation_ab = Rotation.from_euler('zyx', [anglez, angley, anglex])
pointcloud2 = rotation_ab.apply(pointcloud1.T).T + np.expand_dims(translation_ab, axis=1)
euler_ab = np.asarray([anglez, angley, anglex])
euler_ba = -euler_ab[::-1]
pointcloud1 = np.random.permutation(pointcloud1.T).T
pointcloud2 = np.random.permutation(pointcloud2.T).T
return pointcloud1.astype('float32'), pointcloud2.astype('float32'), R_ab.astype('float32'), \
translation_ab.astype('float32'), R_ba.astype('float32'), translation_ba.astype('float32'), \
euler_ab.astype('float32'), euler_ba.astype('float32')
def __len__(self):
return self.data.shape[0]
if __name__ == '__main__':
train = ModelNet40(1024)
test = ModelNet40(1024, 'test')
for data in train:
print(len(data))
break
这是util.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import argparse
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
from scipy.spatial.transform import Rotation
# Part of the code is referred from: https://github.com/ClementPinard/SfmLearner-Pytorch/blob/master/inverse_warp.py
def quat2mat(quat):
x, y, z, w = quat[:, 0], quat[:, 1], quat[:, 2], quat[:, 3]
B = quat.size(0)
w2, x2, y2, z2 = w.pow(2), x.pow(2), y.pow(2), z.pow(2)
wx, wy, wz = w*x, w*y, w*z
xy, xz, yz = x*y, x*z, y*z
rotMat = torch.stack([w2 + x2 - y2 - z2, 2*xy - 2*wz, 2*wy + 2*xz,
2*wz + 2*xy, w2 - x2 + y2 - z2, 2*yz - 2*wx,
2*xz - 2*wy, 2*wx + 2*yz, w2 - x2 - y2 + z2], dim=1).reshape(B, 3, 3)
return rotMat
def transform_point_cloud(point_cloud, rotation, translation):
if len(rotation.size()) == 2:
rot_mat = quat2mat(rotation)
else:
rot_mat = rotation
return torch.matmul(rot_mat, point_cloud) + translation.unsqueeze(2)
def npmat2euler(mats, seq='zyx'):
eulers = []
for i in range(mats.shape[0]):
r = Rotation.from_dcm(mats[i])
eulers.append(r.as_euler(seq, degrees=True))
return np.asarray(eulers, dtype='float32')
当我运行testICP.py时,错误信息如下所示
D:\Envs\DCP\Scripts\python.exe D:/pyproject/dcp-master/ICP/testICP.py
D:\pyproject\dcp-master\data.py:51: H5pyDeprecationWarning: The default file mode will change to 'r' (read-only) in h5py 3.0. To suppress this warning, pass the mode you need to h5py.File(), or set the global default h5.get_config().default_file_mode, or set the environment variable H5PY_DEFAULT_READONLY=1. Available modes are: 'r', 'r+', 'w', 'w-'/'x', 'a'. See the docs for details.
f = h5py.File(h5_name)
0%| | 0/2468 [00:00<?, ?it/s]D:/pyproject/dcp-master/ICP/testICP.py:62: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).
rotation_ab_pred = torch.tensor(rotation_ab_pred, dtype=torch.float32)
D:/pyproject/dcp-master/ICP/testICP.py:67: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).
translation_ab_pred = torch.tensor(translation_ab_pred,dtype=torch.float32)
0%| | 0/2468 [00:02<?, ?it/s]
Traceback (most recent call last):
File "D:/pyproject/dcp-master/ICP/testICP.py", line 180, in <module>
main()
File "D:/pyproject/dcp-master/ICP/testICP.py", line 175, in main
test(test_loader)
File "D:/pyproject/dcp-master/ICP/testICP.py", line 138, in test
test_eulers_ab = test_one_epoch(test_loader)
File "D:/pyproject/dcp-master/ICP/testICP.py", line 83, in test_one_epoch
transformed_src = transform_point_cloud(src, rotation_ab_pred, translation_ab_pred)
File "D:\pyproject\dcp-master\util.py", line 38, in transform_point_cloud
a = torch.matmul(rot_mat, point_cloud) + translation.unsqueeze(2)
RuntimeError: Expected object of device type cuda but got device type cpu for argument #0 'result' in call to _th_bmm_out
Process finished with exit code 1
目前没有回答
相关问题 更多 >
编程相关推荐