private void checkedListBoxBodyParts_ItemCheck(object sender, ItemCheckEventArgs e) { SkeletonJoint changedJoint = JointDictionary.GetTranslation((String)checkedListBoxBodyParts.Items[e.Index]).joint_type; chartErrors.Series[(String)checkedListBoxBodyParts.Items[e.Index]].Enabled = (e.NewValue == CheckState.Checked); foreach (Annotation annotation in annotations[changedJoint]) { annotation.Visible = e.NewValue == CheckState.Checked; } if (activeJoints.Contains(changedJoint)) { if (e.NewValue != CheckState.Checked) { activeJoints.Remove(changedJoint); } } else { if (e.NewValue == CheckState.Checked) { activeJoints.Add(changedJoint); } } OpenNIRecordingController video = (videoDataSource.Source as OpenNIRecordingController); if (video != null) { statistics.Calculate(getActiveJoints(), (double)mediaSliderConfidenceThreshold.Value * mediaSliderValueFactor, false, video.CurrentFrame); } }
/// <summary> /// Draws the skeleton if necessary. /// </summary> private void drawSkeletonAndLabels() { using (Graphics g = Graphics.FromImage(bitmap)) { if (UserLocationInformation.ContainsKey(CurrentFrame)) { foreach (int user in UserLocationInformation[CurrentFrame].Keys) { JointDictionary twoDPositions = Convert3Dto2D(UserLocationInformation[CurrentFrame][user], depthGenerator); if (shouldDrawSkeleton) { DrawSkeleton(g, ANTICOLORS[user % NCOLORS], twoDPositions, ConfidenceThreshold); } if (shouldPrintID) { Point3D com = twoDPositions[SkeletonJoint.Torso].Position; string label = "User " + user.ToString(); using (Brush brush = new SolidBrush(ANTICOLORS[user % NCOLORS])) { g.DrawString(label, font_label, brush, com.X - TextRenderer.MeasureText(label, font_label).Width / 2, com.Y); } } } if (AdditionalSkeletonIDs != null && AdditionalSkeletonInformation != null && shouldDrawSkeleton) { foreach (int user in AdditionalSkeletonIDs) { if (AdditionalSkeletonInformation.ContainsKey(CurrentFrame) && AdditionalSkeletonInformation[CurrentFrame].ContainsKey(user)) { JointDictionary twoDPositions; if (UserLocationInformation.Is3DData) { twoDPositions = Convert3Dto2D(AdditionalSkeletonInformation[CurrentFrame][user], depthGenerator); } else { twoDPositions = AdditionalSkeletonInformation[CurrentFrame][user]; } DrawSkeleton(g, COLORS[user % NCOLORS], twoDPositions, 0.0); } } } } } }
/// <summary> /// Loads all 3D joint positions for a specific user. /// </summary> /// <exception cref="ArgumentException">Thrown if the target dictionary /// does not contain 3d data.</exception> protected void GetJoints3D(SkeletonCapability source, int user, JointDictionary target) { if (!target.Is3DData) { throw new ArgumentException("Trying to load 3d data to a non 3D JointDictionary."); } for (int i = 0; i < JointDictionary.JointTranslationList.Count; i++) { GetJoint3D(source, user, JointDictionary.JointTranslationList[i].joint_type, target); } }
private void clearErrorPoints() { foreach (Series series in chartErrors.Series) { series.Points.Clear(); List <Annotation> remove_list = annotations[JointDictionary.GetTranslation(series.Name).joint_type]; foreach (Annotation annotation in remove_list) { chartErrors.Annotations.Remove(annotation); annotation.Dispose(); } remove_list.Clear(); } }
/// <summary> /// Loads the 3D data for a specific skeleton joint. /// </summary> private void GetJoint3D(SkeletonCapability source, int user, SkeletonJoint joint, JointDictionary target) { SkeletonJointPosition pos; if (joint == SkeletonJoint.Waist) { // Calculate the joint position as arithmetic mean of right // and left hip joints, as it is not possible to poll it // directly. pos = new SkeletonJointPosition(); SkeletonJointPosition posLeft = source.GetSkeletonJointPosition(user, SkeletonJoint.LeftHip); SkeletonJointPosition posRight = source.GetSkeletonJointPosition(user, SkeletonJoint.RightHip); if (posLeft.Position.Z == 0 || posRight.Position.Z == 0) { pos.Confidence = 0; pos.Position = new Point3D( (posLeft.Position.X + posRight.Position.X) / 2, (posLeft.Position.Y + posRight.Position.Y) / 2, 0); } else { pos.Confidence = Math.Min(posLeft.Confidence, posRight.Confidence); pos.Position = new Point3D( (posLeft.Position.X + posRight.Position.X) / 2, (posLeft.Position.Y + posRight.Position.Y) / 2, (posLeft.Position.Z + posRight.Position.Z) / 2); } } else { pos = source.GetSkeletonJointPosition(user, joint); if (pos.Position.Z == 0) { pos.Confidence = 0; } } target[joint] = pos; }
/// <summary> /// Converts a JointDictionary with 3D data to the corresponding one /// with 2D data. Note that the Z-Coordinate is left unchanged, though /// it has no meaning in the resulting 2D space and can be seen as 0. /// </summary> public JointDictionary Convert3Dto2D(JointDictionary source, DepthGenerator generator) { if (!source.Is3DData) { return(new JointDictionary(source)); } else { JointDictionary ret = new JointDictionary(false); foreach (SkeletonJoint joint in source.Keys) { SkeletonJointPosition pos = new SkeletonJointPosition(); pos.Confidence = source[joint].Confidence; pos.Position = generator.ConvertRealWorldToProjective(source[joint].Position); ret.Add(joint, pos); } return(ret); } }
public JointDictionary(JointDictionary original) : base(original) { _is3DData = original.Is3DData; }
/// <summary> /// Draws the currently available user information /// (ID, tracking status) on the Image. If recording, this method /// also writes the user joints to the log-datastructure. /// </summary> private void drawAndLogUserInformation() { using (Graphics g = Graphics.FromImage(bitmap)) { int[] users = this.userGenerator.GetUsers(); if (recording) { movementData.Add(movementData.Keys.Count, new Dictionary <int, JointDictionary>()); } foreach (int user in users) { if (shouldPrintID) { Point3D com = this.userGenerator.GetCoM(user); com = depthGenerator.ConvertRealWorldToProjective(com); string label = ""; if (!this.shouldPrintState) { label += user; } else if (skeletonCapability.IsTracking(user)) { label += user + " - Tracking"; } else if (skeletonCapability.IsCalibrating(user)) { label += user + " - Calibrating..."; } else { label += user + " - Looking for pose"; } using (Brush brush = new SolidBrush(ANTICOLORS[user % NCOLORS])) { g.DrawString(label, font_label, brush, com.X - TextRenderer.MeasureText(label, font_label).Width / 2, com.Y); } } if ((shouldDrawSkeleton || recording) && skeletonCapability.IsTracking(user)) { GetJoints(skeletonCapability, user, joints); if (recording) { JointDictionary threeDPositions = new JointDictionary(true); GetJoints3D(skeletonCapability, user, threeDPositions); movementData[movementData.Keys.Count - 1]. Add(user, threeDPositions); } if (shouldDrawSkeleton) { DrawSkeleton(g, ANTICOLORS[user % NCOLORS], joints, 0.5f); } } } } }
/// <summary> /// Sets the data for the statistics object. The statistic values /// are calculated in this method. The results and truth dictionaries /// must contain at least a key for every frame between minimal and /// maximal frame number. /// </summary> /// <param name="truth">The ground truth dictionary.</param> /// <param name="results">The result dictionary.</param> /// <param name="truth_id">The id of the user to compare to as truth in /// the truth data ids.</param> /// <param name="results_id">The id of the result user to compare with /// in the result data ids.</param> /// <param name="converter">A function to convert 3d data to 2d data /// if necessary.</param> /// <exception cref="Exception">Thrown if the frames are not continuous /// from first to last.</exception> internal void SetData(ImageDictionary truth, ImageDictionary results, int truth_id, int results_id, To2DConverter converter) { // Reset. GlobalMean = 0.0; FrameMean = 0.0; FrameValue = 0.0; NumberOfPoints = 0; first_frame = int.MaxValue; last_frame = -1; isInBatchMode = false; errors = new Dictionary <SkeletonJoint, List <DifferenceData> >(); foreach (JointTranslationTuple translation in JointDictionary.JointTranslationList) { errors.Add(translation.joint_type, new List <DifferenceData>()); } resultDict = results; truthDict = truth; work_in_3D = results.Is3DData; if (work_in_3D && !truth.Is3DData) { throw new ArgumentException("Trying to compare data with insufficient information."); } // Check converter availability if necessary if (!resultDict.Is3DData && truth.Is3DData && converter == null) { throw new ArgumentException("Must convert data to 2D, but no converter was specified."); } // Start calculating data. foreach (int frame in results.Keys) { if (frame < first_frame) { first_frame = frame; } if (frame > last_frame) { last_frame = frame; } // Convert the data if necessary JointDictionary frame_data_truth = new JointDictionary(work_in_3D); JointDictionary frame_data_results = new JointDictionary(work_in_3D); bool user_in_truth = false; bool user_in_results = false; if (results[frame].ContainsKey(results_id)) { user_in_results = true; if (results.Is3DData && !work_in_3D) { frame_data_results = converter(results[frame][results_id]); } else { frame_data_results = results[frame][results_id]; } } if (truth[frame].ContainsKey(truth_id)) { user_in_truth = true; if (truth.Is3DData && !work_in_3D) { frame_data_truth = converter(truth[frame][truth_id]); } else { frame_data_truth = truth[frame][truth_id]; } } foreach (SkeletonJoint joint in errors.Keys) { DifferenceData data = new DifferenceData(); data.frame = frame; data.Difference = double.NaN; Point3D resultsPoint = new Point3D(), truthPoint = new Point3D(); if (user_in_results && frame_data_results.ContainsKey(joint)) { data.inResultData = true; resultsPoint = frame_data_results[joint].Position; } if (user_in_truth && frame_data_truth.ContainsKey(joint)) { data.inTruthData = true; data.Confidence = frame_data_truth[joint].Confidence; truthPoint = frame_data_truth[joint].Position; } if (data.inTruthData && data.inResultData) { if (work_in_3D) { data.Difference = Math.Sqrt( Math.Pow(truthPoint.X - resultsPoint.X, 2.0) + Math.Pow(truthPoint.Y - resultsPoint.Y, 2.0) + Math.Pow(truthPoint.Z - resultsPoint.Z, 2.0)); } else { data.Difference = Math.Sqrt( Math.Pow(truthPoint.X - resultsPoint.X, 2.0) + Math.Pow(truthPoint.Y - resultsPoint.Y, 2.0)); } } int position = 0; List <DifferenceData> to_insert_in = errors[joint]; for (int i = 0; i < to_insert_in.Count; i++) { if (frame > to_insert_in[i].frame) { break; } else { position++; } } errors[joint].Add(data); } } // Check that list is complete!!! int range = last_frame - first_frame + 1; bool failed = false; foreach (SkeletonJoint joint in errors.Keys) { if (errors[joint].Count != range) { failed = true; break; } } if (failed) { errors.Clear(); throw new Exception("The algorithm results did not contain every " + "frame from the first to the last."); } }
private void addErrorPoint(SkeletonJoint series, int x, double y, Statistics.MarkerType markerType) { String seriesName = JointDictionary.GetTranslation(series).name; DataPoint newPoint = new DataPoint(x, y); if (markerType == Statistics.MarkerType.FalseNegative) { EllipseAnnotation marker = new EllipseAnnotation(); marker.AnchorDataPoint = newPoint; marker.AnchorAlignment = ContentAlignment.MiddleCenter; marker.Width = 0.8; marker.Height = 1.6; marker.BackColor = markerColorFalsePositive; marker.LineColor = Color.Black; marker.LineWidth = 1; AnnotationSmartLabelStyle markerLocation = new AnnotationSmartLabelStyle(); markerLocation.IsMarkerOverlappingAllowed = true; markerLocation.IsOverlappedHidden = false; markerLocation.MaxMovingDistance = 0; markerLocation.MinMovingDistance = 0; marker.SmartLabelStyle = markerLocation; chartErrors.Annotations.Add(marker); annotations[series].Add(marker); } if (markerType == Statistics.MarkerType.FalsePositive) { RectangleAnnotation marker = new RectangleAnnotation(); marker.AnchorDataPoint = newPoint; marker.AnchorAlignment = ContentAlignment.MiddleCenter; marker.Width = 0.8; marker.Height = 1.6; marker.BackColor = markerColorFalseNegative; marker.LineColor = Color.Black; marker.LineWidth = 1; AnnotationSmartLabelStyle markerLocation = new AnnotationSmartLabelStyle(); markerLocation.IsMarkerOverlappingAllowed = true; markerLocation.IsOverlappedHidden = false; markerLocation.MaxMovingDistance = 0; markerLocation.MinMovingDistance = 0; marker.SmartLabelStyle = markerLocation; chartErrors.Annotations.Add(marker); annotations[series].Add(marker); } if (markerType == Statistics.MarkerType.NotAvailable) { EllipseAnnotation marker = new EllipseAnnotation(); marker.AnchorDataPoint = newPoint; marker.AnchorAlignment = ContentAlignment.MiddleCenter; marker.Width = 0.8; marker.Height = 1.6; marker.BackColor = markerColorNA; marker.LineColor = Color.Black; marker.LineWidth = 1; AnnotationSmartLabelStyle markerLocation = new AnnotationSmartLabelStyle(); markerLocation.IsMarkerOverlappingAllowed = true; markerLocation.IsOverlappedHidden = false; markerLocation.MaxMovingDistance = 0; markerLocation.MinMovingDistance = 0; marker.SmartLabelStyle = markerLocation; chartErrors.Annotations.Add(marker); annotations[series].Add(marker); } Series insertionSeries = chartErrors.Series[seriesName]; int insertion_index = 0; for (int index = 0; index < insertionSeries.Points.Count; index++) { if (insertionSeries.Points[index].XValue > x) { break; } else { insertion_index++; } } chartErrors.Series[seriesName].Points.Insert(insertion_index, newPoint); }
/// <summary> /// Converts a JointDictionary with 3D data to the corresponding one /// with 2D data. Note that the Z-Coordinate is left unchanged, though /// it has no meaning in the resulting 2D space and can be seen as 0. /// </summary> public JointDictionary Convert3Dto2D(JointDictionary source) { return(base.Convert3Dto2D(source, depthGenerator)); }