public void UpdateTrack() { if (Results == null || Results.Count == 0) { return; } List <PointF> motionTrack = new List <PointF>(); List <Vector> orientationTrack = new List <Vector>(); int startOffset = Results.First(x => x.Value != null).Key; int frameCount = Results.Count; for (int i = 0; i < frameCount; i++) { ISingleFrameExtendedResults currentFrameResult = Results[i]; if (currentFrameResult == null) { continue; } PointF[] headPoints = currentFrameResult.HeadPoints; if (headPoints != null) { PointF midPoint = headPoints[1].MidPoint(headPoints[3]); //Vector up = new Vector(0,1); Vector dir = new Vector(headPoints[2].X - midPoint.X, headPoints[2].Y - midPoint.Y); orientationTrack.Add(dir); motionTrack.Add(headPoints[2]); } } MotionTrack = motionTrack.ToArray(); //OrientationTrack = orientationTrack.ToArray(); if (Boundries != null) { GenerateBehaviourAnalysis(MotionTrack, Boundries, startOffset); } }
private Dictionary <int, ISingleFrameExtendedResults> GenerateDictionary() { //const int SecondBinaryThresold = 10; const double movementDelta = 15; RBSK rbsk = MouseService.GetStandardMouseRules(); if (GapDistance == 0) { GapDistance = GetBestGapDistance(rbsk); } rbsk.Settings.GapDistance = GapDistance; rbsk.Settings.BinaryThreshold = ThresholdValue; Dictionary <int, ISingleFrameExtendedResults> results = new Dictionary <int, ISingleFrameExtendedResults>(); VideoWidth = (int)Image.Width; VideoHeight = (int)Image.Height; //Video.Reset(); int counter = 0; int frameCount = 1; //int frameCount = 70; while (true) { if (Paused) { continue; } if (Cancelled || counter == frameCount) { break; } //using (Image<Bgr, byte> frame = Video.GetFrameImage()) { double waist, waistArea, waistArea2, waistArea3, waistArea4; PointF centroid; //if (counter == 500) //{ // frame.ROI = new Rectangle(0,0,1,1); //} Point[] bodyContour; PointF[] headPoints = ProcessFrame(Image, rbsk, out waist, out waistArea, out waistArea2, out waistArea3, out waistArea4, out centroid, out bodyContour, true); //Console.WriteLine(waist + " " + waistArea); //if (headPoints != null) //{ // foreach (var point in headPoints) // { // frame.Draw(new CircleF(point, 2), new Bgr(Color.Yellow), 2); // } //} //ImageViewer.Show(frame); ISingleFrameExtendedResults frameResult = ModelResolver.Resolve <ISingleFrameExtendedResults>(); frameResult.HeadPoints = headPoints; frameResult.CentroidSize = waist; frameResult.PelvicArea = waistArea; frameResult.PelvicArea2 = waistArea2; frameResult.PelvicArea3 = waistArea3; frameResult.PelvicArea4 = waistArea4; frameResult.Centroid = centroid; frameResult.BodyContour = bodyContour; results.Add(counter, frameResult); counter++; if (ProgressUpdates != null) { ProgressUpdates(this, new RBSKVideoUpdateEvent(((double)counter / frameCount) / 2)); } } } if (Cancelled) { return(results); } //Find the most confident run of head detections List <List <HeadPointHolder> > confidentPoints = new List <List <HeadPointHolder> >(); PointF lastPoint = PointF.Empty; List <HeadPointHolder> currentList = new List <HeadPointHolder>(); double currentTotalMovement = 0; for (int i = 0; i < results.Count; i++) { PointF[] headPoints = results[i].HeadPoints; if (headPoints == null) { //No head found, use alternative methods if (currentList.Count > 0) { confidentPoints.Add(currentList); } currentList = new List <HeadPointHolder>(); lastPoint = PointF.Empty; currentTotalMovement = 0; //Console.WriteLine("Head points are null " + i); continue; } //Check against expected position PointF currentPoint = headPoints[2]; if (lastPoint.IsEmpty) { lastPoint = currentPoint; currentList.Add(new HeadPointHolder(i, currentPoint, currentTotalMovement)); continue; } double distance = lastPoint.Distance(currentPoint); if (distance < movementDelta) { //Acceptable currentTotalMovement += distance; currentList.Add(new HeadPointHolder(i, currentPoint, currentTotalMovement)); lastPoint = currentPoint; } else { if (currentList.Count > 0) { confidentPoints.Add(currentList); } currentList = new List <HeadPointHolder>(); lastPoint = PointF.Empty; currentTotalMovement = 0; //Console.WriteLine("Outside of range " + i); } } if (currentList.Count > 0) { confidentPoints.Add(currentList); } if (confidentPoints.Count == 0) { return(results); } //Find longest list with highest total movement List <HeadPointHolder> bestList = confidentPoints[0]; //double currentMaxTraverse = bestList.Last().TotalDelta; foreach (List <HeadPointHolder> list in confidentPoints) { //double currentTotalDelta = list.Last().TotalDelta; if (list.Count > bestList.Count) { //currentMaxTraverse = currentTotalDelta; bestList = list; } } //We now have a confident set of headpoints int minIndex = bestList.Select(x => x.FrameNumber).Min(); int maxIndex = bestList.Select(x => x.FrameNumber).Max(); minIndex--; while (minIndex >= 0) { //Traverse backwards PointF[] lastPoints = results[minIndex + 1].HeadPoints; if (lastPoints != null) { lastPoint = lastPoints[2]; } else { lastPoint = new PointF(-100, -100); } PointF[] headPoints = results[minIndex].HeadPoints; if (headPoints == null) { //No head found, use alternative methods int previousThreshold = rbsk.Settings.BinaryThreshold; rbsk.Settings.BinaryThreshold = ThresholdValue2; //Video.SetFrame(minIndex); PointF[] headPoints2 = null; //using (Image<Bgr, byte> frame = Video.GetFrameImage()) { //if (frame == null) //{ // break; //} //if (Roi != Rectangle.Empty) //{ // frame.ROI = Roi; //} headPoints2 = ProcessFrame(Image, rbsk, lastPoint, movementDelta); } rbsk.Settings.BinaryThreshold = previousThreshold; if (headPoints2 != null) { //We've got a good location //double temp = results[minIndex].CentroidSize; results[minIndex].HeadPoints = headPoints2; //results[minIndex].CentroidSize = temp; //results[minIndex] = new Tuple<PointF[], double>(headPoints2, temp); } else { for (int i = 0; i <= minIndex; i++) { if (results.ContainsKey(i)) { //double temp = results[i].Item2; //results[i] = new Tuple<PointF[], double>(null, temp); results[i].HeadPoints = null; } } break; } minIndex--; continue; } //Check against expected position PointF currentPoint = headPoints[2]; if (lastPoint.Distance(currentPoint) < movementDelta) { //Good point } else { //Wrong point, search for another rbsk that falls within range //if (minIndex == 17 || minIndex == 16) //{ // Console.WriteLine(""); //} //Video.SetFrame(minIndex); PointF[] headPoints2 = null; //using (Image<Bgr, byte> frame = Video.GetFrameImage()) { //if (frame == null) //{ // break; //} //if (Roi != Rectangle.Empty) //{ // frame.ROI = Roi; //} headPoints2 = ProcessFrame(Image, rbsk, lastPoint, movementDelta); } if (headPoints2 != null) { //We've got a good location //double temp = results[maxIndex].Item2; //results[minIndex] = new Tuple<PointF[], double>(headPoints2, temp); results[minIndex].HeadPoints = headPoints2; } else { //No other rbsk falls within range, use alternative methods //Console.WriteLine("Need to use alternative methods"); for (int i = 0; i <= minIndex; i++) { if (results.ContainsKey(i)) { //double temp = results[i].Item2; //results[i] = new Tuple<PointF[], double>(null, temp); results[i].HeadPoints = null; } } break; } } minIndex--; } maxIndex++; while (maxIndex < results.Count) { //Traverse backwards PointF[] lastPoints = results[maxIndex - 1].HeadPoints; if (lastPoints != null) { lastPoint = lastPoints[2]; } else { lastPoint = new PointF(-100, -100); } PointF[] headPoints = results[maxIndex].HeadPoints; if (headPoints == null) { //No head found, use alternative methods int previousThreshold = rbsk.Settings.BinaryThreshold; rbsk.Settings.BinaryThreshold = ThresholdValue2; //Video.SetFrame(maxIndex); PointF[] headPoints2 = null; //using (Image<Bgr, byte> frame = Video.GetFrameImage()) { //if (frame == null) //{ // break; //} //if (Roi != Rectangle.Empty) //{ // frame.ROI = Roi; //} headPoints2 = ProcessFrame(Image, rbsk, lastPoint, movementDelta); } rbsk.Settings.BinaryThreshold = previousThreshold; if (headPoints2 != null) { //We've got a good location //double temp = results[maxIndex].Item2; //results[maxIndex] = new Tuple<PointF[], double>(headPoints2, temp); results[maxIndex].HeadPoints = headPoints2; } else { int max = results.Keys.Max(); for (int i = maxIndex; i <= max; i++) { if (results.ContainsKey(i)) { //double temp = results[i].Item2; //results[i] = new Tuple<PointF[], double>(null, temp); results[i].HeadPoints = null; } } break; } maxIndex++; continue; } //Check against expected position PointF currentPoint = headPoints[2]; if (lastPoint.Distance(currentPoint) < movementDelta) { //Good point } else { //Wrong point, search for another rbsk that falls within range //Video.SetFrame(maxIndex); PointF[] headPoints2 = null; //using (Image<Bgr, byte> frame = Video.GetFrameImage()) { headPoints2 = ProcessFrame(Image, rbsk, lastPoint, movementDelta); } if (headPoints2 != null) { //We've got a good location //double temp = results[maxIndex].Item2; //results[maxIndex] = new Tuple<PointF[], double>(headPoints2, temp); results[maxIndex].HeadPoints = headPoints2; } else { //No other rbsk falls within range, use alternative methods //Console.WriteLine("Need to use alternative methods"); int max = results.Keys.Max(); for (int i = maxIndex; i <= max; i++) { if (results.ContainsKey(i)) { //double temp = results[i].Item2; //results[i] = new Tuple<PointF[], double>(null, temp); results[i].HeadPoints = null; } } break; } } maxIndex++; } return(results); }
private void PostProcessWhiskers() { Console.WriteLine("Starting post processing"); KeyValuePair <int, ISingleFrameExtendedResults> initWhiskers = HeadPoints.First(x => x.Value != null && x.Value.AllWhiskers != null && x.Value.AllWhiskers.LeftWhiskers != null && x.Value.AllWhiskers.LeftWhiskers.Any()); int initKey = initWhiskers.Key; //int width = (int)Video.Width; //int height = (int)Video.Height; IWhiskerSegment[] leftWhiskers = initWhiskers.Value.AllWhiskers.LeftWhiskers; IWhiskerSegment[] rightWhiskers = initWhiskers.Value.AllWhiskers.RightWhiskers; IWhiskerAllocator wa = ModelResolver.Resolve <IWhiskerAllocator>(); ISingleFrameExtendedResults firstResult = HeadPoints[initKey]; PointF nosePoint = firstResult.HeadPoint; PointF midPoint = firstResult.HeadPoints[1].MidPoint(firstResult.HeadPoints[3]); ITrackSingleWhisker[] leftTrackedWhiskers = wa.InitialiseWhiskers(leftWhiskers, nosePoint, midPoint); ITrackSingleWhisker[] rightTrackedWhiskers = wa.InitialiseWhiskers(rightWhiskers, nosePoint, midPoint); initKey++; for (int i = initKey; i < HeadPoints.Count; i++) { //IWhiskerCollection whiskerCollection = preliminaryWhiskers[i]; IWhiskerSegment[] cLeftWhiskers = HeadPoints[i].AllWhiskers.LeftWhiskers; IWhiskerSegment[] cRightWhiskers = HeadPoints[i].AllWhiskers.RightWhiskers; //IWhiskerAllocator wa = ModelResolver.Resolve<IWhiskerAllocator>(); Dictionary <IWhiskerSegment, ITrackSingleWhisker> left = wa.AllocateWhiskers(i, leftTrackedWhiskers, cLeftWhiskers, nosePoint, midPoint); Dictionary <IWhiskerSegment, ITrackSingleWhisker> right = wa.AllocateWhiskers(i, rightTrackedWhiskers, cRightWhiskers, nosePoint, midPoint); foreach (var kvp in left) { kvp.Value.CurrentWhisker = kvp.Key; kvp.Value.WhiskerList.Add(i, kvp.Key); } foreach (var kvp in right) { kvp.Value.CurrentWhisker = kvp.Key; kvp.Value.WhiskerList.Add(i, kvp.Key); } //foreach (ITrackSingleWhisker iWhisker in leftTrackedWhiskers) //{ // iWhisker.FindPotentialWhisker(i, cLeftWhiskers); //} //foreach (ITrackSingleWhisker iWhisker in rightTrackedWhiskers) //{ // iWhisker.FindPotentialWhisker(i, cRightWhiskers); //} } //Dictionary<int, IWhiskerCollection> finalWhiskers = new Dictionary<int, IWhiskerCollection>(); for (int i = 0; i < HeadPoints.Count; i++) { IWhiskerCollection whiskerCollection = ModelResolver.Resolve <IWhiskerCollection>(); List <IWhiskerSegment> leftWhisks = new List <IWhiskerSegment>(); List <IWhiskerSegment> rightWhisks = new List <IWhiskerSegment>(); foreach (var trackedWhisker in leftTrackedWhiskers) { if (trackedWhisker.WhiskerList.ContainsKey(i)) { leftWhisks.Add(trackedWhisker.WhiskerList[i]); } } foreach (var trackedWhisker in rightTrackedWhiskers) { if (trackedWhisker.WhiskerList.ContainsKey(i)) { rightWhisks.Add(trackedWhisker.WhiskerList[i]); } } whiskerCollection.LeftWhiskers = leftWhisks.ToArray(); whiskerCollection.RightWhiskers = rightWhisks.ToArray(); HeadPoints[i].AllWhiskers = whiskerCollection; //finalWhiskers.Add(i, whiskerCollection); } //AllRects = allRects; //WhiskerResults = finalWhiskers; }
private void ProcessWhiskers() { bool time = false; //bool showOnce = true; //Get quarter size of image around nose point int newWidth = (int)(VideoWidth / ZoomRatio); int newHeight = (int)(VideoHeight / ZoomRatio); IWhiskerDetector whiskerDetector = ModelResolver.Resolve <IWhiskerDetector>(); //float scaleRatio = 4; //whiskerDetector.LineLength = 8*(int) scaleRatio; whiskerDetector.OrientationResolution = 1; //Dictionary<int, IWhiskerCollection> whiskers = new Dictionary<int, IWhiskerCollection>(); int newCount = HeadPoints.Count; int counter = 0; for (int i = 0; i < HeadPoints.Count; i++) { //Stopwatch sw = new Stopwatch(); ISingleFrameExtendedResults currentFrame = HeadPoints[i]; counter++; if (currentFrame == null) { //whiskers.Add(i, null); if (ProgressUpdates != null) { ProgressUpdates(this, new RBSKVideoUpdateEvent(0.5 + (((double)counter / newCount) / 2))); } continue; } if (currentFrame.HeadPoints == null) { //whiskers.Add(i, null); if (ProgressUpdates != null) { ProgressUpdates(this, new RBSKVideoUpdateEvent(0.5 + (((double)counter / newCount) / 2))); } continue; } if (currentFrame.BodyContour == null || !currentFrame.BodyContour.Any()) { //whiskers.Add(i, null); if (ProgressUpdates != null) { ProgressUpdates(this, new RBSKVideoUpdateEvent(0.5 + (((double)counter / newCount) / 2))); } continue; } //if (time) //{ // sw.Stop(); // Console.WriteLine("1) " + sw.ElapsedMilliseconds); // sw.Restart(); //} int x = (int)currentFrame.HeadPoints[2].X - (newWidth / 2); int y = (int)currentFrame.HeadPoints[2].Y - (newHeight / 2); int left = x + newWidth; int top = y + newHeight; if (x < 0) { x = 0; } if (y < 0) { y = 0; } if (left > VideoWidth) { left = VideoWidth; } if (top > VideoHeight) { top = VideoHeight; } Rectangle zoomRect = new Rectangle(x, y, left - x, top - y); //if (time) //{ // sw.Stop(); // Console.WriteLine("2) " + sw.ElapsedMilliseconds); // sw.Restart(); //} //Video.SetFrame(i); //if (time) //{ // sw.Stop(); // Console.WriteLine("3) " + sw.ElapsedMilliseconds); // sw.Restart(); //} Inter interpolationType = Inter.Area; //using (Image<Gray, byte> frame = Video.GetGrayFrameImage()) { Image.ROI = zoomRect; BackgroundImage.ROI = zoomRect; //if (time) //{ // sw.Stop(); // Console.WriteLine("4) " + sw.ElapsedMilliseconds); // sw.Restart(); //} using (Image <Gray, byte> subImage = Image.Copy()) using (Image <Gray, byte> subBinary = BackgroundImage.Copy()) using (Image <Gray, byte> zoomedImage = subImage.Resize(ScaleRatio, interpolationType)) using (Image <Gray, byte> zoomedBinary = subBinary.Resize(ScaleRatio, interpolationType)) { //if (time) //{ // sw.Stop(); // Console.WriteLine("5) " + sw.ElapsedMilliseconds); // sw.Restart(); //} //if (showOnce) //{ // ImageViewer.Show(zoomedImage); // ImageViewer.Show(zoomedBinary); // showOnce = false; //} PointF[] headPointsCorrected = new PointF[5]; int bodyContourLength = currentFrame.BodyContour.Length; Point[] bodyContourCorrected = new Point[bodyContourLength]; for (int j = 0; j < 5; j++) { headPointsCorrected[j] = new PointF((currentFrame.HeadPoints[j].X - zoomRect.X) * ScaleRatio, (currentFrame.HeadPoints[j].Y - zoomRect.Y) * ScaleRatio); } for (int j = 0; j < bodyContourLength; j++) { bodyContourCorrected[j] = new Point((int)((currentFrame.BodyContour[j].X - zoomRect.X) * ScaleRatio), (int)((currentFrame.BodyContour[j].Y - zoomRect.Y) * ScaleRatio)); } List <IWhiskerSegment>[] cWhisk = whiskerDetector.FindWhiskers(zoomedImage, zoomedBinary, headPointsCorrected, bodyContourCorrected, (int)ScaleRatio, currentFrame, null); List <IWhiskerSegment> cWhiskLeft = cWhisk[0]; List <IWhiskerSegment> cWhiskRight = cWhisk[1]; //if (time) //{ // sw.Stop(); // Console.WriteLine("6) " + sw.ElapsedMilliseconds); // sw.Restart(); //} //IWhiskerSegment[] correctedWhiskers = new IWhiskerSegment[cWhisk.Length]; foreach (var whisker in cWhiskLeft) { whisker.X = (int)((whisker.X / ScaleRatio) + zoomRect.X); whisker.Y = (int)((whisker.Y / ScaleRatio) + zoomRect.Y); Point p1 = new Point((int)((whisker.Line.P1.X / ScaleRatio)) + zoomRect.X, (int)((whisker.Line.P1.Y / ScaleRatio) + zoomRect.Y)); Point p2 = new Point((int)((whisker.Line.P2.X / ScaleRatio)) + zoomRect.X, (int)((whisker.Line.P2.Y / ScaleRatio) + zoomRect.Y)); whisker.Line = new LineSegment2D(p1, p2); } foreach (var whisker in cWhiskRight) { whisker.X = (int)((whisker.X / ScaleRatio) + zoomRect.X); whisker.Y = (int)((whisker.Y / ScaleRatio) + zoomRect.Y); Point p1 = new Point((int)((whisker.Line.P1.X / ScaleRatio)) + zoomRect.X, (int)((whisker.Line.P1.Y / ScaleRatio) + zoomRect.Y)); Point p2 = new Point((int)((whisker.Line.P2.X / ScaleRatio)) + zoomRect.X, (int)((whisker.Line.P2.Y / ScaleRatio) + zoomRect.Y)); whisker.Line = new LineSegment2D(p1, p2); } IWhiskerCollection whiskerCollection = ModelResolver.Resolve <IWhiskerCollection>(); whiskerCollection.LeftWhiskers = cWhiskLeft.ToArray(); whiskerCollection.RightWhiskers = cWhiskRight.ToArray(); currentFrame.AllWhiskers = whiskerCollection; //whiskers.Add(i, whiskerCollection); } } if (ProgressUpdates != null) { ProgressUpdates(this, new RBSKVideoUpdateEvent(0.5 + (((double)counter / newCount) / 2))); } //if (time) //{ // sw.Stop(); // Console.WriteLine("7) " + sw.ElapsedMilliseconds); // sw.Restart(); //} } //WhiskerResultsAll = whiskers; //PostProcessWhiskers(); //WhiskerResults = whiskers; }
public ISingleFrameExtendedResults GetData() { ISingleFrameExtendedResults result = ModelResolver.Resolve <ISingleFrameExtendedResults>(); if (HeadPoints != null) { result.HeadPoints = HeadPoints.Select(x => x.GetPoint()).ToArray(); } else { result.HeadPoints = null; } if (BodyContour != null) { result.BodyContour = BodyContour.Select(x => x.GetPoint()).ToArray(); } else { result.BodyContour = null; } if (HeadPoint != null) { result.HeadPoint = HeadPoint.GetPoint(); result.MidPoint = MidPoint.GetPoint(); } if (SmoothedHeadPoint != null) { result.SmoothedHeadPoint = SmoothedHeadPoint.GetPoint(); } if (Orientation != null) { result.Orientation = Orientation.GetVector(); } result.CentroidSize = CentroidSize; result.PelvicArea = PelvicArea; result.Velocity = Velocity; result.AngularVelocity = AngularVelocity; result.Distance = Distance; result.PelvicArea2 = PelvicArea2; result.PelvicArea3 = PelvicArea3; result.PelvicArea4 = PelvicArea4; if (Centroid != null) { result.Centroid = Centroid.GetPoint(); } if (Whiskers != null) { result.Whiskers = Whiskers.GetWhiskerCollection(); } if (AllWhiskers != null) { result.AllWhiskers = AllWhiskers.GetWhiskerCollection(); } if (BestTrackedWhisker != null) { result.BestTrackedWhisker = BestTrackedWhisker.GetWhiskerCollection(); } result.DataLoadComplete(); return(result); }
public SingleFrameExtendedResultXml(ISingleFrameExtendedResults result) { if (result.HeadPoints == null) { HeadPoints = null; HeadPoint = null; MidPoint = null; } else { HeadPoints = result.HeadPoints.Select(x => new PointFXml(x.X, x.Y)).ToArray(); HeadPoint = HeadPoints[2]; MidPoint = new PointFXml(result.HeadPoints[1].MidPoint(result.HeadPoints[3])); } if (result.BodyContour != null) { BodyContour = result.BodyContour.Select(x => new PointXml(x)).ToArray(); } else { BodyContour = null; } SmoothedHeadPoint = new PointFXml(result.SmoothedHeadPoint); Orientation = new VectorXml(result.Orientation); CentroidSize = result.CentroidSize; PelvicArea = result.PelvicArea; Velocity = result.Velocity; AngularVelocity = result.AngularVelocity; Distance = result.Distance; PelvicArea2 = result.PelvicArea2; PelvicArea3 = result.PelvicArea3; PelvicArea4 = result.PelvicArea4; Centroid = new PointFXml(result.Centroid); if (result.Whiskers != null) { Whiskers = new WhiskerCollectionXml(result.Whiskers); } else { Whiskers = null; } if (result.AllWhiskers != null) { AllWhiskers = new WhiskerCollectionXml(result.AllWhiskers); } else { AllWhiskers = null; } if (result.BestTrackedWhisker != null) { BestTrackedWhisker = new WhiskerCollectionXml(result.BestTrackedWhisker); } else { BestTrackedWhisker = null; } }