すだちキャンパス

すだちキャンパス

やってみたこと、学んだことなどのメモ。

TouchDesignerでARマーカー認識した

こんにちは。TouchDesignerで少しARぽいことをしたかったのでやってみました。使用した手段はTouchDesigner + OpenCV + Aruco です。

環境構築

TouchDesignerでOpenCVを使えるようにする

こちら↓の記事の通りにしたらできました。
qiita.com
anaconda promptを用いて環境構築をしたらOKです。

さらにArucoを使えるようにする

ここが超難関でした(1日は溶かした)。最終的には、こちらに書かれていた通りにすると使えるようになりました。
まず、先程作成した環境のフォルダ(C:\Users\[username]\anaconda3\envs\td\lib\site-packages)にある「cv2」のフォルダをコピーします。そして次に、TouchDesigner下(C:\Program Files\Derivative\TouchDesigner099\bin\Lib\site-packages)にある「cv2」のフォルダを、コピーしたcv2フォルダに置き換えてしまいます。すると、Arucoが使えるようになります!
どうやら最後のコメントに書かれているように、anacondaで構築した環境の方にあるパッケージを指定している(つもり)にも関わらず、TouchDesigner側のフォルダにあるパッケージが使われていた事が原因だった様です。

動かしてみる

とりあえずこちらを参考にして、マーカーを撮影して座標を取得できるかを試してみました。
また、マーカーの画像はこちらからお借りしました。
マーカーの動画を撮影し、TOP > Movie File In を置いて読み込みます。またスクリプトを書くので、DAT > OP Execute と CHOP > Script を置きます。 そしてOP ExcuteのPost CookをONにし、Monitor OPs に先程のMovie File In オペレーターをドラッグ&ドロップします。あとはEditをクリックしてスクリプトを書くだけです。

import numpy as np
import cv2

def onPreCook(changeOp):
	return

def onPostCook(changeOp):
	image = changeOp.numpyArray(delayed=True)
	image = np.array(image)
	image = np.uint8(image * 255.0)
	image = np.flipud(image)
	image_gray = image[:, :, 0]

	aruco = cv2.aruco
	dictionary_name = aruco.DICT_6X6_250
	dictionary = aruco.getPredefinedDictionary(dictionary_name)
	corners, ids, rejectedImgPoints = aruco.detectMarkers(image_gray, dictionary)
	points = corners[0].astype(np.int32)
	point = points[0]

	out = op('script1')
	out.clear()
	out.numSamples = 1
	x = out.appendChan('x')
	y = out.appendChan('y')
	h = out.appendChan('h')
	w = out.appendChan('w')

	x[0] = point[0][0]
	y[0] = point[0][1]
	h[0] = abs(point[0][1] - point[1][1])
	w[0] = abs(point[0][0] - point[2][0])

	return

CHOP Script にマーカーの左上のx,y座標と高さ、幅が渡されるので、あとはそれに合わせてTOP > Circle などの図形を表示させてみます。すると大体合っている(つまり、マーカーを読み込めているぽい)ことが分かります。
f:id:sweetgohan:20200907222013p:plain
こんな感じです。

webカメラを使ってみる

よりARらしくするために(?)、webカメラからの入力を使用してみます。

(追記)
TouchDesignerの最新版を使用したら特に問題なくできました。バージョンが古いことによるバグだった様です。
(追記終わり)

webカメラからの入力はTOP > Video Device In でできるから簡単・・・と思っていたら超謎現象が発生しました。内蔵カメラが無いのでUSBカメラを使用したのですが、TouchDesignerに映像が映らないのです。カメラの認識はされていますしアクセス許可はしているのにも関わらず・・・ちなみに他のアプリ(Zoomなど)ではばっちり映ります。
試行錯誤したのですが、最終的にはOBSの仮想カメラを経由することでとりあえず表示させることはできました。ただ、OBSの仮想カメラの設定が少し特殊です。Buffered Frames を10にし、Target Camera をOBS-Camera 2にしてあります。こうしてTouchDesignerのVideo Device In のDeviceを「OBS-Camera」にするとようやく映るようになります。(OBS-Camera 2にすると映りません・・・どういうこと???)
f:id:sweetgohan:20200908175930j:plain
これはかなり謎現象なのでいつか解決したいと思います・・・。

カメラからの入力さえできれば、先程と同様にしてマーカー認識ができます。