private float[,] DoTrain(ref GestureDetector gd)
    {
        /* arrange the key frame data in m_skRecorder.m_dataList */
        m_postFeature.Reset();
        m_postFeature.RegisterJoints(m_jointIdx);         // set the feature type and joint indices to calculate features
        for (int i = 0; i < m_skRecorder.FrameCount; i++)
        {
            int tag = m_skRecorder.m_tagList[i];
            if (tag == 0)
            {
                continue;
            }
            CopyCurFrameJointDataRef(i);
            m_postFeature.UpdateFeatures();             // calculate the features
            for (int j = 0; j < JointCount; j++)
            {
                gd.m_posts[tag - 1][j].AddTrainData(m_postFeature.m_jointVec[(int)m_jointIdx[j]]);
            }
        }

        /* train the posture templates */
        float[,] stdArray = new float[m_tagCount, JointCount];
        for (int i = 0; i < m_tagCount; i++)
        {
            for (int j = 0; j < JointCount; j++)
            {
                stdArray[i, j] = gd.m_posts[i][j].Train();
            }
        }
        // train time interval coefficients
        TrainTimeIntv(gd);

        return(stdArray);
    }
    /// initializer. called after LoadFromFile is called
    public void Init(JointFeature pf)
    {
        if (m_posts == null)
        {
            throw new Exception("the PostureDetector members should be initialized first.");
        }
        m_postFeature    = pf;
        m_fsm            = new FSM(PostureCount, m_intervals, m_intvThres);
        m_fsm.m_thresMul = m_thresMulTimeIntv;
        m_isPostDet      = new bool[PostureCount];
        m_postFeature.RegisterJoints(m_jointIdx);

        // more initialization for the relative joint matcher
        for (int i = 0; i < PostureCount; i++)
        {
            for (int j = 0; j < m_posts[i].JointCount; j++)
            {
                m_posts[i][j].m_thresMul = m_thresMulPerPost[i] * m_thresMulPerJoint[j];
                JointMatcherR jmr = m_posts[i][j] as JointMatcherR;
                if (jmr != null)
                {
                    jmr.SetLastPostJoint(this, i, j);
                }
            }
            m_posts[i].Init(pf);             // should be called after m_posts[i][j].m_thresMul is initialized
        }
    }