1.. _working_with_numpy:
2
3Working with NumPy
4-------------------------------------
5
6Data structure of Open3D is natively compatible with `NumPy <http://www.numpy.org/>`_ buffer.
7The following tutorial generates a variant of sync function using NumPy and visualizes the function using Open3D.
8
9.. code-block:: python
10
11    # src/Python/Tutorial/Basic/working_with_numpy.py
12
13    import copy
14    import numpy as np
15    from open3d import *
16
17    if __name__ == "__main__":
18
19        # generate some neat n times 3 matrix using a variant of sync function
20        x = np.linspace(-3, 3, 401)
21        mesh_x, mesh_y = np.meshgrid(x,x)
22        z = np.sinc((np.power(mesh_x,2)+np.power(mesh_y,2)))
23        xyz = np.zeros((np.size(mesh_x),3))
24        xyz[:,0] = np.reshape(mesh_x,-1)
25        xyz[:,1] = np.reshape(mesh_y,-1)
26        xyz[:,2] = np.reshape(z,-1)
27        print('xyz')
28        print(xyz)
29
30        # Pass xyz to Open3D.PointCloud and visualize
31        pcd = PointCloud()
32        pcd.points = Vector3dVector(xyz)
33        write_point_cloud("../../TestData/sync.ply", pcd)
34
35        # Load saved point cloud and transform it into NumPy array
36        pcd_load = read_point_cloud("../../TestData/sync.ply")
37        xyz_load = np.asarray(pcd_load.points)
38        print('xyz_load')
39        print(xyz_load)
40
41        # visualization
42        draw_geometries([pcd_load])
43
44The first part of the script generates a :math:`n \times 3` matrix ``xyz``.
45Each column has :math:`x, y, z` value of a function :math:`z = \frac{sin (x^2+y^2)}{(x^2+y^2)}`.
46
47.. _from_numpy_to_open3d:
48
49From NumPy to Open3D
50=====================================
51
52.. code-block:: python
53
54    # Pass xyz to Open3D.PointCloud.points and visualize
55    pcd = PointCloud()
56    pcd.points = Vector3dVector(xyz)
57    write_point_cloud("../../TestData/sync.ply", pcd)
58
59Open3D provides conversion from NumPy matrix to a vector of 3D vectors. By using ``Vector3dVector``, NumPy matrix can be directly assigned for ``open3d.PointCloud.points``.
60
61In this manner, any similar data structure such as ``open3d.PointCloud.colors`` or ``open3d.PointCloud.normals`` can be assigned or modified using NumPy. The script saves the point cloud as a ply file for the next step.
62
63
64.. _from_open3d_to_numpy:
65
66From Open3D to NumPy
67=====================================
68
69.. code-block:: python
70
71    # Load saved point cloud and transform it into NumPy array
72    pcd_load = read_point_cloud("../../TestData/sync.ply")
73    xyz_load = np.asarray(pcd_load.points)
74    print('xyz_load')
75    print(xyz_load)
76
77    # visualization
78    draw_geometries([pcd_load])
79
80As shown in this example, ``Vector3dVector`` is converted into a NumPy array using ``np.asarray``.
81
82The tutorial script prints two identical matrices
83
84.. code-block:: sh
85
86    xyz
87    [[-3.00000000e+00 -3.00000000e+00 -3.89817183e-17]
88     [-2.98500000e+00 -3.00000000e+00 -4.94631078e-03]
89     [-2.97000000e+00 -3.00000000e+00 -9.52804798e-03]
90     ...
91     [ 2.97000000e+00  3.00000000e+00 -9.52804798e-03]
92     [ 2.98500000e+00  3.00000000e+00 -4.94631078e-03]
93     [ 3.00000000e+00  3.00000000e+00 -3.89817183e-17]]
94    Writing PLY: [========================================] 100%
95    Reading PLY: [========================================] 100%
96    xyz_load
97    [[-3.00000000e+00 -3.00000000e+00 -3.89817183e-17]
98     [-2.98500000e+00 -3.00000000e+00 -4.94631078e-03]
99     [-2.97000000e+00 -3.00000000e+00 -9.52804798e-03]
100     ...
101     [ 2.97000000e+00  3.00000000e+00 -9.52804798e-03]
102     [ 2.98500000e+00  3.00000000e+00 -4.94631078e-03]
103     [ 3.00000000e+00  3.00000000e+00 -3.89817183e-17]]
104
105and visualizes the function:
106
107.. image:: ../../_static/Basic/working_with_numpy/sync.png
108    :width: 400px
109