c_cpp 为Kinect SDK v2正文数据序列化Boost.Serialization(XML)的定义

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp 为Kinect SDK v2正文数据序列化Boost.Serialization(XML)的定义相关的知识,希望对你有一定的参考价值。

// kinect2_serialization
//
// kinect2_serialization is definitions of Boost.Serialization (XML) for body data that retrieved using Kinect SDK v2.
// You will be able to serialize and deserialize body data using this definitions.
// kinect2_serialization are requires Boost.Serialization and Kinect SDK v2 when serializing data.
// kinect2_serialization are requires only Boost.Serialization when deserialize data.
//
// This source code is licensed under the MIT license. Please see the License in License.txt.
// Copyright (c) 2017 Tsukasa SUGIURA
// t.sugiura0204@gmail.com

#ifndef __KINECT2_SERIALIZATION__
#define __KINECT2_SERIALIZATION__

#include <iostream>
#include <cstdint>
#include <array>
#include <string>
#include <fstream>
#include <sstream>
#include <stdexcept>

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/string.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

// Error Check Macro
#ifndef FAILED
#define FAILED(hr) (((HRESULT)(hr)) < 0)
#endif

#ifndef ERROR_CHECK
#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() );             \
    }
#endif

// Body Count
#ifndef BODY_COUNT
#define BODY_COUNT 6
#endif

// Joint Type
#ifndef _JointType_
#define _JointType_
typedef enum _JointType JointType;

enum _JointType
{
    JointType_SpineBase = 0,
    JointType_SpineMid = 1,
    JointType_Neck = 2,
    JointType_Head = 3,
    JointType_ShoulderLeft = 4,
    JointType_ElbowLeft = 5,
    JointType_WristLeft = 6,
    JointType_HandLeft = 7,
    JointType_ShoulderRight = 8,
    JointType_ElbowRight = 9,
    JointType_WristRight = 10,
    JointType_HandRight = 11,
    JointType_HipLeft = 12,
    JointType_KneeLeft = 13,
    JointType_AnkleLeft = 14,
    JointType_FootLeft = 15,
    JointType_HipRight = 16,
    JointType_KneeRight = 17,
    JointType_AnkleRight = 18,
    JointType_FootRight = 19,
    JointType_SpineShoulder = 20,
    JointType_HandTipLeft = 21,
    JointType_ThumbLeft = 22,
    JointType_HandTipRight = 23,
    JointType_ThumbRight = 24,
    JointType_Count = ( JointType_ThumbRight + 1 )
};
#endif

// Tracking State
#ifndef _TrackingState_
#define _TrackingState_
typedef enum _TrackingState TrackingState;

enum _TrackingState
{
    TrackingState_NotTracked = 0,
    TrackingState_Inferred = 1,
    TrackingState_Tracked = 2
};
#endif

// CameraSpacePoint
#ifndef _CameraSpacePoint_
#define _CameraSpacePoint_
typedef struct _CameraSpacePoint
{
    float X;
    float Y;
    float Z;

    private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize( Archive& archive, unsigned int version )
    {
        static_cast<void>( version );
        archive & boost::serialization::make_nvp( "X", X );
        archive & boost::serialization::make_nvp( "Y", Y );
        archive & boost::serialization::make_nvp( "Z", Z );
    }
} CameraSpacePoint;
#else
namespace boost
{
    namespace serialization
    {
        template<class Archive>
        void serialize( Archive& archive, CameraSpacePoint& position, unsigned int version )
        {
            static_cast<void>( version );
            archive & boost::serialization::make_nvp( "X", position.X );
            archive & boost::serialization::make_nvp( "Y", position.Y );
            archive & boost::serialization::make_nvp( "Z", position.Z );
        }
    }
}
#endif

// Joint
#ifndef _Joint_
#define _Joint_
typedef struct _Joint
{
    JointType JointType;
    CameraSpacePoint Position;
    TrackingState TrackingState;

    private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize( Archive& archive, unsigned int version )
    {
        static_cast<void>( version );
        archive & boost::serialization::make_nvp( "JointType", JointType );
        archive & boost::serialization::make_nvp( "TrackingState", TrackingState );
        if( TrackingState == TrackingState::TrackingState_NotTracked ){
            return;
        }
        archive & boost::serialization::make_nvp( "CameraSpacePoint", Position );
    }
} Joint;
#else
namespace boost
{
    namespace serialization
    {
        template<class Archive>
        void serialize( Archive& archive, Joint& joint, unsigned int version )
        {
            static_cast<void>( version );
            archive & boost::serialization::make_nvp( "JointType", joint.JointType );
            archive & boost::serialization::make_nvp( "TrackingState", joint.TrackingState );
            if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){
                return;
            }
            archive & boost::serialization::make_nvp( "CameraSpacePoint", joint.Position );
        }
    }
}
#endif

// Body
#ifndef _Body_
#define _Body_
typedef struct _Body
{
    public:
    // Constructor
    _Body()
    {}

    #ifdef __IBody_INTERFACE_DEFINED__
    // Constructor
    _Body( const IBody* cbody )
    {
        *this = cbody;
    }

    // Operator Assignment
    _Body& operator = ( const IBody* cbody )
    {
        IBody* body = const_cast<IBody*>( cbody );

        BOOLEAN tracked = FALSE;
        ERROR_CHECK( body->get_IsTracked( &tracked ) );
        set_IsTracked( ( tracked == TRUE ? true : false ) );

        UINT64 trackingId = 0;
        ERROR_CHECK( body->get_TrackingId( &trackingId ) );
        set_TrackingId( trackingId );

        std::array<Joint, JointType::JointType_Count> joints;
        ERROR_CHECK( body->GetJoints( static_cast<UINT>( joints.size() ), &joints[0] ) );
        SetJoints( joints.size(), &joints[0] );

        return *this;
    }
    #endif

    // Get Tracking State
    const bool get_IsTracked( bool* tracked ) const noexcept
    {
        *tracked = this->tracked;
        return true;
    }

    // Set Tracking State
    const bool set_IsTracked( const bool tracked ) noexcept
    {
        this->tracked = tracked;
        return true;
    }

    // Get Tracking ID
    const bool get_TrackingId( uint64_t* trackingId ) const noexcept
    {
        *trackingId = this->trackingId;
        return true;
    }

    // Set Tracking ID
    const bool set_TrackingId( const uint64_t trackingId ) noexcept
    {
        this->trackingId = trackingId;
        return true;
    }

    // Get Joints
    const bool GetJoints( const size_t capacity, Joint* joints ) const noexcept
    {
        if( capacity != this->joints.size() ){
            return false;
        }

        std::copy( &this->joints[0], &this->joints[0] + capacity, &joints[0] );
        return true;
    }

    // Set Joints
    const bool SetJoints( const size_t capacity, const Joint* joints ) noexcept
    {
        if( capacity != this->joints.size() ){
            return false;
        }

        std::copy( &joints[0], &joints[0] + capacity, &this->joints[0] );
        return true;
    }

    private:
    bool tracked = false;
    uint64_t trackingId = 0;
    std::array<Joint, JointType::JointType_Count> joints;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize( Archive& archive, unsigned int version )
    {
        static_cast<void>( version );
        archive & boost::serialization::make_nvp( "TrackingState", tracked );
        if( !tracked ){
            return;
        }
        archive & boost::serialization::make_nvp( "TrackingID", trackingId );
        archive & boost::serialization::make_nvp( "Joint", joints );
    }
} Body;
#endif

// Frame
#ifndef _Frame_
#define _Frame_
typedef struct _Frame
{
    public:
    // Constructor
    _Frame()
    {}

    #ifdef __IBodyFrame_INTERFACE_DEFINED__
    // Constructor
    _Frame( const IBodyFrame* cframe )
    {
        *this = cframe;
    }

    // Operator Assignment
    _Frame& operator = ( const IBodyFrame* cframe )
    {
        IBodyFrame* frame = const_cast<IBodyFrame*>( cframe );

        TIMESPAN rerativeTime = 0;
        ERROR_CHECK( frame->get_RelativeTime( &rerativeTime ) );
        set_RelativeTime( rerativeTime );

        std::array<IBody*, BODY_COUNT> bodies = { nullptr };
        ERROR_CHECK( frame->GetAndRefreshBodyData( static_cast<UINT>( bodies.size() ), &bodies[0] ) );
        SetBodies( bodies.size(), const_cast<const IBody**>( &bodies[0] ) );

        std::for_each( bodies.begin(), bodies.end(), []( IBody*& body ){ if( body != nullptr ){ body->Release(); body = nullptr; } } );

        return *this;
    }
    #endif

    // Get RelativeTime
    const bool get_RelativeTime( int64_t* relativeTime ) const noexcept
    {
        *relativeTime = this->relativeTime;
        return true;
    }

    // Set RelativeTime
    const bool set_RelativeTime( const int64_t relativeTime ) noexcept
    {
        this->relativeTime = relativeTime;
        return true;
    }

    // Get Bodies
    const bool GetBodies( const size_t capacity, Body* bodies ) const noexcept
    {
        if( capacity != this->bodies.size() ){
            return false;
        }

        std::copy( &this->bodies[0], &this->bodies[0] + capacity, &bodies[0] );
        return true;
    }

    #ifdef __IBody_INTERFACE_DEFINED__
    // Set Bodies
    const bool SetBodies( const size_t capacity, const IBody** bodies ) noexcept
    {
        if( capacity != this->bodies.size() ){
            return false;
        }

        std::copy( &bodies[0], &bodies[0] + capacity, &this->bodies[0] );
        return true;
    }
    #endif

    private:
    int64_t relativeTime = 0;
    std::array<Body, BODY_COUNT> bodies;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize( Archive& archive, unsigned int version )
    {
        static_cast<void>( version );
        archive & boost::serialization::make_nvp( "RerativeTime", relativeTime );
        archive & boost::serialization::make_nvp( "Body", bodies );
    }
} Frame;
#endif

#endif // __KINECT2_SERIALIZATION__

以上是关于c_cpp 为Kinect SDK v2正文数据序列化Boost.Serialization(XML)的定义的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp Kinect v2坐标系统映射

c_cpp 使用PCLVisualizer和Kinect v2 Grabber绘制点云

c_cpp 使用继承Kinect2Grabber的CustomGrabber从Kinect v2中检索Body(Joint)

c_cpp 使用KinectGrabber / Kinect2Grabber从Kinect v1 / v2传感器检索的pcl :: PointCloud <pcl :: PointXYZRGBA

c_cpp 使用不带Grabber的Point Cloud Library绘制从Kinect v2检索到的Point Cloud

Kinect for Windows SDK v2.0 开发笔记 (十五) 手势帧