GitHub Actions上でOpen Drone Map(ODM)を動かしてみた！

# 概要
ODMを用いると、複数の画像から一枚のオルソ写真（正射影像）を作成することができます。
この処理を利用してドローンから撮影した画像を利用して一枚の地図を作成することが可能です。
しかしこの処理には相当のメモリが必要になるのでクラウドを利用して処理を行いたいと思いました。
そこで、GitHub Actionsを利用して最大256GBのメモリを駆使してODMを実行できるようにしました。

# 初めに
今回利用するGitHub ActionsのマシンのサイズはGitHub Team以上のプランでなければ使用できませんので登録しました。
最低4ドル程度から利用できるため、個人利用にも適しています。

# GitHub Actionsのマシンの作成
Organization->Setting->Actions->Runnersからマシンをあらかじめ作成しましょう。
今回作成したマシンの設定は下記のとおりです。
* name: 
    * test-larger-runner
* Runner group: 
    * Default
* Image: 
    * Ubuntu Latest (22.04)
* Size: 
    * 16-cores · 64 GB RAM · 600 GB SSD
* Public IP: 
    * Disabled

# リポジトリの作成
今回使用する画像は`ドローンバード`様が公開している[データ](https://github.com/dronebird/oam_chofu20221029disasterdrill0745koga02p3p02)をForkして使用しました。
また後続の処理のために、`photos`フォルダの名前を`images`に変更しておきます。

# GitHub Actionsのワークフローの定義
以下の要件でワークフローのほうを作成します。


1. **トリガー**: 
   - ワークフローは手動で実行される。
   
2. **実行環境**:
   - ジョブは`test-larger-runner`(作成したマシンの名前)上で実行される。
   
3. **ステップ**:
   
   a. **コードのチェックアウト**:
      - カレントリポジトリの最新のコードがチェックアウトされる。
   
   b. **Dockerを使用したODMの実行**:
      - `opendronemap/odm`イメージを使ってDockerコンテナを実行。
      - 実行時にGitHubワークスペースを`/datasets/code`にマウント。
      - ODMのプロジェクトパスとして`/datasets`を指定。

   c. **生成されたファイルのパーミッション変更**:
      - Dockerが生成したすべてのファイルとディレクトリの所有権を`runner`ユーザーに変更。
      - 生成されたすべてのファイルとディレクトリのパーミッションを全ユーザーに対して読み書き可能に設定。

   d. **アーティファクトのアップロード**:
      - ODMによって生成された特定のファイルとディレクトリをアーティファクトとしてアップロード。
      - アーティファクトの名前は`odm-output`。
      - アップロードされる内容は、指定された`.txt`、`.json`ファイルや`odm_.../`と`opensfm/`ディレクトリなど。


以上の要件をもとにChatGPTで生成したスクリプトを`.github/workflows/odm.yml`に配置します。

```
name: ODM Docker Run

on:
  # このワークフローは手動でトリガーされます。
  workflow_dispatch:

jobs:
  run-odm:
    # このジョブは特定のランナー（test-larger-runner）上で実行されます。
    runs-on: test-larger-runner
    
    steps:
    # リポジトリの最新のコードをチェックアウトするステップ。
    - name: Checkout code
      uses: actions/checkout@v2
      
    # ODMをDockerコンテナ内で実行するステップ。
    - name: Run ODM in Docker
      run: |
        # 下記のコマンドでDockerコンテナを実行します。
        # - GitHubのワークスペースはDockerの/datasets/codeにマウントされます。
        # - ODMは/datasets内のデータにアクセスします。
        docker run --rm -v ${{ github.workspace }}:/datasets/code opendronemap/odm --project-path /datasets
    
    # Dockerで生成されたファイルのパーミッションを修正するステップ。
    - name: Update permissions for generated files
      run: |
        # ファイルの所有者をrunnerに変更します。
        sudo chown -R runner:runner .
        # すべてのユーザーに読み書き実行の権限を与えます。
        chmod -R 777 .
    
    # ODMによって生成されたファイルをアーティファクトとしてアップロードするステップ。
    - name: Upload Artifacts
      uses: actions/upload-artifact@v2
      with:
        name: odm-output
        # 以下はアップロードするファイルおよびディレクトリのリストです。
        path: |
          ${{ github.workspace }}/benchmark.txt
          ${{ github.workspace }}/cameras.json
          ${{ github.workspace }}/images.json
          ${{ github.workspace }}/img_list.txt
          ${{ github.workspace }}/log.json
          ${{ github.workspace }}/odm_filterpoints/
          ${{ github.workspace }}/odm_georeferencing/
          ${{ github.workspace }}/odm_meshing/
          ${{ github.workspace }}/odm_orthophoto/
          ${{ github.workspace }}/odm_report/
          ${{ github.workspace }}/odm_texturing/
          ${{ github.workspace }}/odm_texturing_25d/
          ${{ github.workspace }}/opensfm/

```

# 実行結果
約5~10分程度で処理が完了し、実行結果がアーティファクトとして出力されました。
以下がその一部です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2584877/e20d3c03-41eb-0599-547f-ac534db2fcbe.png)

# 参考リンク
* [Open Drone Map](https://www.opendronemap.org/)
* [ドローンバードリポジトリ](https://github.com/dronebird)