isl-org / Open3D

Open3D: A Modern Library for 3D Data Processing
http://www.open3d.org
Other
11.46k stars 2.31k forks source link

write_point_cloud saves with different precision depening on `write_ascii` #4995

Open cmosig opened 2 years ago

cmosig commented 2 years ago

Checklist

Describe the issue

When using write_point_cloud and reading that exact file again the coordinates have been altered, specifically rounded. See the example below where the output is:

42098
7958

The code counts the number of unique x-coords before writing and after reading. This should be the same count. I attached a sample file.

1000_pos1.xyzrgb.csv

Steps to reproduce the bug

import open3d as o3d
import sys
import numpy as np
import pandas as pd

filename = sys.argv[1]

pcd = o3d.io.read_point_cloud(filename=filename, format="xyzrgb", print_progress=True)
# print number of unique x-coords
print(pd.Series(np.array(pcd.points)[:,0]).nunique())
out_filename = filename.replace("xyzrgb.csv", "rgb.pcd")
o3d.io.write_point_cloud(out_filename, pcd)

pcd_read = o3d.io.read_point_cloud(filename=out_filename)
# print number of unique x-coords
print(pd.Series(np.array(pcd_read.points)[:,0]).nunique())

Error message

There is no error message.

Expected behavior

Same number of unique x-coordinates:

42098
42098

Open3D, Python and System information

- Operating system: Ubuntu 20.04 
- Python version: Python 3.9
- Open3D version: output from python: '0.15.2'
- System architecture: x86 
- Is this a remote workstation?: no
- How did you install Open3D?: pip

Additional information

No response

cmosig commented 2 years ago

Update: There seem to be two issues at play:

(1) the coordinates are too large for them to be represented by float32 correctly which they are apparently converted to at some point. This can be resolved by translating the points closer to zero. Not sure if this can be considered a bug. A warning that rounding takes place or a hint in the documentation would be nice though.

(2) The points that are saved to the file are different depending on whether you select write_ascii=True or write_ascii=False as option. Setting this option to True is the only way I could find right now to save the points correctly.

import open3d as o3d
import sys
import numpy as np
import pandas as pd

filename = sys.argv[1]

pcd = o3d.io.read_point_cloud(filename=filename, format="xyzrgb", print_progress=True)
pcd.translate((-384826,-5825884,0))
ser = pd.Series(np.array(pcd.points)[:,0])#.astype("float64")
print(ser.count(), ser.nunique())
out_filename = filename.replace("xyzrgb.csv", "rgb.pcd")
o3d.io.write_point_cloud(out_filename, pcd, write_ascii=True)

pcd_read = o3d.io.read_point_cloud(filename=out_filename)
ser_read = pd.Series(np.array(pcd_read.points)[:,0])
print(ser_read.count(), ser_read.nunique())

Output with ascii_write=True:

42131 42098
42131 42098

Output with ascii_write=False:

42131 42098
42131 41659
mgaschenbeck commented 1 year ago

Is your example UTM coordinates by any chance? If so, I've come across the same issue LOL. Regardless, thanks for your bug report and comment.

Did you fix this further than what you reported above? This was 1.5 years ago so I understand if you can't remember.

cmosig commented 1 year ago

@mgaschenbeck yes, I think it's UTM, but that shouldn't matter. No, I did not fix it, just translated points to zero and used write_ascii=True.