/// <summary>
 /// 現在のフレームのレコード・ユーザを信頼できるデータとしてタグ付けする
 /// TODO : UI上で特別なデータは色とかで反映する
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void CheckTrustDataFrame_Click(object sender, RoutedEventArgs e)
 {
     // record, userを選択中のやつ
     for (int recordNo = 0; recordNo < frameSequence.recordNum; recordNo++)
     {
         if (this.isRecordSelected[recordNo])
         {
             int       record = recordNo;
             int       user   = this.frameSequence.selecteedIntegretedIdList[recordNo];
             int       frame  = this.playingIndex;
             TrustData td     = new TrustData(frame, record, user);
             // こいつをUI上で反映する手がかりにする
             SerializableBody body = td.GetBody(this.frameSequence.Frames);
             body.trustData = true;
             this.frameSequence.trustData.Add(td);
         }
     }
 }
Esempio n. 2
0
        /// <summary>
        /// ミラー状態を補正するための基準骨格フレーム複数から、比較すべきフレームの範囲を決定する
        /// </summary>
        /// <param name="frameLength"></param>
        /// <param name="trustDataList"></param>
        /// <returns></returns>
        private List <Tuple <TrustData, int> > GenerateIterationRanges(int frameLength, List <TrustData> trustDataList)
        {
            trustDataList.Sort((a, b) => a.frameIndex - b.frameIndex);
            List <Tuple <TrustData, int> > iterationRanges = new List <Tuple <TrustData, int> >();

            iterationRanges.Add(Tuple.Create(trustDataList.First(), 0));
            // 基準フレームが複数の場合
            if (trustDataList.Count >= 2)
            {
                for (int i = 0; i < trustDataList.Count() - 1; i++)
                {
                    TrustData curr      = trustDataList[i];
                    TrustData next      = trustDataList[i + 1];
                    int       halfIndex = (curr.frameIndex + next.frameIndex) / 2;
                    iterationRanges.Add(Tuple.Create(curr, halfIndex));
                    iterationRanges.Add(Tuple.Create(next, halfIndex + 1));
                }
            }
            iterationRanges.Add(Tuple.Create(trustDataList.Last(), frameLength - 1));
            return(iterationRanges);
        }
        /// <summary>
        /// 現在のフレームのレコード・ユーザを信頼できるデータとしてタグ付けする
        /// TODO : UI上で特別なデータは色とかで反映する
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckTrustDataFrame_Click(object sender, RoutedEventArgs e)
        {
            // record, userを選択中のやつ
            for (int recordNo = 0; recordNo < frameSequence.recordNum; recordNo++)
            {
                if (this.isRecordSelected[recordNo])
                {
                    int record = recordNo;
                    int user = this.frameSequence.selecteedIntegretedIdList[recordNo];
                    int frame = this.playingIndex;
                    TrustData td = new TrustData(frame, record, user);
                    // こいつをUI上で反映する手がかりにする
                    SerializableBody body = td.GetBody(this.frameSequence.Frames);
                    body.trustData = true;
                    this.frameSequence.trustData.Add(td);
                }
            }

        }
Esempio n. 4
0
        public void Correct(FrameSequence frameSeq)
        {
            // 選択中の統合IDをチェック
            List <TrustData> trustDatas = frameSeq.trustData.Where(t => t.integratedBodyId == frameSeq.selecteedIntegretedIdList[0]).ToList();
            // generate iteration
            List <Tuple <TrustData, int> > iterations = this.GenerateIterationRanges(frameSeq.Frames.Count(), frameSeq.trustData);

            foreach (Tuple <TrustData, int> iterationRange in iterations)
            {
                // set and calcurate pivot
                TrustData        trustData = iterationRange.Item1;
                SerializableBody pivotBody = trustData.GetBody(frameSeq.Frames);
                // translate to world coordinate
                Dictionary <JointType, CvPoint3D64f> pivotJoints = pivotBody.Joints.ToDictionary(p => p.Key,
                                                                                                 p => CvEx.ConvertPoint3D(p.Value.Position.ToCvPoint3D(), frameSeq.ToWorldConversions[trustData.recordIndex]));
                CvPoint3D64f pivotBodyRightVector = this.CalcRightChestCrossVector(pivotJoints);
                CvPoint3D64f pivotBodyLeftVector  = this.CalcLeftChestCrossVector(pivotJoints);
                CvPoint3D64f pivotBodyCrossVector = CvEx.Normalize(pivotBodyRightVector + pivotBodyLeftVector);
                // z軸との角度 +だったらあっち向いてる
                double pivotCrossZCos = CvEx.Cos(pivotBodyCrossVector, new CvPoint3D64f(0, 0, 1));
                // ので、反転してたら修正する
                if (pivotCrossZCos > 0)
                {
                    pivotBody.InverseJoints();
                    pivotJoints = pivotBody.Joints.ToDictionary(p => p.Key,
                                                                p => CvEx.ConvertPoint3D(p.Value.Position.ToCvPoint3D(), frameSeq.ToWorldConversions[trustData.recordIndex]));
                    pivotBodyRightVector = this.CalcRightChestCrossVector(pivotJoints);
                    pivotBodyLeftVector  = this.CalcLeftChestCrossVector(pivotJoints);
                    pivotBodyCrossVector = CvEx.Normalize(pivotBodyRightVector + pivotBodyLeftVector);
                }

                // 繰り返し範囲の連続indexを生成して回す
                IEnumerable <int> continuousRange = this.GenerateContinuousRange(trustData.frameIndex, iterationRange.Item2);
                foreach (int frameIndex in continuousRange)
                {
                    // 前のpivotとのベクトルの差が小さいやつを選んでいく投票空間
                    double[]       bodyCos     = new double[frameSeq.recordNum];
                    CvPoint3D64f[] bodyCrosses = new CvPoint3D64f[frameSeq.recordNum];
                    bool[]         validFlags  = frameSeq.Frames[frameIndex].GetValidFlags();
                    for (int recordNo = 0; recordNo < frameSeq.recordNum; recordNo++)
                    {
                        // pivotと一致した場合
                        if (trustData.recordIndex == recordNo && trustData.frameIndex == frameIndex)
                        {
                            bodyCos[recordNo]     = 1;
                            bodyCrosses[recordNo] = pivotBodyCrossVector;
                            continue;
                        }
                        SerializableBody body = frameSeq.Frames[frameIndex].GetSelectedBody(recordNo, integratedId: trustData.integratedBodyId);
                        if (body == null || body == default(SerializableBody) || body.Joints.Count == 0 || validFlags[recordNo] == false)
                        {
                            bodyCos[recordNo] = -1;
                            continue;
                        }
                        Dictionary <JointType, CvPoint3D64f> joints = body.Joints.ToDictionary(p => p.Key,
                                                                                               p => CvEx.ConvertPoint3D(p.Value.Position.ToCvPoint3D(), frameSeq.ToWorldConversions[recordNo]));
                        // 右胸、左胸の外積ベクトル(正規化済み)
                        CvPoint3D64f rightVector = this.CalcRightChestCrossVector(joints);
                        CvPoint3D64f leftVector  = this.CalcLeftChestCrossVector(joints);
                        // 前フレームの基準ベクトルとの角度(cos)
                        double bothCrossAngle  = CvEx.Cos(rightVector, leftVector);
                        double rightPivotAngle = CvEx.Cos(rightVector, pivotBodyCrossVector);
                        double leftPivotAngle  = CvEx.Cos(leftVector, pivotBodyCrossVector);
                        bool   removedFlag     = false;
                        // そもそも骨がなかった場合
                        if (rightVector == default(CvPoint3D64f))
                        {
                            body.RemoveJoints(Utility.RightBody);
                            removedFlag = true;
                        }
                        if (leftVector == default(CvPoint3D64f))
                        {
                            body.RemoveJoints(Utility.LeftBody);
                            removedFlag = true;
                        }
                        // 右と左のベクトルが離れすぎてる場合
                        if (bothCrossAngle <= 0)
                        {
                            body.RemoveJoints(Utility.UpperBody);
                            removedFlag = true;
                        }
                        if (removedFlag)
                        {
                            bodyCos[recordNo] = -1;
                            continue;
                        }

                        CvPoint3D64f bodyCrossVector = CvEx.Normalize(rightVector + leftVector);
                        double       bodyCrossdiff   = CvEx.Cos(bodyCrossVector, pivotBodyCrossVector);
                        // reverse check
                        if (bodyCrossdiff <= -0.8)
                        {
                            // reverse and update
                            body.InverseJoints();
                            joints = body.Joints.ToDictionary(p => p.Key,
                                                              p => CvEx.ConvertPoint3D(p.Value.Position.ToCvPoint3D(), frameSeq.ToWorldConversions[recordNo]));
                            rightVector     = this.CalcRightChestCrossVector(joints);
                            leftVector      = this.CalcLeftChestCrossVector(joints);
                            bodyCrossVector = CvEx.Normalize(rightVector + leftVector);
                            bodyCrossdiff   = CvEx.Cos(bodyCrossVector, pivotBodyCrossVector);
                        }
                        // update body angle
                        bodyCos[recordNo]     = bodyCrossdiff;
                        bodyCrosses[recordNo] = bodyCrossVector;
                    }
                    // 前のpivotVectorと似ているほどよい. つまり1に近いほど
                    int pivotRecordNo = bodyCos.ToList().IndexOf(bodyCos.Max());
                    // update pivot body vector
                    pivotBodyCrossVector = bodyCrosses[pivotRecordNo];
                }
            }
        }