优化 numpy 点云创建脚本
Optimize numpy point cloud creation script
我正在用 numpy 编写一个简单的脚本,它获取 640 x 480
深度图像(二维 numpy 字节数组),并在给定针孔的情况下将其转换为 num_points x 3
numpy 点数组相机型号。数学相当简单,我已经让脚本运行了——但它非常慢。显然,每帧需要 2 秒。我以前用 C++ 编写过一个类似的脚本,每帧大约 100 毫秒。我想知道我可以对 python 脚本进行哪些优化。这些都可以矢量化吗?我可以从并行化中受益吗?
def create_point_cloud(self, depth_image):
shape = depth_image.shape;
rows = shape[0];
cols = shape[1];
points = np.zeros((rows * cols, 3), np.float32);
bytes_to_units = (1.0 / 256.0);
# Linear iterator for convenience
i = 0
# For each pixel in the image...
for r in xrange(0, rows):
for c in xrange(0, cols):
# Get the depth in bytes
depth = depth_image[r, c, 0];
# If the depth is 0x0 or 0xFF, its invalid.
# By convention it should be replaced by a NaN depth.
if(depth > 0 and depth < 255):
# The true depth of the pixel in units
z = depth * bytes_to_units;
# Get the x, y, z coordinates in units of the pixel
# using the intrinsics of the camera (cx, cy, fx, fy)
points[i, 0] = (c - self.cx) / self.fx * z;
points[i, 1] = (r - self.cy) / self.fy * z;
points[i, 2] = z
else:
# Invalid points have a NaN depth
points[i, 2] = np.nan;
i = i + 1
return points
我无法检查它,因为我没有你的数据,但下面的代码应该可以完成这项工作
def create_point_cloud_vectorized(self,depth_image):
im_shape = depth_image.shape
# get the depth
d = depth_image[:,:,0]
# replace the invalid data with np.nan
depth = np.where( (d > 0) & (d < 255), d /256., np.nan)
# get x and y data in a vectorized way
row = (np.arange(im_shape[0])[:,None] - self.cx) / self.fx * depth
col = (np.arange(im_shape[1])[None,:] - self.cy) / self.fy * depth
# combine x,y,depth and bring it into the correct shape
return array((row,col,depth)).reshape(3,-1).swapaxes(0,1)
我正在用 numpy 编写一个简单的脚本,它获取 640 x 480
深度图像(二维 numpy 字节数组),并在给定针孔的情况下将其转换为 num_points x 3
numpy 点数组相机型号。数学相当简单,我已经让脚本运行了——但它非常慢。显然,每帧需要 2 秒。我以前用 C++ 编写过一个类似的脚本,每帧大约 100 毫秒。我想知道我可以对 python 脚本进行哪些优化。这些都可以矢量化吗?我可以从并行化中受益吗?
def create_point_cloud(self, depth_image):
shape = depth_image.shape;
rows = shape[0];
cols = shape[1];
points = np.zeros((rows * cols, 3), np.float32);
bytes_to_units = (1.0 / 256.0);
# Linear iterator for convenience
i = 0
# For each pixel in the image...
for r in xrange(0, rows):
for c in xrange(0, cols):
# Get the depth in bytes
depth = depth_image[r, c, 0];
# If the depth is 0x0 or 0xFF, its invalid.
# By convention it should be replaced by a NaN depth.
if(depth > 0 and depth < 255):
# The true depth of the pixel in units
z = depth * bytes_to_units;
# Get the x, y, z coordinates in units of the pixel
# using the intrinsics of the camera (cx, cy, fx, fy)
points[i, 0] = (c - self.cx) / self.fx * z;
points[i, 1] = (r - self.cy) / self.fy * z;
points[i, 2] = z
else:
# Invalid points have a NaN depth
points[i, 2] = np.nan;
i = i + 1
return points
我无法检查它,因为我没有你的数据,但下面的代码应该可以完成这项工作
def create_point_cloud_vectorized(self,depth_image):
im_shape = depth_image.shape
# get the depth
d = depth_image[:,:,0]
# replace the invalid data with np.nan
depth = np.where( (d > 0) & (d < 255), d /256., np.nan)
# get x and y data in a vectorized way
row = (np.arange(im_shape[0])[:,None] - self.cx) / self.fx * depth
col = (np.arange(im_shape[1])[None,:] - self.cy) / self.fy * depth
# combine x,y,depth and bring it into the correct shape
return array((row,col,depth)).reshape(3,-1).swapaxes(0,1)