LoginSignup
25
27

More than 3 years have passed since last update.

TouchDesignerでOpenCVをはじめーる(Windows10、Python3.7、OpenCV4.0)

Last updated at Posted at 2020-06-19

はじめに

TouchDesignerでOpenCVやっていきます。導入からMobileNetSSDまで。

開発環境

  • Windows10(RTX2080 Max-Q、i7-8750H、RAM16GB)
  • TouchDesigner 2020.24520
  • Anaconda 2020.02
  • Python 3.7
  • OpenCV 4.0

導入

TouchDesignerからインストールします。
サインインして、Keyを作成しましょう。

開いたらこんな感じ。
image.png

OpenCVを入れる

メニューのDialog->Textport and DATsを開きます。
image.png

下記プログラムを実行して、PythonとOpenCVのバージョンと場所を確認しましょう。

python >>> import sys
python >>> sys.version
'3.7.2 (heads/3.7-Derivative:052feb9e72, Mar  7 2019, 16:29:45) [MSC v.1900 64 bit (AMD64)]'
python >>> import cv2
python >>> cv2.__version__
'4.0.0'
python >>> cv2
<module 'cv2.cv2' from 'C:\\Program Files\\Derivative\\TouchDesigner\\bin\\lib\\site-packages\\cv2\\cv2.cp37-win_amd64.pyd'>

同じ環境をanacondaで作成しましょう。opencv-contribも入れます。

conda create -n td python=3.7
conda activate td
pip install opencv-python
pip install opencv-contrib-python

anaconda promptを開いて、pythonインタプリタを開き、OpenCVの場所を確認します。

(td) C:\Users\good_\Documents\PythonProjects>python
Python 3.7.7 (default, May  6 2020, 11:45:54) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'cv2' is not defined
>>> import cv2
>>> cv2
<module 'cv2.cv2' from 'C:\\Users\\gachimoto\\anaconda3\\envs\\td\\lib\\site-packages\\cv2\\cv2.cp37-win_amd64.pyd'>

anacondaで作成したpydファイルをC:\Program Files\Derivative\TouchDesigner\bin\lib\site-packages\cv2\へ上書きします。

TouchDesignerで機械学習(ObjectDetection)動かしてみたを参考に、メニューのEdit->Preferencesを開き、Python 64-bit Module Pathにanacondaで作成した環境のsite-packagesへのパスを指定します。
image.png

C:\Users\gachimoto\anaconda3\envs\td\lib\site-packages

image.png

これで、OpenCVが使えるようになります。
Increment Filename on SaveをOffにしておくと、ファイルを保存した時に数字が付かなくなります。
(※TouchDesigner のパフォーマンスチューニング & TIPS #バージョン管理は他でやる事が多いのでバックアップは作らない

画像サイズを取得してみる

VideoDeviceIn[TOP]、Null[TOP]、Script[CHOP]を配置します。script1_callbacksを削除し、OP Execute[DAT]を配置し、opexec1のMonitor OPsにnull1を指定、Post CookをONにします。
image.png

image.png

TouchDesigner で Python を使ってみよう!(2) #外部エディタの使い方を参考に、スクリプトをVSCodeで編集するように設定しましょう。

C:\Users\gachimoto\AppData\Local\Programs\Microsoft VS Code\Code.exe

image.png

opexec1のEditからscriptを以下のように編集します。

import cv2
import numpy as np

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

    out = op('script1')
    out.clear()
    out.numSamples = 1
    w = out.appendChan('w')
    h = out.appendChan('h')
    ch = out.appendChan('ch')
    h[0], w[0] = gray.shape
    ch[0] = 1
    return

script1に画像サイズ(幅、高さ、チャンネル数)が表示されたら完了です。

DNNモジュールを用いて人検出してみる

OpenCVのDNNモジュールを用いて、MobileNetSSDで人検出した値(BoundingBoxの左上の座標(x, y)と幅と高さ(w,h))をScript[CHOP]に表示してみましょう。

image.png

MobilNet_SSD_opencvをダウンロードし、MobileNetSSD_deploy.prototxt、MobileNetSSD_deploy.caffemodelを、TouchDesignerのプロジェクトと同じフォルダに置いてください。

opexec1のスクリプトを以下のように編集してください。

import cv2
import numpy as np


def onPostCook(changeOp):
    image = changeOp.numpyArray(delayed=True)
    image = np.array(image)
    image = np.uint8(image * 255.0)
    image = np.flipud(image)
    image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)

    out = op('script1')
    out.clear()

    inWidth = 300
    inHeight = 300
    inScaleFactor = 0.007843
    meanVal = 127.5
    classNames = ('background', 'aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow',
                  'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor')
    net = cv2.dnn.readNetFromCaffe(
        "MobileNetSSD_300x300.prototxt", "MobileNetSSD_train.caffemodel")
    blob = cv2.dnn.blobFromImage(
        image, inScaleFactor, (inWidth, inHeight), meanVal, swapRB=True, crop=False)
    net.setInput(blob)
    detections = net.forward()

    cols = image.shape[1]
    rows = image.shape[0]
    persons = []
    for i in range(detections.shape[2]):
        class_id = int(detections[0, 0, i, 1])
        if classNames[class_id] == 'person':
            confidence = detections[0, 0, i, 2]
            if confidence > 0.2:
                xLeftBottom = int(detections[0, 0, i, 3] * cols)
                yLeftBottom = int(detections[0, 0, i, 4] * rows)
                xRightTop = int(detections[0, 0, i, 5] * cols)
                yRightTop = int(detections[0, 0, i, 6] * rows)
                w = float(xRightTop - xLeftBottom)
                h = float(yRightTop - yLeftBottom)
                x = float((xRightTop + xLeftBottom)/2.0)
                y = float(rows - (yRightTop + yLeftBottom)/2.0)
                persons.append([x, y, w, h])
                # cv2.rectangle(image, (xLeftBottom, yLeftBottom),
                #               (xRightTop, yRightTop), (0, 255, 0))
                # label = classNames[class_id] + ": " + str(confidence)
                # labelSize, baseLine = cv2.getTextSize(
                #     label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
                # cv2.rectangle(image, (xLeftBottom, yLeftBottom - labelSize[1]), (
                #     xLeftBottom + labelSize[0], yLeftBottom + baseLine), (255, 255, 255), cv2.FILLED)
                # cv2.putText(image, label, (xLeftBottom, yLeftBottom),
                #             cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))
                # cv2.imwrite("dnn.png", image)

    if len(persons) > 0:
        out.numSamples = len(persons)
    else:
        out.numSamples = 1

    x = out.appendChan('x')
    y = out.appendChan('y')
    w = out.appendChan('w')
    h = out.appendChan('h')

    if len(persons) > 0:
        for index, person in enumerate(persons):
            x[index] = person[0]
            y[index] = person[1]
            w[index] = person[2]
            h[index] = person[3]
    else:
        x[0] = 0.
        y[0] = 0.
        w[0] = 0.
        h[0] = 0.

    return

TouchDesignerでOpenCVを使った簡単な顔認識についてを参考にして、ごにょごにょするとrenderで人検出結果を切り取り表示することができます。

お疲れ様でした。

追記

def onPostCook(changeOp):
    image = changeOp.numpyArray(delayed=True)
    image = np.array(image)
    image = np.uint8(image * 255.0)
    image = np.flipud(image)

この画像入力の逆をやってTOPに画像をreturnしたいのですが、どうやるんでしょうか?

参考文献

25
27
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
27