プログラミングノート

忘れないためにプログラミングTipsをメモしていく。本当にメモ程度のこともあれば、かっちり書くこともある

oscpackを使ってOpenCVとTouchDesignerを連携させる

oscpackを使ってOSC通信を行う

現在、OpenCV3.46(x64)でPS eyeによる赤外線LEDキャプチャが作動している。
ここで得たLEDの座標をOSCプロトコルを通じてTouchDesignerやUnityなどに送りたい。
oscpackはc++で動かせるOSCライブラリだ。

oscpackのダウンロード、ファイル生成

以下のサイトよりoscパックをダウンロードできる。 http://www.rossbencina.com/code/oscpack
https://code.google.com/archive/p/oscpack/downloads
zipを解凍し Developer Command Prompt for VS 2019で解凍したディレクトリに移動してcmakeを行う。※10/29追記:PS eyeのドライバがx64に対応していないために、後日x86用ビルドを行うことになる。その際の記事についてはコチラ

cmake -G "Visual Studio 16 2019"  

完了すると TestOscpack.sln ができるのでVS2019で開きx64,Releaseとしてビルドする。(ここはOpenCVのプロジェクトに合わせる)

OpenCVプロジェクトに適用

生成されたファイルをOpenCVの プロジェクト プロパティに適用させる。
また、 oscpackは追加のライブラリとしてws2_32.lib及びwinmm.libを用いているので合わせてリンカへ登録する。プロパティ変更内容をいかに示す。
(参考:https://note.mu/prty/n/n4549edcef3e4

OpenCV プラジェクト プロパティ
全般 - VC++プロパティ - インクルードディレクトリ : ...\oscpack_1_1_0
全般 - VC++プロパティ - ライブラリディレクトリ : ...\oscpack_1_1_0\Release
全般 - リンカ - 入力 : oscpack.lib;ws2_32.lib;winmm.lib

以下に、サンプルプログラムから引用した、簡単な動作確認用プログラムを示す。
プログラム終了時にデータを送信している。TouchDesignerのOSC In CHOPのNetwork Portを7000に合わせると動作が確認できるだろう。

#include <opencv2/opencv.hpp>

#include <osc/OscOutboundPacketStream.h>
#include <ip/UdpSocket.h>


#define ADDRESS "127.0.0.1"
#define PORT 7000

#define OUTPUT_BUFFER_SIZE 1024


using namespace cv;
int main(int argh, char* argv[])
{

    cv::VideoCapture cap(0);//内蔵カメラがあるため、PS eyeのカメラは1
    
    if (!cap.isOpened())
    {
        return -1;
    }

    //PS eyeのFPSと解像度の設定
    //FPSと解像度の組み合わせの選択肢はCL-Eye TestのOptionsタブのVideo Capture Pinより確認できる
    cap.set(CAP_PROP_FPS,187.003);
    cap.set(CAP_PROP_FRAME_WIDTH, 320);
    cap.set(CAP_PROP_FRAME_HEIGHT, 240);
    
    cv::Mat frame; 
    while (cap.read(frame))
    {

        cv::imshow("PS eye", frame);
        const int key = cv::waitKey(1);
        if (key == 'q')
        {
            break;
        }
        else if (key == 's')
        {
            cv::imwrite("img.png", frame);
        }
    }


    UdpTransmitSocket transmitSocket(IpEndpointName(ADDRESS, PORT));

    char buffer[OUTPUT_BUFFER_SIZE];
    osc::OutboundPacketStream p(buffer, OUTPUT_BUFFER_SIZE);

    p << osc::BeginBundleImmediate
        << osc::BeginMessage("/test1")
        << true << 23 << (float)3.1415 << "hello" << osc::EndMessage
        << osc::BeginMessage("/test2")
        << true << 24 << (float)10.8 << "world" << osc::EndMessage
        << osc::EndBundle;

    transmitSocket.Send(p.Data(), p.Size());



    cv::destroyAllWindows();
    return 0;
}

※10/29追記:実はこの時点ではOpenCVとTDの通信は行えているが、PS eyeが動作しない。これは64bitプログラムで動作しているが、PSeyeはWin32プログラムでしか認識しない(ドライバの関係?)
Win32プログラムとしてoscpackを利用する方法については
コチラ
以上。