質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.35%

  • C++

    2412questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1204questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • OpenCV

    617questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

  • Kinect

    64questions

    Kinect(キネクト)はマイクロソフトから発売されたジェスチャー・音声認識によって 操作ができるデバイスです。

KinectV2プログラミング HDFace(C++)の改良

受付中

回答 0

投稿 2017/12/02 21:23 ・編集 2017/12/05 13:31

  • 評価
  • クリップ 0
  • VIEW 54

hihihidesan

score 0

前提・実現したいこと

KinectV2 HDfaceで1347点の顔特徴点を表示するプログラムを以下のように組んだのですが、
特徴点が多すぎるためKinect.Face.hで定義されたHighDetailFacePointsの数十点の特徴点のみを
表示するプログラムを組みたいです。どのように改良させればよいでしょうか?

#include <iostream>
#include <sstream>
#include <vector>
#include <array>
#define _USE_MATH_DEFINES
#include <cmath>
#include <atlbase.h>

#include <Windows.h>
#include <Kinect.h>
#include <Kinect.Face.h>

#include <opencv2/opencv.hpp>

#define ERROR_CHECK( ret )                                            \
    if( FAILED( ret ) ){                                            \
        std::stringstream ss;                                        \
        ss << "failed " #ret " " << std::hex << ret << std::endl;    \
        throw std::runtime_error( ss.str().c_str() );                \
    }

class KinectApp
{
private:
    CComPtr<IKinectSensor> kinect;
    CComPtr<IColorFrameReader> colorFrameReader;
    CComPtr<IBodyFrameReader> bodyFrameReader;
    CComPtr<ICoordinateMapper> coordinateMapper;
    std::vector<BYTE> colorBuffer;
    int colorWidth;
    int colorHeight;
    unsigned int colorBytesPerPixel;
    ColorImageFormat colorFormat = ColorImageFormat::ColorImageFormat_Bgra;
    cv::Mat colorImage;

    CComPtr<IHighDefinitionFaceFrameReader> hdFaceFrameReader;
    CComPtr<IFaceModelBuilder> faceModelBuilder;
    CComPtr<IFaceAlignment> faceAlignment;
    CComPtr<IFaceModel> faceModel;
    std::array<float, FaceShapeDeformations::FaceShapeDeformations_Count> shapeUnits;
    UINT32 vertexCount;
    UINT64 trackingId;
    int trackingCount;
    bool produced;

    std::array<cv::Scalar, BODY_COUNT> colors;
    int font = cv::FONT_HERSHEY_SIMPLEX;

public:
    void initialize()
    {
        ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
        ERROR_CHECK( kinect->Open() );
        BOOLEAN isOpen;
        ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
        if( !isOpen ){
            throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
        }

        ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
        CComPtr<IColorFrameSource> colorFrameSource;
        ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
        ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
        CComPtr<IFrameDescription> colorFrameDescription;
        ERROR_CHECK( colorFrameSource->CreateFrameDescription( colorFormat, &colorFrameDescription ) );
        ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) );
        ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) );
        ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) );
        colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
        CComPtr<IBodyFrameSource> bodyFrameSource;
        ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
        ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );

        initializeHDFace();

        // Lookup Table
        colors[0] = cv::Scalar( 255, 0, 0 );
        colors[1] = cv::Scalar( 0, 255, 0 );
        colors[2] = cv::Scalar( 0, 0, 255 );
        colors[3] = cv::Scalar( 255, 255, 0 );
        colors[4] = cv::Scalar( 255, 0, 255 );
        colors[5] = cv::Scalar( 0, 255, 255 );
    }

    void run()
    {
        while( 1 ){
            update();
            draw();

            int key = cv::waitKey( 10 );
            if( key == VK_ESCAPE ){
                cv::destroyAllWindows();
                break;
            }
        }
    }

private:
    void initializeHDFace()
    {
        CComPtr<IHighDefinitionFaceFrameSource> hdFaceFrameSource;
        ERROR_CHECK( CreateHighDefinitionFaceFrameSource( kinect, &hdFaceFrameSource ) );

        ERROR_CHECK( hdFaceFrameSource->OpenReader( &hdFaceFrameReader ) );

        ERROR_CHECK( CreateFaceAlignment( &faceAlignment ) );

        ERROR_CHECK( CreateFaceModel( 1.0f, FaceShapeDeformations::FaceShapeDeformations_Count, &shapeUnits[0], &faceModel ) );
        ERROR_CHECK( GetFaceModelVertexCount( &vertexCount ) );

        FaceModelBuilderAttributes attribures = FaceModelBuilderAttributes::FaceModelBuilderAttributes_None;
        ERROR_CHECK( hdFaceFrameSource->OpenModelBuilder( attribures, &faceModelBuilder ) );
        ERROR_CHECK( faceModelBuilder->BeginFaceDataCollection() );
    }

    void update()
    {
        updateColorFrame();
        updateBodyFrame();
        updateHDFaceFrame();
    }

    void updateColorFrame()
    {
        CComPtr<IColorFrame> colorFrame;
        HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
        if( FAILED( ret ) ){
            return;
        }

        ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], colorFormat ) );

        colorImage = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
    }

    void updateBodyFrame()
    {
        CComPtr<IBodyFrame> bodyFrame;
        HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
        if( FAILED( ret ) ){
            return;
        }

        std::array<CComPtr<IBody>, BODY_COUNT> bodies;
        ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( BODY_COUNT, &bodies[0] ) );

        findClosestBody( bodies );
    }

    inline void findClosestBody( const std::array<CComPtr<IBody>, BODY_COUNT>& bodies )
    {
        float closest = FLT_MAX;
        for( int count = 0; count < BODY_COUNT; count++ ){
            CComPtr<IBody> body = bodies[count];
            BOOLEAN tracked;
            ERROR_CHECK( body->get_IsTracked( &tracked ) );
            if( !tracked ){
                continue;
            }

            std::array<Joint, JointType::JointType_Count> joints;
            ERROR_CHECK( body->GetJoints( JointType::JointType_Count, &joints[0] ) );
            Joint joint = joints[JointType::JointType_Head];
            if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){
                continue;
            }

            CameraSpacePoint point = joint.Position;
            float distance = std::sqrt( std::pow( point.X, 2 ) + std::pow( point.Y, 2 ) + std::pow( point.Z, 2 ) );
            if( closest <= distance ){
                continue;
            }
            closest = distance;

            UINT64 id;
            ERROR_CHECK( body->get_TrackingId( &id ) );
            if( trackingId != id ){
                trackingId = id;
                trackingCount = count;
                produced = false;


                CComPtr<IHighDefinitionFaceFrameSource> hdFaceFrameSource;
                ERROR_CHECK( hdFaceFrameReader->get_HighDefinitionFaceFrameSource( &hdFaceFrameSource ) );
                ERROR_CHECK( hdFaceFrameSource->put_TrackingId( trackingId ) );
            }
        }
    }

    void updateHDFaceFrame()
    {
        CComPtr<IHighDefinitionFaceFrame> hdFaceFrame;
        HRESULT ret = hdFaceFrameReader->AcquireLatestFrame( &hdFaceFrame );
        if( FAILED( ret ) ){
            return;
        }

        BOOLEAN tracked;
        ERROR_CHECK( hdFaceFrame->get_IsFaceTracked( &tracked ) );
        if( !tracked ){
            return;
        }

        ERROR_CHECK( hdFaceFrame->GetAndRefreshFaceAlignmentResult( faceAlignment ) );
        if( faceAlignment != nullptr ){
            // Face Modelのフィッティング
            buildFaceModel();

            // 結果を取得、描画
            result();
        }
    }

    inline void buildFaceModel()
    {
        if( produced ){
            cv::putText( colorImage, "Status : Complete", cv::Point( 50, 50 ), font, 1.0f, colors[trackingCount], 2, CV_AA );
            return;
        }

        FaceModelBuilderCollectionStatus collection;
        ERROR_CHECK( faceModelBuilder->get_CollectionStatus( &collection ) );
        if( collection ){
            // コレクション状態
            cv::putText( colorImage, "Status : " + std::to_string( collection ), cv::Point( 50, 50 ), font, 1.0f, colors[trackingCount], 2, CV_AA );
            std::string status = status2string( collection );
            cv::putText( colorImage, status, cv::Point( 50, 80 ), font, 1.0f, colors[trackingCount], 2, CV_AA );

            // キャプチャー状態
            FaceModelBuilderCaptureStatus capture;
            ERROR_CHECK( faceModelBuilder->get_CaptureStatus( &capture ) );
            status = status2string( capture );
            cv::putText( colorImage, status, cv::Point( 50, 110 ), font, 1.0f, colors[trackingCount], 2, CV_AA );

            return;
        }

        CComPtr<IFaceModelData> faceModelData;
        ERROR_CHECK( faceModelBuilder->GetFaceData( &faceModelData ) );
        if( faceModelData != nullptr ){
            ERROR_CHECK( faceModelData->ProduceFaceModel( &faceModel ) );
            produced = true;
        }
    }

    inline std::string status2string( const FaceModelBuilderCollectionStatus collection )
    {
        //文字数の都合上省略します。
        return status;
    }

    inline std::string status2string( const FaceModelBuilderCaptureStatus capture )
    {
        //文字数の都合上省略します。
    }

    inline void result()
    {
        //文字数の都合上省略します。
    }

    void draw()
    {
        drawHDFaceFrame();
    }

    void drawHDFaceFrame()
    {
        if( !colorImage.empty() ){
            cv::imshow( "HDFace", colorImage );
        }
    }
};

void main()
{
    try{
        KinectApp app;
        app.initialize();
        app.run();
    }
    catch( std::exception& ex ){
        std::cout << ex.what() << std::endl;
    }
}


コード

  

###発生している問題・エラーメッセージ


エラーメッセージ
```

該当のソースコード

補足情報(言語/FW/ツール等のバージョンなど)

言語:C++
NugetでOpenCVを入れました

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.35%

関連した質問

  • 解決済

    C# wave 出力方法について

    前提・実現したいこと C# kinect等の音声機器で取得した音声データを,「○○.wav」のファイルに保存したいです. 発生している問題・エラーメッセージ `

  • 受付中

    Ruby(mruby)とvector等のC++のSTLを連携させるには?

    Ruby(mruby)とC++を連携させようと考えています。 int等、C++のプリミティブ型や関数、クラスを連携させるのは mrubybindという外部のソースコードを 借り

  • 解決済

    数字の合計を表示させる方法

    こんにちは。C++で、int a,bにいくつかの数字を入力し、それぞれの合計を表示するプログラムを作りたいのですが、合計を表示させる方法が分かりません。どなたか教えていただけないで

  • 解決済

    C++ typeid演算子の値がサンプルと違う。

    現在macOSにて、書籍「やさしいC++ 第5版」の写経をしています。 そこで今、typeid演算子を使って派生クラスのオブジェクトのアドレスを入れた基底クラスのポインタ配列からそ

  • 受付中

    C++ファイルの空判定

    C++でファイルの中身が空か判定する方法はありますか? fgetsで1行目を読み込んでnullで判定という手法はありますが、 他にスマートなやり方があればご教示願いします。

  • 受付中

    構造体の中にある配列の初期化の方法が分からず…

    実現したいこと C言語によるプログラミングを行っていて、構造体の配列を初期化しようとしています。 発生している問題・エラーメッセージ 初期化ならこうすればいけるんじゃないかと以

  • 解決済

    c言語で10進数が格納された配列を文字(char)に変換する関数の作成

    前提・実現したいこと c言語で10進数が格納された配列を文字(char)に変換する関数を作りたい 発生している問題・エラーメッセージ 変換がされないとの、putchar((in

  • 解決済

    OpenCVを使った笑顔検出での問題

    前提・実現したいこと OpenCVで元からあるサンプルコード「smiledetect.cpp」を用いて笑顔検出のシステムを作っています。 検出機能を実装中に以下の問題が発生しました

同じタグがついた質問を見る

  • C++

    2412questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1204questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

  • OpenCV

    617questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

  • Kinect

    64questions

    Kinect(キネクト)はマイクロソフトから発売されたジェスチャー・音声認識によって 操作ができるデバイスです。