コード例 #1
0
ファイル: Session.cs プロジェクト: shayan-taheri/Jackknife
        /**
         * Load a participant's dataset and session.
         * Train the recognizer with the training data
         * and run the video through. See what happens...
         */
        public static ConfusionMatrices evaluate_session(DeviceType device, int subject_id)
        {
            // Load up the training dataset.
            Dataset ds = load_subject_dataset(
                device,
                subject_id);

            // Load up the session.
            List <Frame> frames = new List <Frame>();

            load_session(
                device,
                subject_id,
                frames);

            // Create a new recognizer.
            JackknifeBlades blades = new JackknifeBlades();

            blades.SetIPDefaults();
            Jackknife jk = new Jackknife(blades);

            // Train the recognizer, without 'bad' gestures.
            for (int ii = 0;
                 ii < ds.Samples.Count;
                 ii++)
            {
                int    gesture_id   = ds.Samples[ii].GestureId;
                string gesture_name = ds.Gestures[gesture_id];
                if (bad_gesture(gesture_name))
                {
                    continue;
                }
                jk.AddTemplate(ds.Samples[ii]);
            }


            // Get device and application parameters
            // based on the device type.
            configuartion_parameters_t parameters = new configuartion_parameters_t(device);

            // We originally used n=4, r=2 for Kinect data
            // and n=6, r=2 for Leap Motion data, but
            // here we just set the average. There is barely
            // any effect on the results.
            jk.Train(6, 2, 1.00);

            // Play session video through
            // the recognizer.
            List <Vector>         buffer     = new List <Vector>();
            List <int>            detections = new List <int>();
            List <CommandResults> cmds       = new List <CommandResults>();
            int last_cmd_id = -1;
            int next_update = parameters.update_interval;

            int frame_no = 0;

            ExponentialMovingAverage filter = new ExponentialMovingAverage(frames[0].pt);
            Vector pt;

            for (int ii = 0;
                 ii < frames.Count;
                 ii++)
            {
                // skip this frame if its bad
                if (frames[ii].bad_pt)
                {
                    continue;
                }

                // Low pass filter the input.
                // Note, we originally didn't smooth the data,
                // so results now are a little higher than in
                // the paper.
                pt = filter.Filter(
                    frames[ii].pt,
                    1 / (double)parameters.fps);

                //pt = frames[ii].pt;

                frame_no += 1;

                // start a new command
                if (frames[ii].cmd_id != last_cmd_id)
                {
                    last_cmd_id = frames[ii].cmd_id;

                    int gid = convert_gesture_id(
                        ds,
                        frames[ii].gesture_id);

                    CommandResults cmd = new CommandResults(
                        frames[ii].cmd_id,
                        gid);

                    if (bad_gesture(frames[ii].gesture_id))
                    {
                        cmd.ignore = true;
                    }

                    cmds.Add(cmd);
                }

                // This buffering approach is really
                // inefficient, but since this off-line,
                // performance is not important.
                buffer.Add(pt);
                if (buffer.Count > parameters.sliding_window_frame_cnt)
                {
                    buffer.RemoveAt(0);
                }

                // We need to have a couple points before
                // calling the recognizer.
                if (buffer.Count < 2)
                {
                    continue;
                }

                // Wait a few frames again before trying
                // to recognize again.
                if (frame_no < next_update)
                {
                    continue;
                }

                next_update = frame_no + parameters.update_interval;

                // Run the recognizer.
                int gesture_id = jk.Classify(buffer);

                // Add recognition result.
                detections.Add(gesture_id);
                if (detections.Count > parameters.repeat_cnt)
                {
                    detections.RemoveAt(0);
                }

                // Count how many times this gesture was recognized.
                int winner_cnt = 0;
                for (int jj = 0;
                     jj < detections.Count;
                     jj++)
                {
                    if (detections[jj] == gesture_id)
                    {
                        winner_cnt += 1;
                    }
                }

                // Ensure we have enough recognitions.
                if (winner_cnt < parameters.repeat_cnt)
                {
                    continue;
                }

                // If nothing was detected, skip rest.
                if (gesture_id == -1)
                {
                    continue;
                }

                // Hurray! A gesture is recognized!
                // Hopefully it's the right one too!!
                cmds[cmds.Count - 1].add(gesture_id);
                detections.Clear();
                buffer.Clear();
            }

            // Mark bad commands, situations where the participant
            // made a mistake or tracking was lost. We know the
            // command was bad because the protector asked the
            // participant to repeat the gesture, but a new command
            // ID is assigned to the sequence.
            for (int ii = 1;
                 ii < cmds.Count;
                 ii++)
            {
                if (cmds[ii].expected_id == cmds[ii - 1].expected_id)
                {
                    CommandResults temp = cmds[ii - 1];
                    temp.ignore  = true;
                    cmds[ii - 1] = temp;
                }
            }

            // Put all results in confusion matrices.
            ConfusionMatrices ret = new ConfusionMatrices(ds);

            for (int ii = 0; ii < cmds.Count; ii++)
            {
                if (cmds[ii].ignore)
                {
                    continue;
                }

                cmds[ii].update_confusion_matrices(ret);
            }

            return(ret);
        }