Example #1
0
        /// <summary>
        /// 骨格座標の信頼性の値(分散以外)を求めます
        /// </summary>
        /// <param name="record"></param>
        /// <param name="time"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public double GetSkeletonReliability(MotionData prevFrame, MotionData nextFrame, Dictionary <JointType, Joint> prevJoints, Dictionary <JointType, Joint> nextJoints, DateTime time,
                                             CameraIntrinsics cameraInfo)
        {
            double periodAfter  = (time - prevFrame.TimeStamp).TotalSeconds;
            double periodBefore = (nextFrame.TimeStamp - time).TotalSeconds;
            double weightPeriod = Math.Exp(-periodAfter / 0.2) + Math.Exp(-periodBefore / 0.2);

            if (prevJoints == null || prevJoints.Count == 0)
            {
                return(0);
            }
            if (nextJoints == null || nextJoints.Count == 0)
            {
                return(0);
            }
            double prevEdge = 1;
            double nextEdge = 1;

            if (prevJoints.Count > 0)
            {
                prevEdge = prevJoints.Values.Select(p => Utility.GetRatioSqOfPrincipalToFocal(cameraInfo, p.Position.X, p.Position.Y)).Select(v => 1.0 / (1.0 + Math.Pow(v, 4))).Average();
            }
            if (nextJoints.Count > 0)
            {
                nextEdge = nextJoints.Values.Select(p => Utility.GetRatioSqOfPrincipalToFocal(cameraInfo, p.Position.X, p.Position.Y)).Select(v => 1.0 / (1.0 + Math.Pow(v, 4))).Average();
            }
            return(weightPeriod * Math.Sqrt(prevEdge * nextEdge));
        }
 /// <summary>
 /// 指定されたレコードの指定された時刻の指定されたユーザの骨格座標の水平垂直標準偏差積を求めます
 /// </summary>
 /// <param name="record"></param>
 /// <param name="time"></param>
 /// <param name="user"></param>
 /// <returns></returns>
 public double GetVarianceWeight(MotionData prevFrame, MotionData nextFrame, Dictionary<JointType, Joint> prevJoints, Dictionary<JointType, Joint> nextJoints, DateTime time)
 {
     if (prevJoints == null || prevJoints.Count == 0)
         return 0;
     if (nextJoints == null || nextJoints.Count == 0)
         return 0;
     double prevVariance = GetSkeletonCamPosVariance(prevJoints.Values.Select(p => (CvPoint3D64f)p.Position.ToCvPoint3D()).ToList());
     double nextVariance = GetSkeletonCamPosVariance(prevJoints.Values.Select(p => (CvPoint3D64f)p.Position.ToCvPoint3D()).ToList());
     return Math.Sqrt(prevVariance * nextVariance);
 }
        /// <summary>
        /// データを破棄して既存のデータをロードします。
        /// </summary>
        /// <param name="dataDir"></param>
        public void LoadAndSetData(string dataDir)
        {
            this.dataDir    = dataDir;
            this.recordPath = Path.Combine(dataDir, bodyInfoFilename);

            this.motionDataList = this.GetMotionDataFromFile(this.recordPath);
            MotionData md = this.motionDataList[0];

            this.colorWidth  = md.ColorWidth;
            this.colorHeight = md.ColorHeight;
            this.depthWidth  = md.DepthUserWidth;
            this.depthHeight = md.DepthUserHeight;
        }
Example #4
0
        /// <summary>
        /// 指定されたレコードの指定された時刻の指定されたユーザの骨格座標の水平垂直標準偏差積を求めます
        /// </summary>
        /// <param name="record"></param>
        /// <param name="time"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public double GetVarianceWeight(MotionData prevFrame, MotionData nextFrame, Dictionary <JointType, Joint> prevJoints, Dictionary <JointType, Joint> nextJoints, DateTime time)
        {
            if (prevJoints == null || prevJoints.Count == 0)
            {
                return(0);
            }
            if (nextJoints == null || nextJoints.Count == 0)
            {
                return(0);
            }
            double prevVariance = GetSkeletonCamPosVariance(prevJoints.Values.Select(p => (CvPoint3D64f)p.Position.ToCvPoint3D()).ToList());
            double nextVariance = GetSkeletonCamPosVariance(prevJoints.Values.Select(p => (CvPoint3D64f)p.Position.ToCvPoint3D()).ToList());

            return(Math.Sqrt(prevVariance * nextVariance));
        }
        private void ConvertOldToNew(string filepath)
        {
            List <MotionDataOld> mdos;
            var serializer = MessagePackSerializer.Get <List <MotionDataOld> >();

            using (FileStream fs = File.Open(filepath, FileMode.Open))
            {
                mdos = (List <MotionDataOld>)serializer.Unpack(fs);
            }

            //ここで変換する
            List <MotionData> newMd = new List <MotionData>();

            foreach (MotionDataOld mdo in mdos)
            {
                MotionData md = new MotionData();
                md.FrameNo         = mdo.FrameNo;
                md.ImagePath       = mdo.ImagePath;
                md.DepthPath       = mdo.DepthPath;
                md.UserPath        = mdo.UserPath;
                md.bodies          = mdo.bodies.CloneDeep();
                md.TimeStamp       = mdo.TimeStamp;
                md.ColorWidth      = mdo.ColorWidth;
                md.ColorHeight     = mdo.ColorHeight;
                md.DepthUserWidth  = mdo.DepthUserWidth;
                md.DepthUserHeight = mdo.DepthUserHeight;
                if (mdo.depthLUT != null)
                {
                    md.depthLUT = mdo.depthLUT.CloneDeep();
                }
                else
                {
                    md.depthLUT = null;
                }
                newMd.Add(md);
            }

            var serializer2 = MessagePackSerializer.Get <List <MotionData> >();

            using (FileStream fs = File.Open(filepath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                lock (newMd)
                {
                    serializer2.Pack(fs, newMd);
                }
            }
        }
Example #6
0
        public Dictionary <JointType, CvPoint3D64f> InterpolateSkeleton(MotionData prevFrame, MotionData nextFrame, Dictionary <JointType, Joint> prevJoints, Dictionary <JointType, Joint> nextJoints,
                                                                        DateTime time, CvMat ToWorldConversion)
        {
            double prevWeight;

            if (prevFrame.TimeStamp >= nextFrame.TimeStamp)
            {
                prevWeight = 1;
            }
            else
            {
                prevWeight = (time - prevFrame.TimeStamp).TotalSeconds / (nextFrame.TimeStamp - prevFrame.TimeStamp).TotalSeconds;
            }
            double nextWeight = 1.0 - prevWeight;

            if (prevJoints == null || nextJoints == null)
            {
                return(null);
            }
            Dictionary <JointType, CvPoint3D64f> prevData = prevJoints.ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
            Dictionary <JointType, CvPoint3D64f> nextData = nextJoints.ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
            List <JointType> joints = prevData.Keys.Union(nextData.Keys).ToList();
            Dictionary <JointType, CvPoint3D64f> ret = new Dictionary <JointType, CvPoint3D64f>();

            foreach (JointType joint in joints)
            {
                CvPoint3D64f prevPos, nextPos;
                bool         prevFound = prevData.TryGetValue(joint, out prevPos);
                bool         nextFound = nextData.TryGetValue(joint, out nextPos);
                if ((prevFound && nextFound))
                {
                    ret[joint] = CvEx.ConvertPoint3D(prevPos * prevWeight + nextPos * nextWeight, ToWorldConversion);
                }
                else if (_omitWhenDataLack)
                {
                    if (prevFound)
                    {
                        ret[joint] = CvEx.ConvertPoint3D(prevPos, ToWorldConversion);
                    }
                    else if (nextFound)
                    {
                        ret[joint] = CvEx.ConvertPoint3D(nextPos, ToWorldConversion);
                    }
                }
            }
            return(ret);
        }
        /// <summary>
        /// Bodyのidと代表点の座標を返す
        /// </summary>
        /// <param name="recordNo"></param>
        /// <returns></returns>
        public List <Tuple <ulong, Point> > GetIdAndPosition(int recordNo)
        {
            MotionData md = this.records[recordNo];
            List <Tuple <ulong, Point> > ret = new List <Tuple <ulong, Point> >();

            foreach (SerializableBody body in md.bodies)
            {
                if (body.colorSpacePoints != null && body.colorSpacePoints.Count != 0)
                {
                    ret.Add(Tuple.Create(body.TrackingId, Utility.GetAveragePoint(body.colorSpacePoints.Values)));
                }
                else
                {
                    ret.Add(null);
                }
            }
            return(ret);
        }
        /// <summary>
        /// Bodyの左右を反転する
        /// </summary>
        /// <param name="recordNo"></param>
        /// <param name="UserIds"></param>
        public void InverseBody(int recordNo, int integratedId = -1, ulong originalId = 0)
        {
            MotionData md = this.records[recordNo];

            foreach (SerializableBody body in md.bodies)
            {
                if (integratedId != -1 && body.integratedId == integratedId)
                {
                    body.InverseJoints();
                    body.mirrored = !body.mirrored;
                }
                else if (originalId != 0 && body.TrackingId == originalId)
                {
                    body.InverseJoints();
                    body.mirrored = !body.mirrored;
                }
            }
        }
        public void DeleteBody(int recordNo, int integratedId = -1, ulong originalId = 0)
        {
            MotionData md = this.records[recordNo];

            for (int i = 0; i < md.bodies.Length; i++)
            {
                SerializableBody body = md.bodies[i];
                if (integratedId != -1 && body.integratedId == integratedId)
                {
                    Array.Clear(md.bodies, i, 1);
                }
                else if (originalId != 0 && body.TrackingId == originalId)
                {
                    Array.Clear(md.bodies, i, 1);
                }
            }
            md.bodies = md.bodies.Where(b => b != null).ToArray();
        }
        private void ConvertOldToNew(string filepath)
        {
            List<MotionDataOld> mdos;
            var serializer = MessagePackSerializer.Get<List<MotionDataOld>>();
            using (FileStream fs = File.Open(filepath, FileMode.Open))
            {
                mdos = (List<MotionDataOld>)serializer.Unpack(fs);
            }

            //ここで変換する
            List<MotionData> newMd = new List<MotionData>();
            foreach (MotionDataOld mdo in mdos)
            {
                MotionData md = new MotionData();
                md.FrameNo = mdo.FrameNo;
                md.ImagePath = mdo.ImagePath;
                md.DepthPath = mdo.DepthPath;
                md.UserPath = mdo.UserPath;
                md.bodies = mdo.bodies.CloneDeep();
                md.TimeStamp = mdo.TimeStamp;
                md.ColorWidth = mdo.ColorWidth;
                md.ColorHeight = mdo.ColorHeight;
                md.DepthUserWidth = mdo.DepthUserWidth;
                md.DepthUserHeight = mdo.DepthUserHeight;
                if (mdo.depthLUT != null)
                {
                    md.depthLUT = mdo.depthLUT.CloneDeep();
                }
                else
                {
                    md.depthLUT = null;
                }
                newMd.Add(md);
            }

            var serializer2 = MessagePackSerializer.Get<List<MotionData>>();
            using (FileStream fs = File.Open(filepath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                lock (newMd)
                {
                    serializer2.Pack(fs, newMd);
                }
            }
        }
        /// <summary>
        /// データを追加
        /// TODO : 2回目を同じファイル名でレコードすると確実に落ちる
        /// </summary>
        /// <param name="frameNo"></param>
        /// <param name="dateTime"></param>
        /// <param name="bodies"></param>
        public void AddData(int frameNo, DateTime dateTime, Body[] bodies, ref byte[] colorPixels, ref ushort[] depthBuffer, ref byte[] bodyIndexBuffer, Dictionary <ulong, PointsPair> pointPairs)
        {
            this.SaveImages(frameNo, ref colorPixels, ref depthBuffer, ref bodyIndexBuffer);
            MotionData motionData = new MotionData(frameNo, this.dataDir, dateTime, bodies, pointPairs);

            motionData.ColorWidth      = this.colorWidth;
            motionData.ColorHeight     = this.colorHeight;
            motionData.DepthUserWidth  = this.depthWidth;
            motionData.DepthUserHeight = this.depthHeight;
            if (frameNo == 0)
            {
                motionData.depthLUT = this.DepthLUT;
            }

            lock (this.motioDataQueue)
            {
                this.motioDataQueue.Enqueue(motionData);
            }
        }
 /// <summary>
 /// 骨格座標の信頼性の値(分散以外)を求めます
 /// </summary>
 /// <param name="record"></param>
 /// <param name="time"></param>
 /// <param name="user"></param>
 /// <returns></returns>
 public double GetSkeletonReliability(MotionData prevFrame, MotionData nextFrame, Dictionary<JointType, Joint> prevJoints, Dictionary<JointType, Joint> nextJoints, DateTime time, 
     CameraIntrinsics cameraInfo)
 {
     double periodAfter = (time - prevFrame.TimeStamp).TotalSeconds;
     double periodBefore = (nextFrame.TimeStamp - time).TotalSeconds;
     double weightPeriod = Math.Exp(-periodAfter / 0.2) + Math.Exp(-periodBefore / 0.2);
     if (prevJoints == null || prevJoints.Count == 0)
         return 0;
     if (nextJoints == null || nextJoints.Count == 0)
         return 0;
     double prevEdge = 1;
     double nextEdge = 1;
     if (prevJoints.Count > 0)
     {
         prevEdge = prevJoints.Values.Select(p => Utility.GetRatioSqOfPrincipalToFocal(cameraInfo, p.Position.X, p.Position.Y)).Select(v => 1.0 / (1.0 + Math.Pow(v, 4))).Average();
     }
     if (nextJoints.Count > 0)
     {
         nextEdge = nextJoints.Values.Select(p => Utility.GetRatioSqOfPrincipalToFocal(cameraInfo, p.Position.X, p.Position.Y)).Select(v => 1.0 / (1.0 + Math.Pow(v, 4))).Average();
     }
     return weightPeriod * Math.Sqrt(prevEdge * nextEdge);
 }
Example #13
0
        /// <summary>
        /// バイナリから読み込む
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static List <object> LoadFromSequentialBinary(string path)
        {
            IFormatter    formatter = new BinaryFormatter();
            List <object> res       = new List <object>();

            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None))
            {
                while (fs.Length != fs.Position)
                {
                    MotionData md = (MotionData)formatter.Deserialize(fs);
                    md.isValid = true;
                    res.Add(md);
                    //if (md.TimeStamp.Minute < 20)
                    //{
                    //    res.Add(md);
                    //}
                    //if (md.TimeStamp.Hour == 11 && md.TimeStamp.Minute >= 20)
                    //{
                    //    break;
                    //}
                }
            }
            return(res);
        }
Example #14
0
        /// <summary>
        /// recordNoのデータを使わないように設定する
        /// </summary>
        /// <param name="recordNo"></param>
        public void SetDataNotValid(int recordNo)
        {
            MotionData md = this.records[recordNo];

            md.isValid = false;
        }
 public Dictionary<JointType, CvPoint3D64f> InterpolateSkeleton(MotionData prevFrame, MotionData nextFrame, Dictionary<JointType, Joint> prevJoints, Dictionary<JointType, Joint> nextJoints,
     DateTime time, CvMat ToWorldConversion)
 {
     double prevWeight;
     if (prevFrame.TimeStamp >= nextFrame.TimeStamp)
     {
         prevWeight = 1;
     }
     else
     {
         prevWeight = (time - prevFrame.TimeStamp).TotalSeconds / (nextFrame.TimeStamp - prevFrame.TimeStamp).TotalSeconds;
     }
     double nextWeight = 1.0 - prevWeight;
     if (prevJoints == null || nextJoints == null)
         return null;
     Dictionary<JointType, CvPoint3D64f> prevData = prevJoints.ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
     Dictionary<JointType, CvPoint3D64f> nextData = nextJoints.ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
     List<JointType> joints = prevData.Keys.Union(nextData.Keys).ToList();
     Dictionary<JointType, CvPoint3D64f> ret = new Dictionary<JointType, CvPoint3D64f>();
     foreach (JointType joint in joints)
     {
         CvPoint3D64f prevPos, nextPos;
         bool prevFound = prevData.TryGetValue(joint, out prevPos);
         bool nextFound = nextData.TryGetValue(joint, out nextPos);
         if ((prevFound && nextFound))
         {
             ret[joint] = CvEx.ConvertPoint3D(prevPos * prevWeight + nextPos * nextWeight, ToWorldConversion);
         }
         else if (_omitWhenDataLack)
         {
             if (prevFound)
             {
                 ret[joint] = CvEx.ConvertPoint3D(prevPos, ToWorldConversion);
             }
             else if (nextFound)
             {
                 ret[joint] = CvEx.ConvertPoint3D(nextPos, ToWorldConversion);
             }
         }
     }
     return ret;
 }
Example #16
0
        public Dictionary <JointType, CvPoint3D64f> IntegrateSkeleton(DateTime time, int userInt, FrameSequence frameSeq)
        {
            List <CvMat>            ToWorldConversions = frameSeq.ToWorldConversions;
            List <CameraIntrinsics> cameraInfo         = frameSeq.CameraInfo;
            List <UserSegmentation> segm = frameSeq.Segmentations;

            Dictionary <JointType, CvPoint3D64f>[] jointsArr      = new Dictionary <JointType, CvPoint3D64f> [frameSeq.recordNum];
            Dictionary <JointType, CvPoint3D64f>[] pivotCandidate = new Dictionary <JointType, CvPoint3D64f> [frameSeq.recordNum];

            double[] reliabilityArr = new double[frameSeq.recordNum];
            double[] weightArr      = new double[frameSeq.recordNum];

            for (int recordNo = 0; recordNo < frameSeq.recordNum; recordNo++)
            {
                MotionData prevData = frameSeq.GetPrevData(recordNo, time);
                MotionData nextData = frameSeq.GetNextData(recordNo, time);

                if (prevData == null || nextData == null || prevData.bodies.Length * nextData.bodies.Length == 0 || !prevData.isValid || !nextData.isValid)
                {
                    jointsArr[recordNo]      = null;
                    reliabilityArr[recordNo] = 0;
                    weightArr[recordNo]      = 0;
                    continue;
                }

                SerializableBody prevBody = prevData.bodies.Where(b => b.integratedId == userInt).FirstOrDefault();
                SerializableBody nextBody = nextData.bodies.Where(b => b.integratedId == userInt).FirstOrDefault();
                if (prevBody == null || nextBody == null || prevBody.Equals(default(SerializableBody)) || nextBody.Equals(default(SerializableBody)))
                {
                    jointsArr[recordNo]      = null;
                    reliabilityArr[recordNo] = 0;
                    weightArr[recordNo]      = 0;
                    continue;
                }
                // 統計情報によるフィルタリング
                Dictionary <JointType, Joint> prevJoints;
                Dictionary <JointType, Joint> nextJoints;
                if (prevBody.Joints == null || nextBody.Joints == null)
                {
                    continue;
                }

                // pivotが設定されてるとき、つまり、本番統合のとき
                if (pivot != null)
                {
                    // mirror矯正
                    prevJoints = this.CorrectMirrorJoint(prevBody.Joints, ToWorldConversions[recordNo]);
                    nextJoints = this.CorrectMirrorJoint(nextBody.Joints, ToWorldConversions[recordNo]);
                    // next pivot候補つめつめ
                    pivotCandidate[recordNo] = Utility.GetValidJoints(nextJoints).ToDictionary(p => p.Key, p => (CvPoint3D64f)p.Value.Position.ToCvPoint3D());
                }
                else
                {
                    prevJoints = prevBody.Joints;
                    nextJoints = nextBody.Joints;
                }

                // 統計情報があるとき
                if (frameSeq.BodyStat != null)
                {
                    prevJoints = frameSeq.BodyStat.FilterBonesByStatistics(prevJoints);
                    nextJoints = frameSeq.BodyStat.FilterBonesByStatistics(nextJoints);
                }
                else
                {
                    prevJoints = Utility.GetValidJoints(prevBody.Joints);
                    nextJoints = Utility.GetValidJoints(nextBody.Joints);
                }

                jointsArr[recordNo]      = this.InterpolateSkeleton(prevData, nextData, prevJoints, nextJoints, time, ToWorldConversions[recordNo]);
                reliabilityArr[recordNo] = this.GetSkeletonReliability(prevData, nextData, prevJoints, nextJoints, time, cameraInfo[recordNo]);
                weightArr[recordNo]      = this.GetVarianceWeight(prevData, nextData, prevJoints, nextJoints, time);
            }

            // pivot更新
            pivot = new Dictionary <JointType, CvPoint3D64f>();
            foreach (var candidate in pivotCandidate)
            {
                if (candidate != null && pivot.Count <= candidate.Count)
                {
                    pivot = candidate;
                }
            }

            double maxWeight = weightArr.Max();

            double[] modifiedReliabilityList = weightArr.Select(w => Math.Max(0, (w / maxWeight) - _weightBase)).Zip(reliabilityArr, (a, b) => a * b).ToArray();
            var      keys = jointsArr.Where(j => j != null).SelectMany(j => j.Keys).Distinct().ToList();

            if (maxWeight == 0)
            {
                return(null);
            }

            return(CalcEx.LinearMedianSkeletons(jointsArr, modifiedReliabilityList));
        }
 /// <summary>
 /// データを追加
 /// TODO : 2回目を同じファイル名でレコードすると確実に落ちる
 /// </summary>
 /// <param name="frameNo"></param>
 /// <param name="dateTime"></param>
 /// <param name="bodies"></param>
 public void AddData(int frameNo, DateTime dateTime, Body[] bodies, ref byte[] colorPixels, ref ushort[] depthBuffer, ref byte[] bodyIndexBuffer, Dictionary<ulong, PointsPair> pointPairs)
 {
     this.SaveImages(frameNo, ref colorPixels, ref depthBuffer, ref bodyIndexBuffer);
     MotionData motionData = new MotionData(frameNo, this.dataDir, dateTime, bodies, pointPairs);
     motionData.ColorWidth = this.colorWidth;
     motionData.ColorHeight = this.colorHeight;
     motionData.DepthUserWidth = this.depthWidth;
     motionData.DepthUserHeight = this.depthHeight;
     if (frameNo == 0)
     {
         motionData.depthLUT = this.DepthLUT;
     }
     
     lock (this.motioDataQueue)
     {
         this.motioDataQueue.Enqueue(motionData);
     }
 }