-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic tutorial #113
Basic tutorial #113
Changes from all commits
67508d3
f242c7c
20d97e2
fdee856
a2424d7
d9437da
1b2d8dd
a96df9b
8a86ac3
bd211c6
41c7730
0e5ad18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,15 +5,28 @@ Compilation Options | |
|
||
This page shows advanced options to customize your Open3D build. For quick start, see :ref:`getting_started_compilation`. | ||
|
||
.. _python_binding: | ||
|
||
Python binding | ||
================= | ||
|
||
We highly recommend this option as it gives easy interface to users. Open3D tutorial is written for Python binding. | ||
|
||
We use `pybind11 <https://github.com/pybind/pybind11>`_ to build the Python binding. It tries to automatically detect the installed version of Python and link against that. When this fails, or when there are multiple versions of Python and it finds the wrong one, delete CMakeCache.txt and then invoke CMake as follows: | ||
|
||
.. code-block:: bash | ||
|
||
cmake -DPYTHON_EXECUTABLE:FILEPATH=<path-to-python-executable> ../src | ||
|
||
If you are familiar with Anaconda, settings for the compilation is | ||
|
||
.. code-block:: bash | ||
|
||
conda create --name py35 python=3.5 | ||
source activate py35 | ||
cmake -DPYTHON_EXECUTABLE:FILEPATH=<path-to-anaconda>/envs/py35/bin/python3.5 ../src | ||
|
||
This example uses Python 3.5, but you can choose 2.7 or other. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why use a new conda environment? |
||
If you do not want Python binding, turn off the compilation options ``Open3D_BUILD_PYTHON_BINDING`` and ``Open3D_BUILD_PYTHON_BINDING_TESTS``. | ||
|
||
Dependencies | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
.. _tutorial: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be separate files. Each tutorial file has its own document page. |
||
|
||
Tutorial | ||
####################### | ||
|
||
This is a quick Python tutorial to be familiar with the library. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Open3D has two interfaces: C++, and Python. This tutorial focuses on the Python interface since it is easy to use and should be regarded as the primary interface of Open3D. --Note-- |
||
|
||
|
||
.. _tutorial_basic: | ||
|
||
Basic | ||
================= | ||
|
||
|
||
Importing Open3D module | ||
------------------------------------- | ||
Let's get started Open3D by importing Python module. | ||
Once you successfully compiled Open3D with Python binding option, | ||
py3d.so should be visible under Open3D build folder. Let's import it. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. py3d.so (or py3d.pyd if you are using Windows) should be compiled under the build/lib folder. All [Python/Tutorials] files will be also copied to [build/lib]. You can call them in place and see results. Listed below:
|
||
|
||
.. code-block:: python | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a separate file. |
||
|
||
import sys | ||
sys.path.append("../..") | ||
from py3d import * | ||
|
||
This example uses ``sys.path.append()`` to refer the path where py3d.so is located. | ||
If this script runs without any failure message, you are ready to move to the next tutorial. | ||
If it fails, please go over :ref:`python_binding`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think you need to explain this. As long as you explains where these files are, it is straightforward. |
||
|
||
.. note:: To get more information for Open3D functions or classes, it is recommended to use Python built-in ``help()``. For example, ``help(draw_geometries)`` will print detailed input/output arguments of ``draw_geometries`` function. | ||
|
||
Reading and drawing 3D geometry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Separate file. |
||
------------------------------------- | ||
Reading and drawing 3D geometry is made easy. Let's see `Basic/visualize_pointcloud.py`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use more professional words. E.g. This tutorial shows how to read and draw a point cloud with Open3D. The python example is in [Basic/visualize_pointcloud.py]. |
||
|
||
.. code-block:: python | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Complete code. Including the import part. |
||
pcd = read_point_cloud("../../TestData/fragment.ply") | ||
draw_geometries([pcd]) | ||
|
||
Note that ``draw_geometries`` can visualize multiple geometries by taking a list of objects. | ||
We will see more examples of this function later. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change this to: The code is straightforward. First import the Open3D library (named py3d). Then call function The data structure of the point cloud is: More tutorials will show how to manipulate these data records. In this tutorial we just focus on the rendering task. Thus, we finally call draw_geometries functions... This functions does.... Show a figure. Explain the GUI a bit. There are actually lots of stuff to explain, e.g., you can press +- to change the point size, etc. |
||
|
||
For visualizing meshes, use ``read_triangle_mesh``. For example, | ||
|
||
.. code-block:: python | ||
|
||
mesh = read_triangle_mesh("../../TestData/knot.ply") | ||
mesh.compute_vertex_normals() | ||
draw_geometries([mesh]) | ||
|
||
Here, method ``compute_vertex_normals`` computes point normal of meshed surface. | ||
``draw_geometries`` will draw shaded geometry based on the computed normal direction. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. separate file. |
||
|
||
|
||
Manipulating and saving 3D geometry | ||
------------------------------------- | ||
|
||
This is another example, where user gives selection of geometry, and | ||
|
||
.. code-block:: python | ||
|
||
vol = read_selection_polygon_volume("../TestData/Crop/cropped.json") | ||
chair = vol.crop_point_cloud(pcd) | ||
draw_geometries([chair]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this. |
||
|
||
|
||
Read RGB Image | ||
------------------------------------- | ||
|
||
.. code-block:: python | ||
|
||
im_raw = mpimg.imread("../TestData/lena_color.jpg") | ||
im = Image(im_raw) | ||
im_g3 = filter_image(im, ImageFilterType.Gaussian3) | ||
im_g5 = filter_image(im, ImageFilterType.Gaussian5) | ||
im_g7 = filter_image(im, ImageFilterType.Gaussian7) | ||
im_gaussian = [im, im_g3, im_g5, im_g7] | ||
pyramid_levels = 4 | ||
pyramid_with_gaussian_filter = True | ||
im_pyramid = create_image_pyramid(im, pyramid_levels, | ||
pyramid_with_gaussian_filter) | ||
im_dx = filter_image(im, ImageFilterType.Sobel3dx) | ||
im_dx_pyramid = filter_image_pyramid(im_pyramid, ImageFilterType.Sobel3dx) | ||
im_dy = filter_image(im, ImageFilterType.Sobel3dy) | ||
im_dy_pyramid = filter_image_pyramid(im_pyramid, ImageFilterType.Sobel3dy) | ||
|
||
|
||
Read RGBD Image | ||
------------------------------------- | ||
Open3D provides a variety of 3D reconstruction algorithms using depth cameras. | ||
A pair of color and depth image is a input for the reconstruction pipeline. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. separate file and detailed explanation. |
||
|
||
|
||
|
||
.. _tutorial_advanced: | ||
|
||
Advanced | ||
================= | ||
|
||
Customized Visualization | ||
------------------------------------- | ||
|
||
RGBD Odometry | ||
------------------------------------- | ||
|
||
Pointcloud Registration | ||
------------------------------------- |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Advanced | ||
=================================================================== | ||
|
||
.. toctree:: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Basic | ||
=================================================================== | ||
|
||
.. toctree:: | ||
|
||
mesh | ||
pointcloud |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
.. _mesh: | ||
|
||
Reading and visualizing 3D geometry | ||
------------------------------------- | ||
|
||
Let's get started Open3D with the following example. | ||
|
||
.. code-block:: python | ||
|
||
# src/Python/Tutorial/Basic/mesh.py | ||
|
||
import sys | ||
import numpy as np | ||
sys.path.append("../..") | ||
from py3d import * | ||
|
||
if __name__ == "__main__": | ||
|
||
print("Testing mesh in py3d ...") | ||
mesh = read_triangle_mesh("../../TestData/knot.ply") | ||
draw_geometries([mesh]) | ||
mesh.compute_vertex_normals() | ||
draw_geometries([mesh]) | ||
print(mesh) | ||
print(np.asarray(mesh.vertices)) | ||
print(np.asarray(mesh.triangles)) | ||
print("") | ||
|
||
This example reads ``knot.ply`` file and visualize it. | ||
|
||
Let's review the script line by line. The first few lines import necessary Python modules. | ||
|
||
.. code-block:: python | ||
|
||
import sys | ||
import numpy as np | ||
sys.path.append("../..") | ||
from py3d import * | ||
|
||
It uses ``sys.path.append()`` to refer the path where py3d.so is located. | ||
Once you successfully compiled Open3D with Python binding option, | ||
py3d.so should be visible under Open3D build folder. | ||
If it is not, please go over :ref:`python_binding`. | ||
|
||
Let's see the first few lines in the main function. | ||
|
||
.. code-block:: python | ||
|
||
print("Testing mesh in py3d ...") | ||
mesh = read_triangle_mesh("../../TestData/knot.ply") | ||
draw_geometries([mesh]) | ||
mesh.compute_vertex_normals() | ||
|
||
Note that ``draw_geometries`` can visualize multiple geometries simultaneously by taking a list of objects. | ||
We will see more examples of this function later. | ||
|
||
.. note:: To get more information for Open3D functions or classes, it is recommended to use Python built-in ``help()``. For example, ``help(draw_geometries)`` will print detailed input/output arguments of ``draw_geometries`` function. | ||
|
||
With this script, you shall see this interactive window: | ||
|
||
.. image:: ../../_static/mesh_wo_shading.png | ||
:width: 400px | ||
|
||
You can use your mouse/trackpad to see the geometry from different view point. | ||
Wait, why this geometry looks just gray? It is because this mesh does not have surface normal. | ||
Without surface normal, ``draw_geometries`` does not draw surface shading, and that's why we see the gray color. | ||
Press :kbd:`q` to close this interactive window. | ||
|
||
OK, let's draw geometry with surface normal. It is pretty easy. Let's continue: | ||
|
||
.. code-block:: python | ||
|
||
mesh.compute_vertex_normals() | ||
draw_geometries([mesh]) | ||
|
||
Now have this! | ||
|
||
.. image:: ../../_static/mesh_w_shading.png | ||
:width: 400px | ||
|
||
You can freely access member variables of ``mesh`` such as its vertices and indices of vertices for mesh triangles. | ||
The following line | ||
|
||
.. code-block:: python | ||
|
||
print(mesh) | ||
print(np.asarray(mesh.vertices)) | ||
print(np.asarray(mesh.triangles)) | ||
|
||
will print | ||
|
||
.. code-block:: python | ||
|
||
TriangleMesh with 1440 points and 2880 triangles. | ||
[[ 4.51268387 28.68865967 -76.55680847] | ||
[ 7.63622284 35.52046967 -69.78063965] | ||
[ 6.21986008 44.22465134 -64.82303619] | ||
..., | ||
[-22.12651634 31.28466606 -87.37570953] | ||
[-13.91188431 25.4865818 -86.25827026] | ||
[ -5.27768707 23.36245346 -81.43279266]] | ||
[[ 0 12 13] | ||
[ 0 13 1] | ||
[ 1 13 14] | ||
..., | ||
[1438 11 1439] | ||
[1439 11 0] | ||
[1439 0 1428]] | ||
|
||
Here, we got some help from ``numpy`` module. ``np.asarray`` transforms Open3D member variables ``mesh.vertices`` and ``mesh.triangles`` into numpy array. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
.. _pointcloud: | ||
|
||
Reading and visualizing pointcloud | ||
------------------------------------- | ||
|
||
Let's get started Open3D with the following example. | ||
|
||
.. code-block:: python | ||
|
||
import sys | ||
import numpy as np | ||
sys.path.append("../..") | ||
from py3d import * | ||
|
||
if __name__ == "__main__": | ||
|
||
print("Testing point cloud in py3d ...") | ||
print("Load a pcd point cloud, print it, and render it") | ||
pcd = read_point_cloud("../../TestData/ICP/cloud_bin_0.pcd") | ||
print(pcd) | ||
print(np.asarray(pcd.points)) | ||
draw_geometries([pcd]) | ||
|
||
print("Load a ply point cloud, print it, and render it") | ||
pcd = read_point_cloud("../../TestData/fragment.ply") | ||
print(pcd) | ||
print(np.asarray(pcd.points)) | ||
draw_geometries([pcd]) | ||
|
||
print("Downsample the point cloud with a voxel of 0.05") | ||
downpcd = voxel_down_sample(pcd, voxel_size = 0.05) | ||
draw_geometries([downpcd]) | ||
|
||
print("Recompute the normal of the downsampled point cloud") | ||
estimate_normals(downpcd, search_param = KDTreeSearchParamHybrid( | ||
radius = 0.1, max_nn = 30)) | ||
draw_geometries([downpcd]) | ||
print("") | ||
|
||
print("We load a polygon volume and use it to crop the original point cloud") | ||
vol = read_selection_polygon_volume("../../TestData/Crop/cropped.json") | ||
chair = vol.crop_point_cloud(pcd) | ||
draw_geometries([chair]) | ||
print("") | ||
|
||
.. image:: ../../_static/pointcloud.png | ||
:width: 400px | ||
|
||
.. image:: ../../_static/pointcloud_small.png | ||
:width: 400px | ||
|
||
.. image:: ../../_static/pointcloud_downsample.png | ||
:width: 400px | ||
|
||
.. image:: ../../_static/pointcloud_downsample_normal.png | ||
:width: 400px | ||
|
||
.. image:: ../../_static/pointcloud_crop.png | ||
:width: 400px |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this line. It should not be placed here.