Comments (8)
@AAcquier I eventually reimplemented everything in python. I didn't document it properly at the time but I hope this helps:
def compute_point_clouds(depth_ins_params, rgb_ins_params, depth_frame, rgb_frame, point_cloud_dir_name):
frame_filename, depth_frame_file_extension = os.path.splitext(os.path.basename(depth_frame))
depth_img = cv2.imread(depth_frame, cv2.IMREAD_ANYDEPTH).astype(np.float32)
depth_img = cv2.flip(depth_img, 1) # images were saved flipped
# relative_depth_frame = get_relative_depth(depth_img)
color_img = cv2.imread(rgb_frame)
color_img = cv2.flip(color_img, 1) # images were saved flipped
# # Compute point cloud from images
point_cloud = []
new_vertices = []
registered = np.zeros([424, 512, 3], dtype=np.uint8)
undistorted = np.zeros([424, 512, 3], dtype=np.float32)
for y in range(424):
for x in range(512):
mx, my = distort(x, y, depth_ins_params)
ix = int(mx + 0.5)
iy = int(my + 0.5)
point = getPointXYZ(depth_img, y, x, depth_ins_params)
if (ix >= 0 and ix < 512 and iy >= 0 and iy < 424): # check if pixel is within the image
undistorted[iy, ix] = depth_img[y, x]
z = depth_img[y, x]
if z > 0 and not np.isnan(z):
# point_cloud.append(point)
cx, cy = depth_to_color(x, y, z, depth_ins_params, rgb_ins_params)
if (cx >= 0 and cx < 1920 and cy >= 0 and cy < 1080):
registered[y, x, :] = color_img[cy, cx].flatten()
registered[y, x, :] = cv2.cvtColor(registered[y, x].reshape([1, 1, 3]),
cv2.COLOR_BGR2RGB)
point_cloud.append([(point), registered[y, x, :]])
new_vertices.append((point[0], point[1], point[2], registered[y, x, 0],
registered[y, x, 1], registered[y, x, 2]))
pc_file_name = os.path.join(point_cloud_dir_name, frame_filename + '.ply')
new_vertices = np.array(new_vertices, dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])
el = PlyElement.describe(new_vertices, 'vertex')
PlyData([el]).write(pc_file_name)
print('Saved Point cloud ' + frame_filename + '.ply to ' + point_cloud_dir_name)
def getPointXYZ(undistorted, r, c, depth_ins):
depth_val = undistorted[r, c] #/ 1000.0 # map from mm to meters
if np.isnan(depth_val) or depth_val <= 0.001:
x = 0
y = 0
z = 0
else:
x = (c + 0.5 - depth_ins['cx']) * depth_val / depth_ins['fx']
y = (r + 0.5 - depth_ins['cy']) * depth_val / depth_ins['fy']
z = depth_val
point = [x, y, z]
return point
def distort(mx, my, depth_ins):
# see http://en.wikipedia.org/wiki/Distortion_(optics) for description
# based on the C++ implementation in libfreenect2
dx = (float(mx) - depth_ins['cx']) / depth_ins['fx']
dy = (float(my) - depth_ins['cy']) / depth_ins['fy']
dx2 = np.square(dx)
dy2 = np.square(dy)
r2 = dx2 + dy2
dxdy2 = 2 * dx * dy
kr = 1 + ((depth_ins['k3'] * r2 + depth_ins['k2']) * r2 + depth_ins['k1']) * r2
x = depth_ins['fx'] * (dx * kr + depth_ins['p2'] * (r2 + 2 * dx2) + depth_ins['p1'] * dxdy2) + depth_ins['cx']
y = depth_ins['fy'] * (dy * kr + depth_ins['p1'] * (r2 + 2 * dy2) + depth_ins['p2'] * dxdy2) + depth_ins['cy']
return x, y
def depth_to_color(mx, my, dz, depth_ins, color_ins):
# based on the C++ implementation in libfreenect2, constants are hardcoded into sdk
depth_q = 0.01
color_q = 0.002199
mx = (mx - depth_ins['cx']) * depth_q
my = (my - depth_ins['cy']) * depth_q
wx = (mx * mx * mx * color_ins['mx_x3y0']) + (my * my * my * color_ins['mx_x0y3']) + \
(mx * mx * my * color_ins['mx_x2y1']) + (my * my * mx * color_ins['mx_x1y2']) + \
(mx * mx * color_ins['mx_x2y0']) + (my * my * color_ins['mx_x0y2']) + \
(mx * my * color_ins['mx_x1y1']) +(mx * color_ins['mx_x1y0']) + \
(my * color_ins['mx_x0y1']) + (color_ins['mx_x0y0'])
wy = (mx * mx * mx * color_ins['my_x3y0']) + (my * my * my * color_ins['my_x0y3']) +\
(mx * mx * my * color_ins['my_x2y1']) + (my * my * mx * color_ins['my_x1y2']) +\
(mx * mx * color_ins['my_x2y0']) + (my * my * color_ins['my_x0y2']) + (mx * my * color_ins['my_x1y1']) +\
(mx * color_ins['my_x1y0']) + (my * color_ins['my_x0y1']) + color_ins['my_x0y0']
rx = (wx / (color_ins['fx'] * color_q)) - (color_ins['shift_m'] / color_ins['shift_d'])
ry = int((wy / color_q) + color_ins['cy'])
rx = rx + (color_ins['shift_m'] / dz)
rx = int(rx * color_ins['fx'] + color_ins['cx'])
return rx, ry
from pylibfreenect2.
You probably solved this already but adding the answer for future users.
The first step in the solution would be to convert the rgb image into bytes and then read them back from the buffer correctly and reshape to get dim=2
.
So,
color_img = cv2.imread(image_file_name)
color_img = cv2cvtColor(color_img, cv2.COLOR_BGR2BGRA)
color_img = color_img.tobytes()
color_img = np.frombuffer(color_img, dtype=np.float)
color_img = color_img.reshape((1080, 1920))
color_img = color_img.astype(np.float32)
And then just create the frame
color_frame = Frame(1920, 1080, 4, FrameType.Color, color_img)
.
But there is still a problem.
When trying to use 'Registration.apply' I get an assertion error (because of rgb.take_ownership). There is no way to set it manually. For undistorting the depth it works fine.
@r9y9 , Is there a way to register the depth and rgb offline? (I want to generate an XYZRGB point cloud)
from pylibfreenect2.
Hi,
Im trying to run the code @sitzikbs proposed but for me it does not seem to work. I need to convert an rgb image (BGR in opencv) to a Frame object but the execution gets stuck in np.frombuffer. If I change the dtype to float32 it decodes an array with nan in all positions. Do you know where the problem could be?
from pylibfreenect2.
You probably solved this already but adding the answer for future users.
The first step in the solution would be to convert the rgb image into bytes and then read them back from the buffer correctly and reshape to getdim=2
.
So,
color_img = cv2.imread(image_file_name)
color_img = cv2cvtColor(color_img, cv2.COLOR_BGR2BGRA)
color_img = color_img.tobytes()
color_img = np.frombuffer(color_img, dtype=np.float)
color_img = color_img.reshape((1080, 1920))
color_img = color_img.astype(np.float32)
And then just create the frame
color_frame = Frame(1920, 1080, 4, FrameType.Color, color_img)
.But there is still a problem.
When trying to use 'Registration.apply' I get an assertion error (because of rgb.take_ownership). There is no way to set it manually. For undistorting the depth it works fine.@r9y9 , Is there a way to register the depth and rgb offline? (I want to generate an XYZRGB point cloud)
I Have the same issue with the registration of the depth map and RGB offline, did you find a solution???
from pylibfreenect2.
Hi @sitzikbs ,
Thanks for your code it is really helpful but I still got a couple of questions concerning it:
- Should the depth_frames[j] in the second line of compute_point_clouds() have been edited in simply depth_frames?
- Where do the distort (line 19), depth_to_color (l 28) functions come from?
Kind regards,
Alex
from pylibfreenect2.
- yes, you are correct. I originally passed a sequence but changed the code a bit to answer your question, but seem to have missed that. I edited the original code.
- these function I also converted to python from the c++ code, forgot to attach them as well. here is the code, Ill also put it in the original message for completeness :
def distort(mx, my, depth_ins):
# see http://en.wikipedia.org/wiki/Distortion_(optics) for description
# based on the C++ implementation in libfreenect2
dx = (float(mx) - depth_ins['cx']) / depth_ins['fx']
dy = (float(my) - depth_ins['cy']) / depth_ins['fy']
dx2 = np.square(dx)
dy2 = np.square(dy)
r2 = dx2 + dy2
dxdy2 = 2 * dx * dy
kr = 1 + ((depth_ins['k3'] * r2 + depth_ins['k2']) * r2 + depth_ins['k1']) * r2
x = depth_ins['fx'] * (dx * kr + depth_ins['p2'] * (r2 + 2 * dx2) + depth_ins['p1'] * dxdy2) + depth_ins['cx']
y = depth_ins['fy'] * (dy * kr + depth_ins['p1'] * (r2 + 2 * dy2) + depth_ins['p2'] * dxdy2) + depth_ins['cy']
return x, y
def depth_to_color(mx, my, dz, depth_ins, color_ins):
# based on the C++ implementation in libfreenect2, constants are hardcoded into sdk
depth_q = 0.01
color_q = 0.002199
mx = (mx - depth_ins['cx']) * depth_q
my = (my - depth_ins['cy']) * depth_q
wx = (mx * mx * mx * color_ins['mx_x3y0']) + (my * my * my * color_ins['mx_x0y3']) + \
(mx * mx * my * color_ins['mx_x2y1']) + (my * my * mx * color_ins['mx_x1y2']) + \
(mx * mx * color_ins['mx_x2y0']) + (my * my * color_ins['mx_x0y2']) + \
(mx * my * color_ins['mx_x1y1']) +(mx * color_ins['mx_x1y0']) + \
(my * color_ins['mx_x0y1']) + (color_ins['mx_x0y0'])
wy = (mx * mx * mx * color_ins['my_x3y0']) + (my * my * my * color_ins['my_x0y3']) +\
(mx * mx * my * color_ins['my_x2y1']) + (my * my * mx * color_ins['my_x1y2']) +\
(mx * mx * color_ins['my_x2y0']) + (my * my * color_ins['my_x0y2']) + (mx * my * color_ins['my_x1y1']) +\
(mx * color_ins['my_x1y0']) + (my * color_ins['my_x0y1']) + color_ins['my_x0y0']
rx = (wx / (color_ins['fx'] * color_q)) - (color_ins['shift_m'] / color_ins['shift_d'])
ry = int((wy / color_q) + color_ins['cy'])
rx = rx + (color_ins['shift_m'] / dz)
rx = int(rx * color_ins['fx'] + color_ins['cx'])
return rx, ry
from pylibfreenect2.
Thank you very much for that, is there a way to find the depth of rgb pixel an/or the physical distance between (ie in mm) between 2 rgb pixels?
from pylibfreenect2.
from pylibfreenect2.
Related Issues (20)
- Kinect Recording
- Creating Frame from numpy array HOT 2
- Freenect2Device setConfiguration
- Offline RGB/depth registration
- OSError: libfreenect2 library cannot be found HOT 1
- is Raspberry pi 4 support? HOT 6
- How to use cuda to process data? HOT 2
- How to set record frame rate?
- How to flip RGB and depth images ?
- Problem with pip install
- Issues running examples HOT 2
- Timeout only in Python, not in C++ HOT 2
- [Error] connecting three "kinectv2"
- Pylibfreenect2 Setup.py Can't find DLL's HOT 1
- How to align the Color and the Depth
- Running slow when saving the video
- how to get skeletons ?
- ImportError trying to install pylibfreenect2
- recent installs failing? lower your Cython verison
- Gray Images using kinect V2 and libfreenect
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pylibfreenect2.