I am writing a simple script in numpy which takes a 640 x 480 depth image (a 2D numpy array of bytes), and converts it into a num_points x 3 numpy array of points, given a pinhole camera model. The math is fairly simple, and I've gotten the script to work -- but its extremely slow. Apparently, it takes 2 seconds for each frame. I've written a similar script in C++ before and gotten ~100ms per frame. I'm wondering what optimizations I can make to my python script. Can any of this be vectorized? Could I benefit from parallelization?
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