Non Rigid Registration (非剛体レジストレーション)　やってみた

## Non Rigid Registration やってみる
　Non Rigid Registration は位置合わせ対象の点群全体を非剛体と見做し、各点に対して位置合わせ対象への変換を適用することで点群の位置合わせを行うというものです。

ちょっと検索すると医療分野での適用例が数多く出てくるのですが、ヘルスケア分野で扱われるMRI, CT, PETなどのデータに対しての適用が多く行われているようです。[1]

　逆にRigid Registration（剛体レジストレーション）はどういうものかというと、位置合わせしたい点群全体に対して移動や回転の変換のみを適用することで位置合わせをおこないます。例えば人間をスキャンした点群があって一方は両手を上げていて、もう一方は手を下げているデータがあった場合これらを全体に対する移動や変換のみで正しく位置合わせすることは不可能だということは容易に想像できるかと思います。
Rigid Registrationはpclで実装されているicp,ndtなどで使用することが可能で、環境中での自己位置推定などのアプリケーションでよく使用されています。

またaffine registrationという分類もあり。これは移動、回転に加えスケール、せん断による変換が可能となっています。[2]

ちなみに点群におけるregistrationとは下記のgifのような赤と黒の二つの点群の位置合わせを行うタスク（良い位置合わせができる変換を求めるタスク）のことを指します。



><img width="200" alt="animation.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/5abd6929-2903-fbdf-d7c9-c7ceae8290de.gif">


>https://pcl.readthedocs.io/projects/tutorials/en/latest/_images/animation.gif



### 調査対象
github 上で#non-rigid-registration タグで検索して出てきた３つのrepogitoryのサンプルを試してみることにしました。本当にやってみただけ、なんの知見も得られないでしょう。

[github上での検索結果](https://github.com/search?q=%23non-rigid-registration&type=Repositories)

https://github.com/kzampog/cilantro

https://github.com/neka-nat/probreg

https://github.com/ohirose/bcpd

### 実行
動作環境　ubuntu18.04
cmake version 3.21.1

#### 1 cilantro
./build/examples/non_rigid_icp examples/test_clouds/frame_1.ply examples/test_clouds/frame_2.ply 

![Screenshot from 2021-09-20 17-34-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/140da82b-6145-48aa-f2a0-c9cd6e909d93.png)


./build/examples/rigid_icp examples/test_clouds/frame_1.ply examples/test_clouds/frame_2.ply 

![Screenshot from 2021-09-20 17-34-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/8644b9fd-24dc-eff7-a997-3a43bdedf7b0.png)


！?　

ほぼrigid もnon-rigidも結果が変わらないように見えます。本当は同じデータで複数アルゴリズムを試すべきですがスルーして次に行きます。

#### 2 probreg
examples/bcpd_nonrigid.py  を実行。ビジュアライザーを眺めながら1分ほど待つと完了。緑が正解データ、青が合わせ込んだ結果のようです。赤は最初の状態でしょうか？わかりにくいですがスケールが違うのでしょうか？次に行うBCPDのサンプルに含まれているドラゴンのデータを対象にして実行してみるといつまで経っても終わらないので、やめることにしました。

![Screenshot from 2021-12-13 18-29-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/e13c417b-73ed-4730-6a5c-bbbe0f650569.png)

#### 3.bcpd
demoフォルダに含まれている　shapeTransferF.sh　を実行。
target がこれで
![Screenshot from 2021-12-13 18-41-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/8dba4c59-76e9-a5c5-50d9-d02b9f601bf5.png)

source がこれ。あっ、小さいおじさんですね。確かにスケールが明らかに違うのでnon-rigidになるはずです。
![Screenshot from 2021-12-13 18-45-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/5ec8a6ad-2564-519a-9e11-7df2bcd33e50.png)
拡大するとこんな感じ。
![Screenshot from 2021-12-13 18-49-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/634941f4-c425-49a2-8a13-c02c857371d2.png)

数秒まつと結果が出てきます、確かにnon-ridigな感じでregistrationが行われてますね。
![Screenshot from 2021-12-13 18-46-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55095/86613614-b6c5-6183-dbf6-f833bc15d36d.png)

### おわり
それぞれ使ったデータは全然違いますが、BCPDは明らかにnon-rigidな結果が得られました。しかしスクリプト中にいろんなパラメータがあって、対象によってうまくいくパラメータ探しが大変なんだろうなあと思いました。はい。以上です。

### 参考

[1, A Survey of Rigid 3D Pointcloud Registration Algorithms](https://www.researchgate.net/publication/265186421_A_Survey_of_Rigid_3D_Pointcloud_Registration_Algorithms)

[2, 点群のレジストレーションとマッピングの概要](https://jp.mathworks.com/help/vision/ug/point-cloud-registration-workflow.html)