OpenToonzのプラグインを作るよ~ネガポジ反転

オープンソースのアニメ制作ソフト[OpenToonz](https://opentoonz.github.io/)が公開され、OpenCVを使ったエフェクトプラグインの作成がアナウンスされているので、簡単なプラグインを作ってみます。完成品のレポジトリは <https://github.com/Hi-king/opentoonz_not> です。

やること
==============

↓これを入力として

![hokusai.jpg](https://qiita-image-store.s3.amazonaws.com/0/28934/333ed3c2-9070-d5d4-fcd9-178f8ddd5b3e.jpeg)

↓こうするプラグインを作ります

![hokusai_not.0001.png](https://qiita-image-store.s3.amazonaws.com/0/28934/400f22c8-2a8e-1a6e-bfd0-335be86a1135.png)

手順
===================

以下の手順に従ってやっていきます。ただし、筆者の環境はMac OSXなので、windowsだと若干手順が異なるかと思います。

1. opentoonz_plugin_utilityを組み込む
2. プラグインのビルド設定
3. プラグインのお決まり部分のソースコードを書く
4. 実行したい処理そのものを書く
5. ビルドして実行

1. opentoonz_plugin_utilityを組み込む
==========================================

OpenCVを利用したプラグインを作るには、公式に提供されている <https://github.com/opentoonz/opentoonz_plugin_utility> を使います。使い方は <https://github.com/opentoonz/dwango_opentoonz_plugins> を参考にすればよいのですが、要するにサブモジュールにしてビルドです。

```bash
cd プラグイン開発用gitレポジトリ
git submodule add https://github.com/opentoonz/opentoonz_plugin_utility.git
git submodule update --init --recursive
```

これでplugin_utilityのディレクトリができます。この時点では、plugin_utilityはまだビルドされてないので、これを先にビルドします。

```bash
cd opentoonz_plugin_utility
cmake .
make
```
これで、OSXなら `opentoonz_plugin_utility/lib/libopentoonz_plugin_utility.a` が生成されていると思います。ここまでで、opentoonz_plugin_utilityを使う準備が終了です。

2. プラグインのビルド設定
==========================================

本来の処理以外に、プラグイン作るのに共通の操作がいろいろあります。正直面倒なので、この辺は既に作成済みの僕のレポジトリ <https://github.com/Hi-king/opentoonz_not> のコピペでもいいかと思います。

まず最初に面倒なのは、CMakeListsを作ることです。CMakeListsのポイントは2点

a. plugin_utility(とOpenCV)をリンクする

前項で作った `libopentoonz_plugin_utility.a` をリンクします。

```cmake
set(PLUGIN_UTILITY_LIB "${CMAKE_CURRENT_SOURCE_DIR}/opentoonz_plugin_utility/lib/${CMAKE_CFG_INTDIR}/libopentoonz_plugin_utility.a")
set(LIBS ${OpenCV_LIBS} ${PLUGIN_UTILITY_LIB})
add_subdirectory(opentoonz_plugin_utility)
include_directories(opentoonz_plugin_utility/include
                    opentoonz_plugin_utility/opentoonz_plugin_headers
                    "${OpenCV_INCLUDE_DIRS}")
target_link_libraries(${PLUGIN_NAME} ${LIBS})
```

b. プラグインのビルド設定

出力ファイルは.pluginという拡張子にする必要があります

```cmake
set_target_properties(${PLUGIN_NAME} PROPERTIES
	PREFIX "${PLUGIN_VENDOR}_"
	SUFFIX "_${CMAKE_SYSTEM_NAME}.plugin"
	ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
	LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
	RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
add_definitions(-DPLUGIN_NAME="${PLUGIN_NAME}")
add_definitions(-DPLUGIN_VENDOR="${PLUGIN_VENDOR}")
```

3. プラグインのお決まり部分のソースコードを書く
============================================

お決まりの部分のコードが結構有るので、基本的には既存のコードをコピーするのが楽です。筆者は <https://github.com/opentoonz/opentoonz_plugin_utility/blob/b627ffea081de27cffa9eebde4f9618ee6ffbbfe/samples/amp/src/main.cpp> をコピーしました。

書き換えるところは

a. 入力画像数

複数画像を使うときは増やしましょう。基本的にはINPUTだけでいいと思います。PORT_COUNTは入力画像数を数えるためのものなので必ず最後に置きましょう。

```cpp
  enum {
    PORT_INPUT,
    PORT_COUNT,
  };
```

b. パラメタ

パラメタとして設定したい値の名前リストを書きます

```cpp
  enum {
    PARAM_GAIN,
    PARAM_COUNT,
  };
```

いろいろやるならほかにも必要に応じて書き換えが必要ですが、この2点だけ抑えるだけで結構なことが出来ます。

4. 実行したい処理そのものを書く
===============================

自分の実装したいアルゴリズムを書きましょう。computeというメソッドをオーバーライドします。実のところ、きちんとコードを書くのはここだけです。

```cpp
  public:
  int compute(Config const& config, Params const& params, Args const& args,
              cv::Mat& retimg) override try{
    DEBUG_PRINT(__FUNCTION__);
     // 入力画像を取得
    if (args.invalid(PORT_INPUT)) {
      return 0;
    }
    cv::Mat input_img;
    input_img = args.get(PORT_INPUT); 

    // ここから処理
    std::vector<cv::Mat> planes;
    cv::split(input_img, planes);
    planes[0] = ~planes[0];
    planes[1] = ~planes[1];
    planes[2] = ~planes[2];
    cv::merge(planes, retimg);
    return 0;
  } catch (cv::Exception const& e) {
    DEBUG_PRINT(e.what());
  }
```

RGBAの4チャンネル画像を受け取って、RGBの3チャンネルを反転して返すコードです。(Aも反転すると大体透明になって悲しいことになります ><)。今回のコードでは隠蔽できたんですが、OpenToonzで扱われるMatは8bitと16bitがあるので、ビット深度に応じた関数テンプレートを利用する必要がある時があることには注意したほうがいいかもです(参考: https://github.com/opentoonz/dwango_opentoonz_plugins/blob/master/BlurChromaticAberration/src/main.cpp#L93)。

5. ビルドして実行
======================================
ひととおり出来たので、後はビルドしてプラグインディレクトリに配置です

```
cd プロジェクトルート
cmake .
make
cp hiking_not_Darwin.plugin /Applications/OpenToonz/OpenToonz_1.0_stuff/plugins
```

あとはOpenToonzを再起動して、変換したい画像を読み込み、`Windows->Schematic`を開く。エフェクトの適用なので、Fx Schematicの画面にして、

![スクリーンショット 2016-03-30 22.45.57.png](https://qiita-image-store.s3.amazonaws.com/0/28934/f5f5e9b6-dfa1-fa76-58a1-470db27094da.png)

↑プラグインを追加

![スクリーンショット 2016-03-30 22.45.27.png](https://qiita-image-store.s3.amazonaws.com/0/28934/e1b4a7e1-2f78-d4ab-1e06-09d3d30d2f61.png)

↑プレビュー

## ╭( ･ㅂ･)و ̑̑ ｸﾞｯ !