Help us understand the problem. What is going on with this article?

【Kinect V2】JointTypeのpositionをスムーズに取得する

昔作った資産をまたサルベージした

BodyFrameのPositionをColorFrameに変換して画像とかを動かす時に
Positionがガタガタになる問題を解決するために実装した。

ガタガタするのはなぜか

もはやかなりうろ覚えだがKinectV2はToF方式で計測されており
対象へ赤外線を照射し、それが反射してKinectに戻ってくる時間を元に位置情報を取得している。

このとき対象物に動きがあった場合、射出した赤外線がデバイスに戻ってこないことがあり
それが測定不能値としてPositionが欠損するためにガタガタしてしまう(だった気がする)

どうやって解消したか

生の値を使用すると欠損があった場合にPosition.x,y,zはNULLないし0となってしまうので
ここを補完する必要がある

なので位置情報のバッファを取っておいて前後の値で穴埋めすれば解決するはず、
という結論に達した。

以下ソース。
Queueを使用して位置データを保持するDictionaryに、指定した数の履歴を追加しておき
Dictionary内に保持されたPositionを平滑化する(平均値で動かす)
Smoothing関数にJointTypeとそのフレームにおけるPositionを渡せば
平滑化されたPositionが返却される。
今気づいたがz軸が考慮されてねぇ。

using System;
using System.Windows;
using System.Collections.Generic;
using Microsoft.Kinect;

namespace Microsoft.Samples.Kinect.BodyBasics
{
    class SmoothingPoint
    {
        private static Dictionary<JointType, Queue<Point>> pointBufferS = new Dictionary<JointType, Queue<Point>>();
        private static Dictionary<JointType, Queue<Point>> pointBufferE = new Dictionary<JointType, Queue<Point>>();

        public SmoothingPoint()
        {
            foreach (JointType jt in Enum.GetValues(typeof(JointType)))
            {
                pointBufferS.Add(jt, new Queue<Point>());
                pointBufferE.Add(jt, new Queue<Point>());
            }
        }

        public Point Smoothing(JointType jType, Point p)
        {
            return DoubleMovingAverage(jType, p);
        }

        private Point SimpleAverageFilter(JointType jt, Point newPoint, int parameter)
        {
            pointBufferS[jt].Enqueue(newPoint);
            if (pointBufferS[jt].Count <= parameter)
            {
                return newPoint;
            }
            pointBufferS[jt].Dequeue();
            Point[] list = pointBufferS[jt].ToArray();
            Point point = new Point();
            double x = 0;
            double y = 0;

            int n = pointBufferS[jt].Count;
            for (int i = 0; i < pointBufferS[jt].Count; i++)
            {
                Point p = list[i];
                x += p.X;
                y += p.Y;
            }
            point.X = x / n;
            point.Y = y / n;

            return point;
        }

        private Point DoubleMovingAverage(JointType jt, Point newPoint, int parameter = 5)
        {
            Point newSimpleAverage = SimpleAverageFilter(jt, newPoint, parameter);
            pointBufferE[jt].Enqueue(newSimpleAverage);
            if (pointBufferE[jt].Count <= parameter)
            {
                return newSimpleAverage;
            }
            pointBufferE[jt].Dequeue();
            Point[] list = pointBufferE[jt].ToArray();
            Point point = new Point();
            double x = 0;
            double y = 0;

            int n = pointBufferE[jt].Count;
            for (int i = 0; i < pointBufferE[jt].Count; i++)
            {
                Point p = list[i];
                x += p.X;
                y += p.Y;
            }
            point.X = x / n;
            point.Y = y / n;

            return point;
        }
    }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした