なるように、なる

徒然なつぶやき、備忘録です。

Keras + Python3.7

GANのために開発環境つくったので、メモ。

開発機

  • OS : windows10
  • GPU : GTX1660Ti

いれたもの

  • python3.7.6
  • tensorflow-2.2.0
  • keras-2.3.1
  • cuda10.1
  • cuDNNv7.6.5

CUDNN_STATUS_INTERNAL_ERROR が出る問題

内容

https://github.com/tensorflow/tensorflow/issues/24496

対応

以下をコードに記載する。

import tensorflow as tf

gpu_devices = tf.config.experimental.list_physical_devices('GPU')
for device in gpu_devices: tf.config.experimental.set_memory_growth(device, True)

TouchDesignerでOpenCVのDNNモジュールを使う

WHY?

すごく調子の良いNoise Glitchが手に入ったのと、SquarepusherのMVに触発されたことで、openCVオンリーでお手軽にSemanticSegmentationが出来ないかと調べ始めました。
するとEnetという手法・モデルがヒットし、試してみることにしました。
できました。

本稿では、dnnについては何も語りません(語れません)。
TouchDesignerでdnnを使う前後の部分の学びの共有になります。

サンプルはこちら↓
https://github.com/thinpedelica/touchdesigner_sample/tree/master/Segmentation

Items

  • EnetのモデルをTouchDesignerで動かす
  • DATにTOPの画像を入力する
  • DATからTOPに画像を出力する(Spout for Python)
  • 性能について

Environment

  • OS: windows10
  • CPU: core-i7 9750H
  • GPU: GTX 1660Ti
  • TouchDesigner: 2020.22080

References

EnetのモデルをTouchDesignerで動かす

Enetモデルは、TouchDesignerに同梱されているopenCVだけで動作しました。
pyimagesearchからサンプルコード+学習済みモデルをダウンロードできます (メールアドレス登録するとリンクを送ってくれます) 。

ローカルのPythonで動くことを確認出来たら、あとをText DATに貼り付けるだけでした。

※なお、pyimagesearchはライセンスが不明だったので、gitに登録したコードとモデルは、本家のものに変更しました。

動作確認が出来たら、実際に使用するかたちにします。
今回はOP Execute DATに実装しました。

初期化処理

net = cv2.dnn.readNet(os.path.join(ENET_BASE_PATH, MODEL_FILE))

Cookごとの処理

blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (WIDTH, HEIGHT), 0,
    swapRB=True, crop=False)

net.setInput(blob)
output = net.forward()

classMap = np.argmax(output[0], axis=0)
mask = COLORS[classMap]
mask = cv2.resize(mask, (image.shape[1], image.shape[0]),
    interpolation=cv2.INTER_NEAREST)

すごく短いですね。機械学習すごい。

DATにTOPの画像を入力する

過去のTouchDesignerは、DATでTOPの画像を参照することができなかったらしいですが、今はできます。
@satoruhigaさん、@komakinexさん、@v_ohjiさんの記事を参考にしました。感謝!

TOPから画像を抜く

def onPostCook(changeOp):
    frame = changeOp.numpyArray(delayed = True)

TouchDesignerの画像フォーマットをopenCVのフォーマットに変換する

f_arr = frame[:, :, 0:3]
f_arr = f_arr * 255.0
image_invert = f_arr.astype (np.uint8)
image = np.flipud(image_invert)

なお、移植元のコードではnumPyで画像のリサイズを行っていたのですが、TDSWで聞いたところ、TOPで変換(リサイズなど)したほうが速いようなので、事前にTOPで実施するようしました。

DatからTOPに画像を出力する

2020.04時点で調べた限り、DATから直接TOPに画像を出力する方法はありませんでした。
そのため、DATからSpoutで送信し、Syphon Spout In TOPで受信するという方法で、Segmentation領域の画像をTOPに渡しました。
※ただ、これみんなやりたいことだと思うので、今後いい感じの方法が追加される気がします。

調べたらSpout-for-Pythonがbuild済のpyd(dll)を提供してくれていたり、サンプルにTouchDesignerを使っていたりですごく良い感じだったのですが、私の環境ではなぜかモジュールをimportする際にエラーがでてしまいました。

諦めて、こちらを参考に自分でビルドしました。
これが思いのほか一発で出来たので、Spout-for-Pythonがコケた人は、諦めてビルドしなおしましょう!

思い出せる限りの注意点

  • ローカルのPythonのバージョンをTouchDesignerと合わせておきましょう(私は3.7.2)

  • boostのバージョンはTouchDesignerと合ってなくても大丈夫だった(私は1.72)

  • 「create user-config.jam file and add this:」というところでは、ユーザフォルダ直下に「user-config.jam」を作成する
    (C:\Users\shampagne\user-config.jam)

  • Spout for Pythonをビルドする際に指定するincludeとlibのディレクトリは、ローカルのPythonのものでOK

これで無事にSpout for Pythonをimportできるようになりました。
サンプルコードから送信に必要な処理を抜いてくると以下のようになりました。

# setup the texture so we can load the output into it
glBindTexture(GL_TEXTURE_2D, textureSendID)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
# copy output into texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, output )

# Send texture to spout...
# Its signature in C++ looks like this: bool SendTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO = 0);
if sys.version_info[1] == 5:
    spoutSender.SendTexture(textureSendID, GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0)
else:
    spoutSender.SendTexture(textureSendID.item(), GL_TEXTURE_2D, spoutSenderWidth, spoutSenderHeight, False, 0)

これで、Enetで生成したSegmentationされた領域の画像をTOPに戻すことができました。

性能について

EnetモデルによるSegmentation部分の速度は、私の環境では以下のようになりました。
ただ、これバックエンドがCPUになっているようです。。

  • 512x256 : 73ms (13FPS)
  • 1024x512 : 354ms ( 3FPS)

精度は、後者の高解像度のほうが、見た目で分かるレベルでよかったです。
-> 2020.04.27 バックエンドをCUDAにしたところ、1024x512が80msくらいになりました。

おわりに

今回も多くの先輩たちのおかげで、調べたらすべての情報があり、
わりと難なくやりたいことができました。大変ありがたいことです。

この記事も、誰かの役に立ちますように。

動画deTouch

今回は、NEORTの埋め込みタグを使ってみたいというだけで書いてます。
作成したprojectはgitに登録したので、良かったらご覧ください。

https://github.com/thinpedelica/touchdesigner_sample/tree/master/movie_effect

※入力の動画は登録していないので、動かしてみたい方はtextに記載のURLからダウンロードをお願いします

 

きっかけ

普段VJさせてもらっているDJさんから「具象的な絵も使ってみたら?」と言われて、バナナを回して以来のmovie file inを使って製作しました。

 

作ったもの

night

街の光、明るいところをバキバキさせてみようというのがスタート地点。
入力のgrid sopにnoiseでほんのちょっぴりz値つけておいて、color.rを掛けたら暗いところは0、明るいところはとがる。雑ですね。

バキバキ反応させるために、元画像に速めのnoiseを噛ませました。

 

bubble

水の動きがpaletteに入っているfeedbackEdgeと相性良さそうと思って作成。
そしてなにも頑張ることなく完了。compositの噛ませ方で味わいが変わるのもナイスです。


forest

 

displaceをfeedBackするとglitchするという、MUTEKのチュートリアルにあったテクを使ってみました。

f:id:Shampagne:20200315184819p:plain


すごく少ないオペレータですが、良い感じです。工夫すればもっと伸びそう。

 

おわりに

ばっちりNEORTの動画が埋め込まれましたね。

大満足です。ありがとうございます。

NDI on WSL(Windows Subsystem for Linux)

WSLでUSBカメラ画像を使いたかったのですが、WSLは現状デバイスアクセスできないということだったので、NDI(Network Device Interface)でWinからWSLに画像を送り込む環境を構築しました、という話。

 

ポイント

通常、NDI ReceiverはマルチキャストDNS(mDNS)でSenderを自動認識するのだが、WSLはmDNSに対応していない。そのため、NDI Discovery Serverを利用し、ReceiverとSenderを接続する。

 

環境構築

  1. WSL環境の構築:省略
  2. NDI SDKのWSLへのインストール:省略
  3. NDI SDKのWinへのインストール:省略
  4. NDI ToolsのWinへのインストール
    SDKとは別途インストールする必要がある。
      -> https://ndi.tv/tools/
  5. NDI Access Manager for LinuxのWSLへのインストール
    NDI ToolsはWin版しか提供していない。その代わりのもの。
      -> http://www.sienna-tv.com/ndi/accessmanager.html
          リクエストするとメールでzipのダウンロードアドレスが送られてくる。

接続手順

  1. NDI Access ManagerでNDI Discovery Serverを利用するように設定(Win)
    C:\Program Files\NewTek\NDI 4 Tools\Access Manager\
      Application.NdiGroupEditor.exe

    f:id:Shampagne:20200201232654j:plain

  2. NDI Access ManagerでNDI Discovery Serverを利用するように設定(WSL)
    以下のバイナリを叩く。
    /PATH_TO_INSTALL/Access Manager Ubuntu$ ./NDI\ Access\ Manager

    f:id:Shampagne:20200201233832j:plain

    ブラウザからアクセスする(事前にポート9091を開放しておく)

    f:id:Shampagne:20200201233940p:plain

  3. NDI Discovery Serverを起動する(Win)
    C:\Program Files\NewTek\NDI 4 SDK\Bin\Utilities\x64\
    NewTek NDI Discovery Service.exe
  4. 送受信アプリを起動する
    私の場合は、
    WSL: Receiver
      /PATH_TO_INSTALL/NDI SDK for Linux/examples/C++/NDIlib_Recv
    WIN: Sender
      C:\Program Files\NewTek\NDI 4 Tools\Test Patterns

    上手くいってると疎通する。

    f:id:Shampagne:20200201234816j:plain

     

NDIビギナーなので、誤りなどありましたらご指摘ください。

RealSense T265 環境構築メモ

www.youtube.com

 

SDKのインストール

 DL元:https://www.intelrealsense.com/developers#firmware

 インストール先(任意):C:\Program Files (x86)\Intel RealSense SDK 2.0

 

バイスの接続確認

Intel RealSense Viewer」で接続確認する。

 

サンプルコードを動かす

「Examples for Intel RealSense SDK 2.0」で、コードと挙動を把握する。

  1. rs-ar-basic : cordinate translation(ここのReadMeは必ず読むこと)
  2. pose : single thread
  3. pose-predict : call back
  4. trajectory

開発環境構築(VisualStudio2015)

  • additional include dir
    $(RSSDK2_DIR)include\librealsense2
  • additional lib dir
    $(RSSDK2_DIR)lib\x64
  • additional lib
    realsense2.lib
  • PATHの追加
    C:\Program Files (x86)\Intel RealSense SDK 2.0\bin\x64

取得できるデータ(ReadMeのコピペ)

  • **Translation** (in meters, relative to initial position)
  • **Velocity** (in meter/sec)
  • **Rotation** (as represented in quaternion rotation, relative to initial position)
  • **Angular velocity** (in radians/sec)
  • **Angular acceleration** (in radians/sec^2)
  • **Tracker confidence** (pose data confidence 0x0 - Failed, 0x1 - Low, 0x2 - Medium, 0x3 - High)
  • **Mapper confidence** (pose data confidence 0x0 - Failed, 0x1 - Low, 0x2 - Medium, 0x3 - High)

メモ

  • rs2::video_frame
    メンバ変数に保持しようとすると死亡した

サンプル

   https://github.com/thinpedelica/t265t

TouchDesignerの勉強方法

はじめに

TouchDesigner(TD)をはじめて2か月が経ちました。
ほんとに良い感じの絵が簡単に出るので、驚きの日々を過ごしています。
(自分はこれまでopenFrameworksを使ってきたのですが、「なぜ、あんなにコードを書ける人がTDに移ったんだろう?」というモヤモヤがあったのですが、自分で使ってみたら納得しました)

今日はこの2か月のまとめとして、自分が辿ったTDの学習方法(というかお世話になった方々)を紹介します。
いつも通り、誰かのお役に立てばいいなぁ、と。

 

おすすめ学習方法

コーディングを覚えるのに比べたら圧倒的に簡単に使えるTDですが、
それでもいきなりでは何していいか分からないと思います。自分はそうでした。
SOP?CHOP?って感じでした。

なので、自分の経験を踏まえて、おすすめの学習フローをご紹介します。

  1. TDSWの初級ワークショップに参加する
  2. 比嘉先生の資料でベンキョする
  3. 日本語のビデオチュートリアルをやる
  4. 英語のビデオチュートリアルをやる

TDSWの初級ワークショップに参加する

tdsw.peatix.com

TDのお作法、オペレータ(op)の基本的な使い方がわずか2~3時間で学べます。
予習不要。親切丁寧にバナナを回させてくれます。

 

比嘉先生の資料でベンキョする

station.backspace.tokyo

これ見れちゃっていいのでしょうか?という感がありますが、大先生の講義資料です。
テキスト&ビデオなので、自分のペースで理解していくことができます。
SOPの基礎とかGPUインスタンシングなどの基礎を、ビデオチュートリアルに臨む前に抑えておく。

 

日本語のビデオチュートリアルをやる

www.youtube.com

英語のビデオチュートリアルにトライする前に、日本語でチュートリアル慣れしておく。
Mutek2018のチュートリアルが最高。
英語分からなくてもビデオチュートリアル出来るけど、やっぱり日本語で説明聞きながらのほうが理解し易く進めやすい。

以下がおすすめ。

英語のビデオチュートリアルをやる

チュートリアルに慣れたら、英語のチュートリアルも(たぶんn)出来るようになってるはず。英語分からなくても、絶対トライしたほうが良いです。有益過ぎます。

以下、おすすめを通り越した必修科目。

DERIVATIVE公式

www.derivative.ca

bileam tschepe

www.youtube.com

Matthew Ragan

www.youtube.com

 

おわりに

チュートリアルをアップしてくださっている方々や、TDSW運営に感謝いたします。
自分も今後コミュニティに貢献できるよう、がんばります。

自分の2か月の成果物も置いておきます。

www.youtube.com

 

https://github.com/thinpedelica/TouchYoga

 

Enjoy!

TouchDesingerでヨガ

TouchDesignerでYogaの姿勢推定しました。

youtu.be

去年はopenFrameworks、一昨年はvvvvで作成したものです。
過去と比べるとだいぶ見栄えが良くなったと思います。
TDのおかげです。