public Path(int ID, personBlob blob) { this.ID = ID; this.blob = blob; this.open = false; this.points = new List<PointF>(); }
public void addBlob(personBlob b) { this.blobs.Add(b); }
//get the assignment for blob, comparing a distance heuristic against //all blobs private int getAssignment(personBlob personBlob, List<personBlob> compBlobs, List<int> assigned) { int assign = 0; double best = double.PositiveInfinity; for (int i = 0; i < compBlobs.Count; i++) { double sizeDiff = Math.Sqrt(Math.Abs((personBlob.size - compBlobs[i].size))); if (sizeDiff < 40) { double temp = util.floatDist(personBlob.x, personBlob.y, compBlobs[i].x, compBlobs[i].y); if (temp < 15 && temp < best && !assigned.Contains(i)) { best = temp; assign = i; } } } if (best != double.PositiveInfinity) return assign; else return -1; }
// public BitmapSource findPaths() { Bitmap blank = new Bitmap(640, 480); Graphics g = Graphics.FromImage(blank); System.Drawing.Pen bluePen = new System.Drawing.Pen(System.Drawing.Color.Blue); System.Drawing.Pen greenPen = new System.Drawing.Pen(System.Drawing.Color.Green); System.Drawing.Pen redPen = new System.Drawing.Pen(System.Drawing.Color.Red); //sort by time //go through List of blobs b frame and find paths for (int i = 1; i < this.blobFrames.Count; i++) { Frame prevFrame = blobFrames[i-1]; Frame currFrame = blobFrames[i]; int prevBlobCount = prevFrame.blobs.Count; int currBlobCount = currFrame.blobs.Count; List<personBlob> prevCopy = new List<personBlob>(); foreach (personBlob b in prevFrame.blobs) { personBlob newb = new personBlob(b.x, b.y, b.size); newb.ID = b.ID; prevCopy.Add(newb); } //if the last frame has the same amount of blobs as the current one if (prevBlobCount == currBlobCount) { //if only one person, then we just assign it if (prevBlobCount == 1) { //assign this ID to the blob in the current frame int? id = prevFrame.blobs[0].ID; if (id.HasValue) { currFrame.blobs[0].ID = (int) id; //add this point to the path with this ID this.paths.addPointToPath((int) id, new PointF(currFrame.blobs[0].x, currFrame.blobs[0].y)); } } //more than one person so we need to assign else { List<int> assigned = new List<int>(); //get assignment values for each of the blobs in the current frame, mapped by the previous frame for (int j = 0; j < currBlobCount; j++) { if (prevCopy.Count > 0) { int index = getAssignment(currFrame.blobs[j], prevCopy, assigned); //if index is -1, then we couldn't find an assignment if (index == -1) { currFrame.blobs[j].ID = idCount; Path newPath = new Path(idCount, currFrame.blobs[j]); newPath.open = true; this.paths.addPath(newPath); this.paths.addPointToPath(idCount, new PointF(currFrame.blobs[j].x, currFrame.blobs[j].y)); idCount++; } else { int? id = prevCopy[index].ID; if (id.HasValue) { assigned.Add((int)id); // prevCopy.Remove(prevCopy[index]); currFrame.blobs[j].ID = (int)id; this.paths.addPointToPath((int)id, new PointF(currFrame.blobs[j].x, currFrame.blobs[j].y)); } } } } } } //if there are more blobs in the current frame else if (prevBlobCount < currBlobCount) { //first, we should check to make sure the blob didn't appear out of nowhere //look at position for now, maybe look at change in size //we need to get the indices of the new blob(s) in the current frame List<int> newBlobIndices= getNewBlobs(prevFrame.blobs, currFrame.blobs); List<int> assigned = new List<int>(); //we need to add a new path for new blobs for (int j = 0; j < currBlobCount; j++ ) { //if this blob's index is in the indices of new blobs, //set the blob's ID to a new id and make a new path with this ID and the new blob if (newBlobIndices.Contains(j)) { currFrame.blobs[j].ID = idCount; Path newPath = new Path(idCount, currFrame.blobs[j]); newPath.open = true; this.paths.addPath(newPath); this.paths.addPointToPath(idCount, new PointF(currFrame.blobs[j].x, currFrame.blobs[j].y)); idCount++; } //else, this blob is in the previous frame, so we find the assignment else { if (prevCopy.Count > 0) { int index = getAssignment(currFrame.blobs[j], prevCopy, assigned); if (index == -1) { currFrame.blobs[j].ID = idCount; Path newPath = new Path(idCount, currFrame.blobs[j]); newPath.open = true; this.paths.addPath(newPath); this.paths.addPointToPath(idCount, new PointF(currFrame.blobs[j].x, currFrame.blobs[j].y)); idCount++; } else { int? id = prevCopy[index].ID; if (id.HasValue) { assigned.Add((int)id); // prevCopy.Remove(prevCopy[index]); currFrame.blobs[j].ID = (int)id; this.paths.addPointToPath((int)id, new PointF(currFrame.blobs[j].x, currFrame.blobs[j].y)); } } } } } } //if there are less blobs in the current frame, then we just add the ones that haven't left //to their paths else { //List<int> oldBlobIndices = getOldBlobs(prevFrame.blobs, currFrame.blobs); List<int> assigned = new List<int>(); //with a list of old blobs filtered out, we assign to the current blobs for (int j = 0; j < currBlobCount; j++) { int index = getAssignment(currFrame.blobs[j], prevCopy, assigned); if (index == -1) { currFrame.blobs[j].ID = idCount; Path newPath = new Path(idCount, currFrame.blobs[j]); newPath.open = true; this.paths.addPath(newPath); this.paths.addPointToPath(idCount, new PointF(currFrame.blobs[j].x, currFrame.blobs[j].y)); idCount++; } else { int? id = prevCopy[index].ID; if (id.HasValue && this.paths.isOpen((int)id)) { assigned.Add((int)id); // prevCopy.Remove(prevCopy[index]); currFrame.blobs[j].ID = (int)id; this.paths.addPointToPath((int)id, new PointF(currFrame.blobs[j].x, currFrame.blobs[j].y)); } } } } } System.Drawing.Pen purplePen = new System.Drawing.Pen(System.Drawing.Color.Purple); System.Drawing.Pen medPen = new System.Drawing.Pen(System.Drawing.Color.MediumSeaGreen); System.Drawing.Pen radPen = new System.Drawing.Pen(System.Drawing.Color.MediumTurquoise); System.Drawing.Pen coralPen = new System.Drawing.Pen(System.Drawing.Color.LightCoral); this.blobFrames.Clear(); for (int i = 0; i < this.paths.paths.Count; i++) { Path p = this.paths.paths[i]; for (int j = 1; j < p.points.Count; j++) { if (i % 7 == 0) g.DrawLine(bluePen, p.points[j - 1], p.points[j]); else if (i % 7 == 1) g.DrawLine(greenPen, p.points[j - 1], p.points[j]); else if (i % 7 == 2) g.DrawLine(purplePen, p.points[j - 1], p.points[j]); else if (i % 7 == 3) g.DrawLine(redPen, p.points[j - 1], p.points[j]); else if (i % 7 == 4) g.DrawLine(radPen, p.points[j - 1], p.points[j]); else if (i % 7 == 5) g.DrawLine(medPen, p.points[j - 1], p.points[j]); else g.DrawLine(coralPen, p.points[j - 1], p.points[j]); } } bluePen.Dispose(); g.Dispose(); return this.noise_remover.BitmapSourceFromBitmap(blank); }