/// <summary>
 /// 全てのユーザを統合してバイナリで出力する
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void ExportAllBodiesAsBinary_Click(object sender, RoutedEventArgs e)
 {
     if (frameSequence.Segmentations != null)
     {
         var res = SkeletonInterpolator.ExportFromProject(frameSequence, startIndex, endIndex);
         Dictionary <int, List <Dictionary <JointType, CvPoint3D64f> > > mergedBodies = res.Item1;
         foreach (int userId in mergedBodies.Keys)
         {
             string path = System.IO.Path.Combine(Environment.CurrentDirectory, userId.ToString() + @"_Body.dump");
             Utility.SaveBodySequence(mergedBodies[userId], path);
         }
         //Utility.SaveToBinary(res.Item2, System.IO.Path.Combine(Environment.CurrentDirectory, @"TimeData.dump"));
     }
 }
 /// <summary>
 /// 選択中のユーザを統合してバイナリで出力する
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void ExportSelectedBodiesAsBinary_Click(object sender, RoutedEventArgs e)
 {
     if (frameSequence.Segmentations != null && this.isUserSelected.All(b => b))
     {
         var    res  = SkeletonInterpolator.ExportFromProject(frameSequence, startIndex, endIndex);
         string path = System.IO.Path.Combine(Environment.CurrentDirectory, @"SelectedUserBody.dump");
         int    id   = this.frameSequence.selecteedIntegretedIdList[0];
         if (this.frameSequence.selecteedIntegretedIdList.All(i => i == id))
         {
             if (res.Item1.Keys.Contains(id))
             {
                 Utility.SaveBodySequence(res.Item1[id], path);
                 Utility.SaveToBinary(res.Item2[id], System.IO.Path.Combine(Environment.CurrentDirectory, @"TimeData.dump"));
             }
         }
     }
 }
        /// <summary>
        /// 修正してくれるやつ
        /// </summary>
        /// <param name="frameSeq"></param>
        public static void Correct(FrameSequence frameSeq) {
            List<OrderTuple> orders = new List<OrderTuple>();
            foreach (var pair in frameSeq.Frames.Select((frame, index) => Tuple.Create(frame, index)))
            {
                for (int recordNo = 0; recordNo < pair.Item1.recordNum; recordNo++)
                {
                    orders.Add(new OrderTuple(pair.Item1.Time, recordNo, pair.Item2));
                }
            }
            // 前フレームのユーザと対応するBodyを保持する
            Dictionary<int, SerializableBody>[] prevUserBodyMapArray = new Dictionary<int, SerializableBody>[frameSeq.recordNum];
            for (int i = 0; i < frameSeq.recordNum; i++)
            {
                prevUserBodyMapArray[i] = new Dictionary<int, SerializableBody>();
            }
            SerializableBody prevUserBody;

            orders = orders.OrderBy(x => x.Timestamp.Ticks).ToList();
            SkeletonInterpolator interp = new SkeletonInterpolator(0.5, true);
            foreach (OrderTuple tuple in orders) {
                Frame currFrame = frameSeq.Frames[tuple.FrameIndex];
                const long maxInterval = (long)(10000000 * 0.1);
                DateTime prev = new DateTime(tuple.Timestamp.Ticks - maxInterval);
                IEnumerable<int> users = currFrame.GetBodyList(tuple.RecordIndex).Select(b => b.integratedId);
                foreach (int user in users)
                {
                    SerializableBody currBody = currFrame.GetSelectedBody(tuple.RecordIndex, integratedId: user);
                    // 前のBodyと比較して同じ場合は処理をスキップする
                    if (prevUserBodyMapArray[tuple.RecordIndex].TryGetValue(user, out prevUserBody) && prevUserBody.Joints != null && currBody.Joints != null)
                    {
                        double avgDistanceSq = CalcBodyDistanceSq(prevUserBody.Joints, currBody.Joints).Values.Average();
                        if (avgDistanceSq == 0.0)
                        {
                            //currFrame.DeleteBody(tuple.RecordIndex, integratedId: user);
                            continue;
                        }
                    }
                    prevUserBodyMapArray[tuple.RecordIndex][user] = currBody;

                    Dictionary<JointType, CvPoint3D64f> prevJoints = interp.IntegrateSkeleton(prev, user, frameSeq);
                    if (prevJoints != null && currBody.Joints != null)
                    {
                        Dictionary<JointType, CvPoint3D64f> currJoints = currBody.Joints.ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
                        HashSet<JointType> mirroredPrevKeys = new HashSet<JointType>(prevJoints.Keys.Select(j => CalcEx.GetMirroredJoint(j)));
                        if (currJoints != null && prevJoints != null) {
                            var absJoints = currJoints.ToDictionary(p => p.Key, p => CvEx.ConvertPoint3D(p.Value, frameSeq.ToWorldConversions[tuple.RecordIndex]));
                            var absMirroredJoints = absJoints.ToDictionary(p => CalcEx.GetMirroredJoint(p.Key), p => p.Value);
                            var availableKeys = prevJoints.Keys.Where(j => mirroredPrevKeys.Contains(j)).ToList();
                            var keysNormal = availableKeys.Intersect(absJoints.Keys).ToList();
                            var keysMirrored = availableKeys.Intersect(absMirroredJoints.Keys).ToList();

                            if (keysNormal.Count > 0 && keysMirrored.Count > 0) {
                                double avg1 = keysNormal.Select(j => CvEx.GetDistanceSq(prevJoints[j], absJoints[j])).Average();
                                double avg2 = keysMirrored.Select(j => CvEx.GetDistanceSq(prevJoints[j], absMirroredJoints[j])).Average();
                                if (avg2 < avg1) {
                                    currFrame.InverseBody(tuple.RecordIndex, integratedId: user);
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 修正してくれるやつ
        /// </summary>
        /// <param name="frameSeq"></param>
        public static void Correct(FrameSequence frameSeq)
        {
            List <OrderTuple> orders = new List <OrderTuple>();

            foreach (var pair in frameSeq.Frames.Select((frame, index) => Tuple.Create(frame, index)))
            {
                for (int recordNo = 0; recordNo < pair.Item1.recordNum; recordNo++)
                {
                    orders.Add(new OrderTuple(pair.Item1.Time, recordNo, pair.Item2));
                }
            }
            // 前フレームのユーザと対応するBodyを保持する
            Dictionary <int, SerializableBody>[] prevUserBodyMapArray = new Dictionary <int, SerializableBody> [frameSeq.recordNum];
            for (int i = 0; i < frameSeq.recordNum; i++)
            {
                prevUserBodyMapArray[i] = new Dictionary <int, SerializableBody>();
            }
            SerializableBody prevUserBody;

            orders = orders.OrderBy(x => x.Timestamp.Ticks).ToList();
            SkeletonInterpolator interp = new SkeletonInterpolator(0.5, true);

            foreach (OrderTuple tuple in orders)
            {
                Frame             currFrame   = frameSeq.Frames[tuple.FrameIndex];
                const long        maxInterval = (long)(10000000 * 0.1);
                DateTime          prev        = new DateTime(tuple.Timestamp.Ticks - maxInterval);
                IEnumerable <int> users       = currFrame.GetBodyList(tuple.RecordIndex).Select(b => b.integratedId);
                foreach (int user in users)
                {
                    SerializableBody currBody = currFrame.GetSelectedBody(tuple.RecordIndex, integratedId: user);
                    // 前のBodyと比較して同じ場合は処理をスキップする
                    if (prevUserBodyMapArray[tuple.RecordIndex].TryGetValue(user, out prevUserBody) && prevUserBody.Joints != null && currBody.Joints != null)
                    {
                        double avgDistanceSq = CalcBodyDistanceSq(prevUserBody.Joints, currBody.Joints).Values.Average();
                        if (avgDistanceSq == 0.0)
                        {
                            //currFrame.DeleteBody(tuple.RecordIndex, integratedId: user);
                            continue;
                        }
                    }
                    prevUserBodyMapArray[tuple.RecordIndex][user] = currBody;

                    Dictionary <JointType, CvPoint3D64f> prevJoints = interp.IntegrateSkeleton(prev, user, frameSeq);
                    if (prevJoints != null && currBody.Joints != null)
                    {
                        Dictionary <JointType, CvPoint3D64f> currJoints = currBody.Joints.ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
                        HashSet <JointType> mirroredPrevKeys            = new HashSet <JointType>(prevJoints.Keys.Select(j => CalcEx.GetMirroredJoint(j)));
                        if (currJoints != null && prevJoints != null)
                        {
                            var absJoints         = currJoints.ToDictionary(p => p.Key, p => CvEx.ConvertPoint3D(p.Value, frameSeq.ToWorldConversions[tuple.RecordIndex]));
                            var absMirroredJoints = absJoints.ToDictionary(p => CalcEx.GetMirroredJoint(p.Key), p => p.Value);
                            var availableKeys     = prevJoints.Keys.Where(j => mirroredPrevKeys.Contains(j)).ToList();
                            var keysNormal        = availableKeys.Intersect(absJoints.Keys).ToList();
                            var keysMirrored      = availableKeys.Intersect(absMirroredJoints.Keys).ToList();

                            if (keysNormal.Count > 0 && keysMirrored.Count > 0)
                            {
                                double avg1 = keysNormal.Select(j => CvEx.GetDistanceSq(prevJoints[j], absJoints[j])).Average();
                                double avg2 = keysMirrored.Select(j => CvEx.GetDistanceSq(prevJoints[j], absMirroredJoints[j])).Average();
                                if (avg2 < avg1)
                                {
                                    currFrame.InverseBody(tuple.RecordIndex, integratedId: user);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
        public static Tuple <Dictionary <int, List <Dictionary <JointType, CvPoint3D64f> > >, Dictionary <int, List <DateTime> > > ExportFromProject(FrameSequence frameseq, int startIndex, int endIndex)
        {
            TimeSpan        period     = new TimeSpan((long)(10000000 / frameseq.frameRate));
            List <DateTime> timestamps = new List <DateTime>();

            for (DateTime time = frameseq.Frames[startIndex].Time; time < frameseq.Frames[endIndex].Time; time += period)
            {
                timestamps.Add(time);
            }

            HashSet <Tuple <int, JointType> > uniqueUserJoint = new HashSet <Tuple <int, JointType> >();
            List <Frame> frames = frameseq.Slice(startIndex, endIndex);

            foreach (Frame frame in frames)
            {
                for (int i = 0; i < frameseq.recordNum; i++)
                {
                    foreach (SerializableBody body in frame.GetBodyList(i))
                    {
                        foreach (JointType jointType in Utility.GetValidJoints(body.Joints).Keys)
                        {
                            // TrackingIdと勝手に作ったuser idの対応辞書が必要. 以下の処理はとりあえず
                            Tuple <int, JointType> userJoint = new Tuple <int, JointType>(body.integratedId, jointType);
                            if (!uniqueUserJoint.Contains(userJoint))
                            {
                                uniqueUserJoint.Add(userJoint);
                            }
                        }
                    }
                }
            }

            List <Tuple <int, JointType> > userJointPairs = (
                from pair in uniqueUserJoint
                orderby pair.Item1, pair.Item2
                select pair
                ).ToList();

            Dictionary <int, List <Dictionary <JointType, CvPoint3D64f> > > allBodies = new Dictionary <int, List <Dictionary <JointType, CvPoint3D64f> > >();
            Dictionary <int, List <DateTime> > allTimes = new Dictionary <int, List <DateTime> >();
            SkeletonInterpolator skeletonInterpolator   = new SkeletonInterpolator(0.5, true);

            foreach (int user in userJointPairs.Select(p => p.Item1).Distinct())
            {
                skeletonInterpolator.pivot = new Dictionary <JointType, CvPoint3D64f>();
                // pivot初期化処理
                Dictionary <JointType, Joint>[] firstJoints = new Dictionary <JointType, Joint> [frameseq.recordNum];
                for (int no = 0; no < frameseq.recordNum; no++)
                {
                    var bodies = frameseq.GetNextData(no, timestamps[0]).bodies;
                    if (bodies.Count() > 0)
                    {
                        SerializableBody body = bodies.Where(b => b.integratedId == user).FirstOrDefault();
                        if (body != null)
                        {
                            var validJoints = Utility.GetValidJoints(body.Joints).ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
                            if (skeletonInterpolator.pivot.Count < validJoints.Count)
                            {
                                skeletonInterpolator.pivot = validJoints;
                            }
                        }
                    }
                }

                List <Dictionary <JointType, CvPoint3D64f> > jointsSeq = new List <Dictionary <JointType, CvPoint3D64f> >();
                List <DateTime> times = new List <DateTime>();
                foreach (DateTime time in timestamps)
                {
                    Dictionary <JointType, CvPoint3D64f> joints = skeletonInterpolator.IntegrateSkeleton(time, user, frameseq);
                    // jointsがnullの場合にはダミーデータを突っ込んで長さを稼ぐ
                    if (joints == null)
                    {
                        jointsSeq.Add(new Dictionary <JointType, CvPoint3D64f>()
                        {
                            { JointType.SpineBase, new CvPoint3D64f(float.MaxValue, float.MaxValue, float.MaxValue) }
                        });
                    }
                    else
                    {
                        jointsSeq.Add(joints);
                    }
                    times.Add(time);
                }
                allBodies[user] = jointsSeq;
                allTimes[user]  = times;
            }
            return(Tuple.Create(allBodies, allTimes));
        }
        public static Tuple<Dictionary<int, List<Dictionary<JointType, CvPoint3D64f>>>, Dictionary<int, List<DateTime>>> ExportFromProject(FrameSequence frameseq, int startIndex, int endIndex)
        {
            TimeSpan period = new TimeSpan((long)(10000000 / frameseq.frameRate));
            List<DateTime> timestamps = new List<DateTime>();
            for (DateTime time = frameseq.Frames[startIndex].Time; time < frameseq.Frames[endIndex].Time; time += period)
            {
                timestamps.Add(time);
            }

            HashSet<Tuple<int, JointType>> uniqueUserJoint = new HashSet<Tuple<int, JointType>>();
            List<Frame> frames = frameseq.Slice(startIndex, endIndex);
            foreach(Frame frame in frames){
                for (int i = 0; i < frameseq.recordNum; i++)
                {
                    foreach (SerializableBody body in frame.GetBodyList(i))
                    {
                        foreach (JointType jointType in Utility.GetValidJoints(body.Joints).Keys)
                        {
                            // TrackingIdと勝手に作ったuser idの対応辞書が必要. 以下の処理はとりあえず
                            Tuple<int, JointType> userJoint = new Tuple<int, JointType>(body.integratedId, jointType);
                            if (!uniqueUserJoint.Contains(userJoint))
                            {
                                uniqueUserJoint.Add(userJoint);
                            }
                        }
                    }
                }
            }

            List<Tuple<int, JointType>> userJointPairs = (
                from pair in uniqueUserJoint
                orderby pair.Item1, pair.Item2
                select pair
                ).ToList();

            Dictionary<int, List<Dictionary<JointType, CvPoint3D64f>>> allBodies = new Dictionary<int, List<Dictionary<JointType, CvPoint3D64f>>>();
            Dictionary<int, List<DateTime>> allTimes = new Dictionary<int, List<DateTime>>();
            SkeletonInterpolator skeletonInterpolator = new SkeletonInterpolator(0.5, true);
            foreach (int user in userJointPairs.Select(p => p.Item1).Distinct())            
            {
                skeletonInterpolator.pivot = new Dictionary<JointType, CvPoint3D64f>();
                // pivot初期化処理
                Dictionary<JointType, Joint>[] firstJoints = new Dictionary<JointType,Joint>[frameseq.recordNum];
                for (int no = 0; no < frameseq.recordNum; no++)
                {
                    var bodies = frameseq.GetNextData(no, timestamps[0]).bodies;
                    if (bodies.Count() > 0)
                    {
                        SerializableBody body = bodies.Where(b => b.integratedId == user).FirstOrDefault();
                        if (body != null)
                        {
                            var validJoints = Utility.GetValidJoints(body.Joints).ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
                            if (skeletonInterpolator.pivot.Count < validJoints.Count)
                            {
                                skeletonInterpolator.pivot = validJoints;
                            }
                        }
                    }
                }

                List<Dictionary<JointType, CvPoint3D64f>> jointsSeq = new List<Dictionary<JointType, CvPoint3D64f>>();
                List<DateTime> times = new List<DateTime>();
                foreach(DateTime time in timestamps)
                {
                    Dictionary<JointType, CvPoint3D64f> joints = skeletonInterpolator.IntegrateSkeleton(time, user, frameseq);
                    // jointsがnullの場合にはダミーデータを突っ込んで長さを稼ぐ
                    if (joints == null)
                    {
                        jointsSeq.Add(new Dictionary<JointType, CvPoint3D64f>() { { JointType.SpineBase, new CvPoint3D64f(float.MaxValue, float.MaxValue, float.MaxValue) } });
                    }
                    else
                    {
                        jointsSeq.Add(joints);
                    }
                    times.Add(time);
                }
                allBodies[user] = jointsSeq;
                allTimes[user] = times;
            }
            return Tuple.Create(allBodies, allTimes);
        }