

kinectのfacetrackを使ってまばたきを検出したいのですが、前処理として画像のトリミング(目の周辺部分)を行わなければならないと思うのですが、トリミング処理がうまく行きませんがうまくいきません。良い方法はありますでしょうか？使っている言語はC#です。どうかよろしくお願いします。

[code]

    using System;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Collections.Generic;
    using System.Linq;
    
    
    using Microsoft.Kinect;
    using Microsoft.Kinect.Toolkit;
    using Microsoft.Kinect.Toolkit.FaceTracking;
    
    namespace FaceTrackingCamera
    {
        /// <summary>
        /// MainWindow.xaml の相互作用ロジック
        /// </summary>
        public partial class MainWindow : Window
        {
            // 解像度・フレームレート
            private ColorImageFormat rgbFormat = ColorImageFormat.RgbResolution640x480Fps30;
            private const DepthImageFormat depthFormat = DepthImageFormat.Resolution320x240Fps30;
    
            // KinectSensorChooser
            private KinectSensorChooser kinectChooser = new KinectSensorChooser();
    
            // FaceTrackerオブジェクト
            FaceTracker faceTracker = null;
    
            // Kinectセンサーからの画像情報を受け取るバッファ
            private byte[] pixelBuffer = null;
    
            // Kinectセンサーからの深度情報を受け取るバッファ
            private short[] depthBuffer = null;
    
            // Kinectセンサーからの骨格情報を受け取るバッファ
            private Skeleton[] skeletonBuffer = null;
    
            // 画面に表示するビットマップ
            private RenderTargetBitmap bmpBuffer = null;
    
            // ビットマップへの描画用DrawingVisual
            private DrawingVisual drawVisual = new DrawingVisual();
    
    
    
            private WriteableBitmap bgImg2 = null;
            private Int32Rect rectimg;
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            // 初期化処理(Kinectセンサーやバッファ類の初期化)
            private void WindowLoaded(object sender, RoutedEventArgs e)
            {
                kinectChooser.KinectChanged += KinectChanged;
                kinectChooser.Start();
            }
    
            // 終了処理
            private void WindowClosed(object sender, EventArgs e)
            {
                kinectChooser.Stop();
            }
    
            // Kinectセンサーの挿抜イベントに対し、初期化/終了処理を呼び出す
            private void KinectChanged(object sender, KinectChangedEventArgs args)
            {
                if (args.OldSensor != null)
                    UninitKinectSensor(args.OldSensor);
    
                if (args.NewSensor != null)
                    InitKinectSensor(args.NewSensor);
            }
    
            // Kinectセンサーの初期化
            private void InitKinectSensor(KinectSensor kinect)
            {
                // ストリームの有効化
                ColorImageStream clrStream = kinect.ColorStream;
                clrStream.Enable(rgbFormat);
    
                DepthImageStream depthStream = kinect.DepthStream;
                depthStream.Enable(depthFormat);
    
                SkeletonStream skelStream = kinect.SkeletonStream;
                kinect.DepthStream.Range = DepthRange.Near;
    
                skelStream.EnableTrackingInNearRange = true;
                skelStream.TrackingMode = SkeletonTrackingMode.Seated;
                skelStream.Enable();
    
                // バッファの初期化
                pixelBuffer = new byte[clrStream.FramePixelDataLength];
                depthBuffer = new short[depthStream.FramePixelDataLength];
                skeletonBuffer = new Skeleton[skelStream.FrameSkeletonArrayLength];
    
                // 画面に表示するビットマップの初期化
                bmpBuffer = new RenderTargetBitmap(clrStream.FrameWidth,clrStream.FrameHeight,96, 96, PixelFormats.Default);
                bgImg2 = new WriteableBitmap(clrStream.FrameWidth, clrStream.FrameHeight, 96, 96, PixelFormats.Bgr32, null);
    
    
    
                // イベントハンドラの登録
                kinect.AllFramesReady += AllFramesReady;
    
                faceTracker = new FaceTracker(kinect);
    
                rectimg = new Int32Rect(0, 0, clrStream.FrameWidth, clrStream.FrameHeight);        
            }
    
            // Kinectセンサーの終了処理
            private void UninitKinectSensor(KinectSensor kinect)
            {
                if (faceTracker != null)
                {
                    faceTracker.Dispose();
                    faceTracker = null;
                }
                kinect.AllFramesReady -= AllFramesReady;
            }
    
            // FrameReady イベントのハンドラ
            // (Kinectセンサーの情報をもとにFaceTrackingを行い、
            //  認識した顔の各点に赤い点を描画)
            private void AllFramesReady(object sender, AllFramesReadyEventArgs e)
            {
                KinectSensor kinect = sender as KinectSensor;
    
                using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame())
                using (DepthImageFrame depthImageFrame = e.OpenDepthImageFrame())
                using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
                {
                    if (colorImageFrame == null || depthImageFrame == null || skeletonFrame == null)
                        return;
    
                    // 顔の各点の座標を保持するバッファ
                    EnumIndexableCollection<FeaturePoint, Microsoft.Kinect.Toolkit.FaceTracking.PointF> facePoints = null;
                    EnumIndexableCollection<FeaturePoint, Vector3DF> facePoints3D = null;
    
                    colorImageFrame.CopyPixelDataTo(pixelBuffer);
                    depthImageFrame.CopyPixelDataTo(depthBuffer);
                    skeletonFrame.CopySkeletonDataTo(skeletonBuffer);
    
    
                    //描画の準備(左画面)
                    var drawContext1 = drawVisual.RenderOpen();
                    int frmWidth = colorImageFrame.Width;
                    int frmHeight = colorImageFrame.Height;
    
    
    
                    rgbImage.Source = bmpBuffer;
                    IPLImage.Source = bgImg2;
    
    
                    // カメラの画像情報から原画像のビットマップを作成し描画(左)
                    var bgImg1 = new WriteableBitmap(frmWidth, frmHeight, 96, 96, PixelFormats.Bgr32, null);
                    bgImg1.WritePixels(new Int32Rect(0, 0, frmWidth, frmHeight), pixelBuffer, frmWidth * 4, 0);
    
                    //右画面の原画像を追加
                    bgImg2.WritePixels(rectimg, pixelBuffer, frmWidth * 4, 0);
    
                    var rect1 = new System.Windows.Rect(0, 0, frmWidth, frmHeight);
                    drawContext1.DrawImage(bgImg1, rect1);
                    //System.Drawing.Pen pen = Pens.White;
    
    
                    foreach (Skeleton skeleton in skeletonBuffer)
                    {
                        // トラックできている骨格だけを対象とする
                        if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
                        {  // 今回のフレームにFaceTrackingを適用
                            FaceTrackFrame frame = faceTracker.Track(rgbFormat, pixelBuffer, depthFormat, depthBuffer, skeleton);       
                            //顔情報が認識できなかった場合は0を書き出す
                            //1フレーム毎に顔情報情報を取得する
                            facePoints3D = frame.Get3DShape();
                            facePoints = frame.GetProjected3DShape();
    
                            var rect2 = new System.Windows.Rect(facePoints[15].X, facePoints[15].Y, 100, 50);
                            if (frame.TrackSuccessful)
                            {
                                //原画像の上から新たに描写
                                drawContext1.DrawRectangle(System.Windows.Media.Brushes.Red, null, rect2);                    
                                foreach (var facePt in facePoints)
                                {
                                    // 取得した顔の各点に赤い点を描画(左)
                                    var pt = new System.Windows.Point(facePt.X, facePt.Y);
                                    drawContext1.DrawEllipse(System.Windows.Media.Brushes.Red, null, pt, 1, 1);
                                 }
                            }
                        }
                        //if (facePoints != null) { }
                    }
                    // 画面に表示するビットマップに描画(左)
                    drawContext1.Close();
                    bmpBuffer.Render(drawVisual);
                }
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2015-01-20T16:39:24.487
4933
2015-01-21T12:46:10.990
2015-01-21T12:46:10.990
7606
question
c# kinect
kinectのfacetrackを使って瞬きを検出したいのですが


`facePoints`の特徴点はインデックスが決まっていたはずです。[リンク先](https://msdn.microsoft.com/en-
us/library/jj130970.aspx#ID4EJNAC1)の情報が使用されているバージョンで通用するかはわかりませんが、図の通りなら15以下の点を調べればいいので

[code]

    var minX = facePoints.Take(16).Select(_ => _.X).Min();
    var maxX = facePoints.Take(16).Select(_ => _.X).Max();
    var minY = facePoints.Take(16).Select(_ => _.Y).Min();
    var maxY = facePoints.Take(16).Select(_ => _.Y).Max();
    
[/code]

という感じで目の領域が分かるかと。


CC BY-SA 3.0
2015-01-20T21:59:22.487
4935
2015-01-20T21:59:22.487
5750
4933
answer