Open3Dの使い方：読み込みと表示，点と法線の取得

pythonで点群処理できる[Open3D](http://www.open3d.org)が面白そう．でもほとんど情報がないので覚書．

#インストール

[マニュアル通り](http://www.open3d.org/docs/getting_started.html#compiling-from-source)，cmakeでビルド．

#使い方探検

plyの読み込みと，読み込んだ点群（メッシュ）の点と法線データへのアクセス．
ここではStanford bunnyのplyファイルを利用．


```python:open3d.py
import sys
sys.path.append("../..") # ビルドしたディレクトリ Open3D/build/lib/ へのパス
import numpy as np
import py3d

print("read ply points#############################")
pcd1 = py3d.read_point_cloud("bun000.ply") # メッシュなしply
print("pcd1:", pcd1)
print("has points?", pcd1.has_points())
point_array = np.asarray(pcd1.points)
print(point_array.shape, "points:\n", point_array)
print("has color?", pcd1.has_colors())
print("colors:", np.asarray(pcd1.colors))
print("has normals?", pcd1.has_normals())
py3d.draw_geometries([pcd1], window_name="pcd1 without normals", width=640, height=480)


print("estimate normal#############################")
py3d.estimate_normals(pcd1, search_param = py3d.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
print("has normals?", pcd1.has_normals())
normal_array = np.asarray(pcd1.normals)
print(normal_array.shape, "normals:\n", normal_array)
py3d.draw_geometries([pcd1], "pcd1 with normals", 640, 480)


print("read ply mesh#############################")
pcd2 = py3d.read_triangle_mesh("bun000mesh.ply") # メッシュありply
print("has triangle normals?", pcd2.has_triangle_normals())
print("triangle normals:\n", np.asarray(pcd2.triangle_normals))
print("has triangles?", pcd2.has_triangles())
print("triangles:", np.asarray(pcd2.triangles))
print("has vertices?", pcd2.has_vertices())
print("has vertex colors?", pcd2.has_vertex_colors())
print("vertex colors:", np.asarray(pcd2.vertex_colors))
print("has vertex normals?", pcd2.has_vertex_normals())
print("vertex normals:\n", np.asarray(pcd2.vertex_normals))
py3d.draw_geometries([pcd2], "pcd2 with mesh but no normals", 640, 480)

print("estimate normal#############################")
pcd2.compute_vertex_normals()
print("has triangle normals?", pcd2.has_triangle_normals())
print("triangle normals:\n", np.asarray(pcd2.triangle_normals))
print("has triangles?", pcd2.has_triangles())
print("triangles:", np.asarray(pcd2.triangles))
print("has vertices?", pcd2.has_vertices())
print("has vertex colors?", pcd2.has_vertex_colors())
print("vertex colors:", np.asarray(pcd2.vertex_colors))
print("has vertex normals?", pcd2.has_vertex_normals())
print("vertex normals:\n", np.asarray(pcd2.vertex_normals))
py3d.draw_geometries([pcd2], "pcd2 with mesh and normals", 640, 480)
```

##結果

まずは点の読み込みと表示．デフォルトでは疑似カラーで表示．

```text:結果
read ply points#############################
pcd1: PointCloud with 40256 points.
has points? True
(40256, 3) points:
 [[-0.06325    0.0359793  0.0420873]
 [-0.06275    0.0360343  0.0425949]
 [-0.0645     0.0365101  0.0404362]
 ...
 [-0.01575    0.187201  -0.0220209]
 [-0.01525    0.187218  -0.0237782]
 [-0.018      0.18794   -0.0197253]]
has color? False
colors: []
has normals? False
```
![スクリーンショット 2018-03-19 20.54.34.png](https://qiita-image-store.s3.amazonaws.com/0/44835/9305a1f2-3eb4-46e2-6314-8ac928a6d81f.png)

法線を推定するとシェーディンクされる．

```text:
estimate normal#############################
has normals? True
(40256, 3) normals:
 [[ 0.77476967  0.08028207 -0.62712579]
 [ 0.7390345   0.08114476 -0.66876269]
 [ 0.84369634 -0.03701673 -0.53554294]
 ...
 [ 0.85078342  0.27561442  0.44744192]
 [ 0.87997424  0.27744062  0.38558013]
 [ 0.76228806  0.32116905  0.56193181]]
```

![スクリーンショット 2018-03-19 20.54.44.png](https://qiita-image-store.s3.amazonaws.com/0/44835/6a983d2c-21b0-1ddc-6c5a-964d38c329be.png)


メッシュを読み込むと，vertex normalはあっても
triangle normal（メッシュの法線）がないとレンダリングがフラットになってしまう．

```text:
read ply mesh#############################
has triangle normals? False
triangle normals:
 []
has triangles? True
triangles: [[    0     4     3]
 [    5     4     0]
 [    0     1     5]
 ...
 [40254 40241 40242]
 [40248 40249 40255]
 [40255 40249 40250]]
has vertices? True
has vertex colors? False
vertex colors: []
has vertex normals? True
vertex normals:
 [[-1.69331  -1.25787   1.37105 ]
 [-1.30787  -1.20169   1.51385 ]
 [-1.53457  -0.343746  0.839465]
 ...
 [ 2.9521    0.500314  0.993934]
 [ 1.33488   0.502489  0.407219]
 [ 0.767662  0.817897  0.538318]]
```

![スクリーンショット 2018-03-19 20.55.03.png](https://qiita-image-store.s3.amazonaws.com/0/44835/61345120-80e4-d105-e9dc-d6e260ed7c23.png)

法線を計算して表示．色なしで表示される．

```text:
estimate normal#############################
has triangle normals? True
triangle normals:
 [[-0.76876577 -0.47361776  0.42975041]
 [-0.58323136 -0.51290694  0.62989496]
 [-0.58308966 -0.51300634  0.62994519]
 ...
 [ 0.90297077  0.34193215  0.26024256]
 [ 0.65027956  0.64132158  0.40723841]
 [ 0.59599493  0.66653699  0.4477929 ]]
has triangles? True
triangles: [[    0     4     3]
 [    5     4     0]
 [    0     1     5]
 ...
 [40254 40241 40242]
 [40248 40249 40255]
 [40255 40249 40250]]
has vertices? True
has vertex colors? False
vertex colors: []
has vertex normals? True
vertex normals:
 [[-0.67306678 -0.49998554  0.54497299]
 [-0.56041895 -0.5149211   0.64868087]
 [-0.86084632 -0.19283085  0.47091387]
 ...
 [ 0.9357322   0.15858547  0.31504905]
 [ 0.89992944  0.33876054  0.27453288]
 [ 0.61698985  0.657365    0.43266012]]
```

![スクリーンショット 2018-03-19 20.55.11.png](https://qiita-image-store.s3.amazonaws.com/0/44835/d4ef242d-b519-dabc-9275-1593a7fab317.png)