/// <summary>
        /// Raises the corresponding event.
        /// </summary>
        private void onExportFinished(object parameter)
        {
            object[] parameters = parameter as object[];
            OpenNIRecordingController sender    = parameters[0] as OpenNIRecordingController;
            DirectoryInfo             exportDir = parameters[1] as DirectoryInfo;
            List <int>      frames  = parameters[2] as List <int>;
            List <int>      userIDs = parameters[3] as List <int>;
            ImageDictionary exported_file_information2D = parameters[4] as ImageDictionary;
            ImageDictionary exported_file_information3D = parameters[5] as ImageDictionary;
            bool            ExportRelativePathNames     = (bool)parameters[6];
            String          export_filename_suffix      = parameters[7] as String;


            if (exportThread != null && exportThread.IsAlive)
            {
                exportThread.Join();
            }

            if (ExportFinished != null)
            {
                ExportFinished(sender, exportDir, frames, userIDs,
                               exported_file_information2D,
                               exported_file_information3D,
                               ExportRelativePathNames, export_filename_suffix);
            }
        }
        /// <summary>
        /// Starts to record the current stream. The stream must have been
        /// initialized when calling this method by using the method
        /// <see cref="StartGenerating"/>.
        /// </summary>
        /// <param name="captureFolder">The folder to create to recording in.</param>
        /// <param name="SaveUserPosition">Whether to record the user position
        /// in a separate file.</param>
        /// <exception cref="Exception">Thrown if initialization of the recording
        /// fails.</exception>
        internal void StartRecording(DirectoryInfo captureFolder, bool SaveUserPosition)
        {
            lock (RUN_CONTROL_LOCK)
            {
                if (!shouldRun || recording)
                {
                    return;
                }
                else
                {
                    // Change display options to get possibly smooth
                    // recording.W
                    shouldDrawBackground = true;
                    shouldDrawHighlight  = false;
                    shouldDrawPixels     = false;
                    shouldDrawSkeleton   = true;

                    // Setup datastructures for recording.
                    movementData = new ImageDictionary(true);
                    if (SaveUserPosition)
                    {
                        Stream file_stream = new FileStream(
                            Path.Combine(captureFolder.FullName, MAP_FILE_NAME), FileMode.Create);
                        Stream write_stream;
                        if (COMPRESS_USER_DATA)
                        {
                            write_stream = file_stream;
                        }
                        else
                        {
                            write_stream = file_stream;
                        }
                        // A writer for the user data file.
                        userInformationWriter = new BinaryWriter(write_stream);
                    }


                    lock (HARDWARELOCK)
                    {
                        recorder = new Recorder(context);
                        recorder.SetDestination(RecordMedium.File,
                                                Path.Combine(captureFolder.FullName, ONI_FILE_NAME));
                        recorder.AddNodeToRecording(imageGenerator);
                        recorder.AddNodeToRecording(depthGenerator);
                    }

                    FileInfo movementDataFileInfo = new FileInfo(
                        Path.Combine(captureFolder.FullName,
                                     USER_ANNOTATION_FILENAME));
                    movementDataFileName = movementDataFileInfo.FullName;
                }
                recording = true;
                onStartedRecording();
            }
        }
        private void listBoxResultDataSets_SelectedIndexChanged(object sender, EventArgs e)
        {
            listBoxUserResults.ClearSelected();
            listBoxUserResults.Items.Clear();
            onEvaluationRangeChanged(-1, -1);
            OpenNIRecordingController source = (videoDataSource.Source as OpenNIRecordingController);

            if (source != null)
            {
                source.AdditionalSkeletonInformation = null;
                source.AdditionalSkeletonIDs.Clear();
                source.RequestUpdate(true);
            }

            if (listBoxResultDataSets.SelectedItem == null)
            {
                listBoxUserResults.Enabled = false;
            }
            else
            {
                String resultfilename = Path.Combine(current_take_dir.FullName, (String)listBoxResultDataSets.SelectedItem);
                try
                {
                    using (FileStream file = File.Open(resultfilename, FileMode.Open))
                    {
                        resultDictionary = (ImageDictionary)movementDataSerializer.Deserialize(file);
                    }
                    Dictionary <int, int> userActivities = resultDictionary.GetUserStatistics(null);
                    foreach (int userID in userActivities.Keys)
                    {
                        listBoxUserResults.Items.Add("User " + userID);
                    }

                    if (source != null)
                    {
                        source.AdditionalSkeletonInformation = resultDictionary;
                        onEvaluationRangeChanged(resultDictionary.Keys.Min(),
                                                 resultDictionary.Keys.Max());
                    }

                    listBoxUserResults.Enabled = true;
                }
                catch (Exception ex)
                {
                    listBoxUserResults.ClearSelected();
                    listBoxUserResults.Items.Clear();
                    listBoxUserResults.Enabled = false;
                    MessageBox.Show(this,
                                    "An Error occured loading the results file:\n" + ex.Message,
                                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Reports success and tries to generate data index file.
        /// </summary>
        private void exportFinished(
            OpenNIRecordingController sender,
            DirectoryInfo exportDir, List <int> frames, List <int> userIDs,
            ImageDictionary exportedFiles2D,
            ImageDictionary exportedFiles3D, bool ExportRelativePathNames,
            String export_filename_suffix)
        {
            // Report success.
            lazyInvoke((MethodInvoker) delegate
            {
                exportForm.textBoxProgress.Text =
                    "Exporting images finished. Generating data index file...";
            });


            try
            {
                if (exportedFiles2D != null)
                {
                    using (FileStream write_to = File.OpenWrite(
                               Path.Combine(exportDir.FullName, "Export2D" + export_filename_suffix + ".xml")))
                    {
                        movementDataSerializer.Serialize(write_to, exportedFiles2D);
                    }
                }
                if (exportedFiles3D != null)
                {
                    using (FileStream write_to = File.OpenWrite(
                               Path.Combine(exportDir.FullName, "Export3D" + export_filename_suffix + ".xml")))
                    {
                        movementDataSerializer.Serialize(write_to, exportedFiles3D);
                    }
                }
            }
            catch (Exception e)
            {
                showException("Error creating data index file: \n" +
                              e.Message);
            }

            // Report success.
            lazyInvoke((MethodInvoker) delegate
            {
                exportForm.Hide();
                textBoxExport.Text = "Last export successful to folder " + exportDir.FullName;
            });

            sender.ResetExportEventHandlers();
        }
        /// <summary>
        /// Creates a new control instance with a recording as data
        /// source. The current image data can be obtained by the
        /// <see cref="Image"/>-property. The
        /// <see cref="NewImageDataAvailable"/> event informs about when the
        /// data is updated, the <see cref="ErrorOccured"/>-event about
        /// errors.
        /// </summary>
        /// <exception cref="System.Exception">Thrown if the stream could not
        /// be initialized properly.</exception>
        public OpenNIRecordingController(String recording_filename,
                                         String movementDataFileName, String userAnnotationFilename)
        {
            // Create a new context and the data-generating nodes.
            context = new Context();
            context.OpenFileRecording(recording_filename);
            this.recording_filename = recording_filename;

            _userInformationReader = new BinaryReader(
                new FileStream(movementDataFileName, FileMode.Open));

            using (FileStream annotation_stream = File.OpenRead(userAnnotationFilename))
            {
                _userLocationInformation = (ImageDictionary)movementDataSerializer.Deserialize(annotation_stream);
            }

            // Image
            imageGenerator = (ImageGenerator)context.FindExistingNode(NodeType.Image);

            // Depth
            depthGenerator = (DepthGenerator)context.FindExistingNode(NodeType.Depth);
            histogram      = new int[depthGenerator.DeviceMaxDepth];

            // Player
            player = (Player)context.FindExistingNode(NodeType.Player);
            player.PlaybackSpeed = 1.0;

            if (depthGenerator == null || imageGenerator == null || player == null)
            {
                throw new Exception("Could not initialize recording stream.");
            }

            // Error handling
            context.ErrorStateChanged += context_ErrorStateChanged;
            context.StartGeneratingAll();
        }
        /// <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.");
            }
        }
        /// <summary>
        /// The export logic.
        /// </summary>
        /// <param name="parameter">An object[] with the real parameters.
        /// Have a look at <see cref="ExportFrames"/> for a usage
        /// example.</param>
        private void doExport(object parameter)
        {
            object[] parameters = parameter as object[];
            if (parameters == null)
            {
                return;
            }

            // Export directory
            DirectoryInfo exportDir = parameters[10] as DirectoryInfo;

            if (exportDir == null)
            {
                return;
            }

            // Frame list
            List <int> frames = parameters[0] as List <int>;

            if (frames == null || frames.Count == 0)
            {
                return;
            }
            frames.Sort();

            // User list
            List <int> userIDs = parameters[1] as List <int>;

            if (userIDs == null)
            {
                return;
            }

            // Ignore List
            List <int> formerIgnoreList = new List <int>(UsersToIgnore);

            UsersToIgnore.Clear();
            List <int> occuringUsers = GetUserStatistics(frames).Keys.ToList <int>();

            foreach (int user in occuringUsers)
            {
                if (!userIDs.Contains(user))
                {
                    UsersToIgnore.Add(user);
                }
            }

            // The rest of parameters
            bool AnnotationsIn2D         = (bool)parameters[2];
            bool AnnotationsIn3D         = (bool)parameters[3];
            bool ExportRelativePathNames = (bool)parameters[4];
            bool ImageOrDepth            = (bool)parameters[5];
            bool DrawBackground          = (bool)parameters[6];
            bool DrawSkeleton            = (bool)parameters[7];
            bool DrawHighlights          = (bool)parameters[8];
            bool DrawLabels = (bool)parameters[9];

            // Number format
            int max = frames[frames.Count - 1];
            int characters;

            if (max == 0)
            {
                characters = 1;
            }
            else
            {
                characters = (int)Math.Ceiling(Math.Log10(max));
            }
            String exportFormatString = "d" + characters;

            // The export xml files.
            ImageDictionary exportedIndex2D = new ImageDictionary(false);

            exportedIndex2D.XmlExportFrameFileList = new Dictionary <int, string>();
            exportedIndex2D.XmlOmitPoints          = (userIDs.Count == 0);

            ImageDictionary exportedIndex3D = new ImageDictionary(true);

            exportedIndex3D.XmlExportFrameFileList = new Dictionary <int, string>();
            exportedIndex3D.XmlOmitPoints          = (userIDs.Count == 0);

            String filename;
            String export_filename_suffix = "";

            lock (RUN_CONTROL_LOCK)
            {
                try
                {
                    StopPlayback();

                    lock (EXPORT_LOCK)
                    {
                        // Configure for export
                        DrawSkeletonMesh         = DrawSkeleton;
                        DrawSensorData           = true;
                        this.ImageOrDepth        = ImageOrDepth;
                        this.DrawBackground      = DrawBackground;
                        this.DrawUserHighlight   = DrawHighlights;
                        this.DrawUserInformation = DrawLabels;

                        if (DrawSkeleton)
                        {
                            export_filename_suffix += "s";
                        }
                        if (!DrawSensorData)
                        {
                            export_filename_suffix += "a";
                        }
                        if (!ImageOrDepth)
                        {
                            export_filename_suffix += "d";
                        }
                        if (!DrawBackground)
                        {
                            export_filename_suffix += "b";
                        }
                        if (DrawUserHighlight)
                        {
                            export_filename_suffix += "h";
                        }
                        if (DrawUserInformation)
                        {
                            export_filename_suffix += "l";
                        }

                        if (export_filename_suffix.Length > 0)
                        {
                            export_filename_suffix = "-" + export_filename_suffix;
                        }

                        for (int frameIndex = 0; frameIndex < frames.Count; frameIndex++)
                        {
                            SeekFrame(frames[frameIndex]);
                            RequestUpdate(false);
                            String relative_filename = frames[frameIndex].ToString(exportFormatString) +
                                                       export_filename_suffix + ".png";
                            filename = Path.Combine(exportDir.FullName,
                                                    relative_filename);


                            lock (ImageLock)
                            {
                                bitmap.Save(filename, ImageFormat.Png);
                            }

                            // Get the user positions in this frame
                            Dictionary <int, JointDictionary> frame_positions2D =
                                new Dictionary <int, JointDictionary>();
                            Dictionary <int, JointDictionary> frame_positions3D =
                                new Dictionary <int, JointDictionary>();
                            if (UserLocationInformation.ContainsKey(frames[frameIndex]))
                            {
                                foreach (int user in UserLocationInformation[frames[frameIndex]].Keys)
                                {
                                    if (userIDs.Contains(user))
                                    {
                                        frame_positions3D.Add(user, new JointDictionary(
                                                                  UserLocationInformation[frames[frameIndex]][user]));
                                        frame_positions2D.Add(user, new JointDictionary(
                                                                  Convert3Dto2D(UserLocationInformation[frames[frameIndex]][user], depthGenerator)));
                                    }
                                }
                            }
                            exportedIndex2D.Add(frames[frameIndex], frame_positions2D);
                            if (!ExportRelativePathNames)
                            {
                                exportedIndex2D.XmlExportFrameFileList.Add(
                                    frames[frameIndex], filename);
                            }
                            else
                            {
                                exportedIndex2D.XmlExportFrameFileList.Add(
                                    frames[frameIndex], relative_filename);
                            }
                            exportedIndex3D.Add(frames[frameIndex], frame_positions3D);
                            if (!ExportRelativePathNames)
                            {
                                exportedIndex3D.XmlExportFrameFileList.Add(
                                    frames[frameIndex], filename);
                            }
                            else
                            {
                                exportedIndex3D.XmlExportFrameFileList.Add(
                                    frames[frameIndex], relative_filename);
                            }


                            onExportMadeProgress(
                                (float)(frameIndex + 1) / (float)frames.Count * 100, frameIndex + 1, frames.Count);
                            if (export_cancelled)
                            {
                                return;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    onExportFailed(e.Message);
                    return;
                }

                // Reset ignore list
                UsersToIgnore.Clear();
                UsersToIgnore.AddRange(formerIgnoreList);

                if (!AnnotationsIn2D)
                {
                    exportedIndex2D = null;
                }
                if (!AnnotationsIn3D)
                {
                    exportedIndex3D = null;
                }
            }

            // Report success.
            Thread reporter = new Thread(onExportFinished);

            reporter.Start(new object[] { this, exportDir, frames, userIDs,
                                          exportedIndex2D, exportedIndex3D, ExportRelativePathNames,
                                          export_filename_suffix });
        }
예제 #8
0
        /// <summary>
        /// Reconfigures the exporting parameters and starts the second part
        /// of the batch export.
        /// </summary>
        private void batchExportPart1Finished(
            OpenNIRecordingController sender,
            DirectoryInfo exportDir, List <int> frames, List <int> userIDs,
            ImageDictionary exportedFiles2D,
            ImageDictionary exportedFiles3D, bool ExportRelativePathNames,
            String export_filename_suffix)
        {
            // Report success.
            lazyInvoke((MethodInvoker) delegate
            {
                exportForm.textBoxProgress.Text =
                    "Exporting standard images finished (Batch export part 1)." +
                    "Generating data index file...";
            });


            try
            {
                if (exportedFiles2D != null)
                {
                    using (FileStream write_to = File.OpenWrite(
                               Path.Combine(exportDir.FullName, "Export2D" + export_filename_suffix + ".xml")))
                    {
                        movementDataSerializer.Serialize(write_to, exportedFiles2D);
                    }
                }
                if (exportedFiles3D != null)
                {
                    using (FileStream write_to = File.OpenWrite(
                               Path.Combine(exportDir.FullName, "Export3D" + export_filename_suffix + ".xml")))
                    {
                        movementDataSerializer.Serialize(write_to, exportedFiles3D);
                    }
                }
            }
            catch (Exception e)
            {
                showException("Error creating data index file: \n" +
                              e.Message);
            }

            // Configure for the second export.
            // Check whether the user selected to do a batch export.
            OpenNIRecordingController exportVideo = sender;

            exportVideo.ExportFinished -= batchExportPart1Finished;
            exportVideo.ExportFinished += batchExportPart2Finished;

            // Reset progress bar.
            lazyInvoke((MethodInvoker) delegate
            {
                exportForm.progressBar.Value    = 0;
                exportForm.textBoxProgress.Text = "Initializing batch export part 2...";
            });

            // Begin exporting.
            exportVideo.ExportFrames(
                frames,
                userIDs,
                (exportedFiles2D != null),
                (exportedFiles3D != null),
                ExportRelativePathNames,
                true, true, true, false, false,
                exportDir);
        }