Closed robinmoon2 closed 2 months ago
Hi! You can get the rgb and point-cloud/depth-map as numpy arrays from:
rgb = frame.point_cloud().copy_data("rgb")
xyz = frame.point_cloud().copy_data("xyz")
z = frame.point_cloud().copy_data("z")
you can then save those as png with one of many tools, for example opencv.
It works well for the z and rgb files. But I tried something for the xyz file that I don't nat in .png but in .xyz and I all my coordonates are "nan nan nan". Here is my code :
` Code :
with camera.capture(settings) as frame :
data_file = f"{nom_dossier}/Frame.zdf"
rgb = frame.point_cloud().copy_data("bgra")
xyz = np.array(frame.point_cloud().copy_data("xyz"))
z = frame.point_cloud().copy_data("z")
point_cloud = f"{nom_dossier}/Frame.pcd"
frame.save(point_cloud)
frame.save(data_file)
cv2.imwrite(f"{nom_dossier}/rgb.png", rgb)
cv2.imwrite(f"{nom_dossier}/depth.png",z)
with open(f"{nom_dossier}/point_cloud.xyz", "w") as f:
for point in xyz:
f.write(f"{point[0]} {point[1]} {point[2]}\n")
`
Do you have a solution to direclty save the xyz file or do I need to take the informations from the .zdf file ?
First of all, you should know that the slice xyz[:,:,2]
is the exact same data as z
. So if one contains some NaNs, so does the other.
The reason why the xyz
data contains some NaNs is that it's a structured point cloud, meaning that it has one xyz point for each pixel of the camera [i,j]
. We cannot successfully find the xyz
values for every single pixel, because some camera pixels point at regions of your scene that is in the projector shadow. Those indices in the array still need to contain something, so we fill them with NaN.
An .xyz
file that you are trying to make is an unstructured point cloud, meaning that this is merely a linear list of points with no association with camera pixels [i,k]
. In this case you can (and should) just ignore the NaN points. So to solve your issue, I believe you should do something like:
for point in xyz:
if not np.isnan(point[0]):
f.write(f"{point[0]} {point[1]} {point[2]}\n")
i.e. merely skip the NaN points.
The solution doesn't work. I have the error : ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Sorry, I forgot that for point in xyz:
will be wrong because xyz
is a 3D array.
This should work:
xyz = frame.point_cloud().copy_data("xyz")
height = xyz.shape[0]
width = xyz.shape[1]
for row in range(height):
for col in range(width):
point = xyz[row, col, :]
if not np.isnan(point[0]):
f.write(f"{point[0]} {point[1]} {point[2]}\n")
alternatively:
xyz = frame.point_cloud().copy_data("xyz")
xyz_flat = xyz.reshape(-1, 3)
for point in xyz_flat:
if not np.isnan(point[0]):
f.write(f"{point[0]} {point[1]} {point[2]}\n")
I will test this solution but for the moment I find something that works : I open a zdf file then I use it to copy the data of xyz points like a xyz file :
frame = zivid.Frame(file)
xyz = frame.point_cloud().copy_data('xyz')
points = np.nan_to_num(xyz)
Then, I can go through each pixel of the matrix and get the tuple of the coordinates of the point. thanks for helping me ;)
I will test this solution but for the moment I find something that works : I open a zdf file then I use it to copy the data of xyz points like a xyz file :
frame = zivid.Frame(file) xyz = frame.point_cloud().copy_data('xyz') points = np.nan_to_num(xyz)
Then, I can go through each pixel of the matrix and get the tuple of the coordinates of the point. thanks for helping me ;)
That should work, but be aware that this will yield [0,0,0] points for all the missing NaN points, not actually remove them.
Hello, I'm on a script to load the settings that I want to use for the hdr and I'm doing multiple hdr to compare the point cloud later between them. But I not only want the file in .pcd, I also want the RGB and depth files wich are in png.
How can I register this different files into my folder as well as the point cloud file ? This is my code : `app = zivid.Application() camera = app.connect_camera()
`
Thanks in advance !