コード例 #1
0
ファイル: MainWindow.xaml.cs プロジェクト: ushadow/handinput
        void depthDisplay_MouseDown(object sender, MouseButtonEventArgs e)
        {
            var p   = e.GetPosition(depthDisplay);
            var x   = (int)(p.X * HandInputParams.DepthWidth / depthDisplay.ActualWidth);
            var y   = (int)(p.Y * HandInputParams.DepthHeight / depthDisplay.ActualHeight);
            var raw = depthManager.PixelData[y * HandInputParams.DepthWidth + x];

            Log.DebugFormat("depth = {0}", DepthUtil.RawToDepth(raw));
        }
コード例 #2
0
ファイル: StipHandTracker.cs プロジェクト: ushadow/handinput
        void ConvertDepthImage(short[] depthFrame)
        {
            var data  = Gray.Data;
            var scale = (float)255 / HandInputParams.MaxDepth;

            for (int r = 0; r < height; r++)
            {
                for (int c = 0; c < width; c++)
                {
                    var index = r * width + c;
                    var pixel = depthFrame[index];
                    var depth = DepthUtil.RawToDepth(pixel);
                    depth = (depth <HandInputParams.MinDepth || depth> HandInputParams.MaxDepth) ?
                            HandInputParams.MaxDepth : depth;
                    data[r, c, 0] = (byte)((HandInputParams.MaxDepth - depth) * scale);
                }
            }
            CvInvoke.cvResize(Gray.Ptr, smallGray.Ptr, INTER.CV_INTER_LINEAR);
        }
コード例 #3
0
        private void AlignColorImage(short[] depthFrame, Image <Gray, Byte> colorImage)
        {
            CvInvoke.cvZero(alignedImg.Ptr);

            var data        = colorImage.Data;
            var alignedData = alignedImg.Data;

            for (int r = 0; r < height; r++)
            {
                for (int c = 0; c < width; c++)
                {
                    var depthPixel = depthFrame[r * width + c];
                    var depth      = DepthUtil.RawToDepth(depthPixel);
                    var cp         = mapper.MapDepthPointToColorPoint(c, r, depth);
                    if (cp.X >= 0 && cp.X < width && cp.Y >= 0 && cp.Y < height)
                    {
                        alignedData[r, c, 0] = data[cp.Y, cp.X, 0];
                    }
                }
            }
            CvInvoke.cvMorphologyEx(alignedImg.Ptr, alignedImg.Ptr, IntPtr.Zero, IntPtr.Zero,
                                    CV_MORPH_OP.CV_MOP_CLOSE, 1);
        }
コード例 #4
0
        /// <summary>
        /// If no bounding box is found, returns the last bounding box.
        /// </summary>
        /// <returns></returns>
        List <Rectangle> FindBestBoundingBox(short[] depthFrame, Skeleton skeleton)
        {
            CvInvoke.cvConvert(SaliencyProb.Ptr, TempMask.Ptr);
            // Non-zero pixels are treated as 1s. Source image content is modifield.
            CvInvoke.cvFindContours(TempMask.Ptr, storage, ref contourPtr, StructSize.MCvContour,
                                    RETR_TYPE.CV_RETR_EXTERNAL, CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, new Point(0, 0));
            var contour = new Seq <Point>(contourPtr, null);

            SortedList <float, Seq <Point> > bestContours = new SortedList <float, Seq <Point> >();
            List <Rectangle> bestBoundingBoxes            = new List <Rectangle>();

            float z    = DefaultZDist;
            var   hand = SkeletonUtil.GetJoint(skeleton, JointType.HandRight);

            if (hand != null)
            {
                z = hand.Position.Z;
            }
            double perimThresh = DepthUtil.GetDepthImageLength(width, HandWidth, z) * 2;

            FaceModel = SkeletonUtil.GetFaceModel(skeleton, mapper);

            for (; contour != null && contour.Ptr.ToInt32() != 0; contour = contour.HNext)
            {
                var perim = CvInvoke.cvContourPerimeter(contour.Ptr);
                if (perim > perimThresh)
                {
                    var rect   = contour.BoundingRectangle;
                    var score  = ContourScore(rect);
                    var center = rect.Center();
                    int x      = (int)center.X;
                    int y      = (int)center.Y;
                    var depth  = DepthUtil.RawToDepth(depthFrame[y * width + x]);
                    if (!FaceModel.IsPartOfFace(x, y, depth) &&
                        (bestContours.Count < NumTrackedHands || score > bestContours.ElementAt(0).Key))
                    {
                        bestContours.Add(score, contour);
                        if (bestContours.Count > NumTrackedHands)
                        {
                            bestContours.RemoveAt(0);
                        }
                    }
                }
            }

            if (bestContours.Count > 0)
            {
                foreach (var c in bestContours.Values)
                {
                    var rect = c.BoundingRectangle;
                    CvInvoke.cvCamShift(TrackedDepthFrame.Ptr, rect, new MCvTermCriteria(CamShiftIter),
                                        out connectedComp, out shiftedBox);
                    var bestBoundingBox = shiftedBox.MinAreaRect();
                    bestBoundingBoxes.Add(bestBoundingBox);
                    //FloodFill(TrackedDepthFrame, bestBoundingBox);
                    //if (bestBoundingBox.Width > 0) {
                    //  TempMask.ROI = bestBoundingBox;
                    //  CvInvoke.cvFindContours(TempMask.Ptr, storage, ref contourPtr, StructSize.MCvContour,
                    //      RETR_TYPE.CV_RETR_EXTERNAL, CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                    //      new Point(0, 0));
                    //  contour = new Seq<Point>(contourPtr, null);

                    //  Seq<Point> largestContour = null;
                    //  var maxPerim = perimThresh;
                    //  for (; contour != null && contour.Ptr.ToInt32() != 0; contour = contour.HNext) {
                    //    var perim = CvInvoke.cvContourPerimeter(contour.Ptr);
                    //    if (perim > maxPerim) {
                    //      maxPerim = perim;
                    //      largestContour = contour;
                    //    }
                    //  }

                    //  CvInvoke.cvZero(TempMask.Ptr);
                    //  if (largestContour != null)
                    //    TempMask.Draw(largestContour, new Gray(255), -1);
                    //  FilterImage(TrackedDepthFrame, TempMask);
                    //  TempMask.ROI = Rectangle.Empty;
                    //}
                }
            }

            return(bestBoundingBoxes);
        }
コード例 #5
0
        private SkeletonPoint FindHand(short[] depthData, Rectangle rect)
        {
            CvInvoke.cvZero(HandImage.Ptr);
            var handImageData  = HandImage.Data;
            var handMaskData   = HandMask.Data;
            var playerMaskData = playerMask.Data;

            var maxDepth = 0;
            var minDepth = Int32.MaxValue;

            for (int y = rect.Top; y < rect.Top + rect.Height && y < height; y++)
            {
                for (int x = rect.Left; x < rect.Left + rect.Width && x < width; x++)
                {
                    if (y > 0 && x > 0 && handMaskData[y, x, 0] > 0 &&
                        playerMaskData[y, x, 0] > 0)
                    {
                        var depth = DepthUtil.RawToDepth(depthData[y * width + x]);
                        maxDepth = Math.Max(maxDepth, depth);
                        if (depth < minDepth)
                        {
                            minDepth = depth;
                        }
                    }
                }
            }

            var scale = (float)255 / (maxDepth - minDepth);

            for (int y = rect.Top; y < rect.Top + rect.Height && y < height; y++)
            {
                for (int x = rect.Left; x < rect.Left + rect.Width && x < width; x++)
                {
                    if (y > 0 && x > 0 && playerMaskData[y, x, 0] > 0 &&
                        handMaskData[y, x, 0] > 0)
                    {
                        var depth = DepthUtil.RawToDepth(depthData[y * width + x]);
                        handImageData[y, x, 0] = (byte)((maxDepth - depth) * scale);
                    }
                }
            }

            var connectedComp = new MCvConnectedComp();
            var shiftedBox    = new MCvBox2D();

            CvInvoke.cvCamShift(HandImage.Ptr, rect, new MCvTermCriteria(0.0), out connectedComp,
                                out shiftedBox);

            PrevHand = new windows.Point(HandBox.center.X, HandBox.center.Y);
            HandBox  = shiftedBox;
            var newRect  = shiftedBox.MinAreaRect();
            var aveDepth = 0.0;
            var count    = 0;

            for (int y = newRect.Top; y < newRect.Top + newRect.Height && y < height; y++)
            {
                for (int x = newRect.Left; x < newRect.Left + newRect.Width && x < width; x++)
                {
                    if (x > 0 && y > 0 && playerMaskData[y, x, 0] > 0 &&
                        handMaskData[y, x, 0] > 0)
                    {
                        var depth = DepthUtil.RawToDepth(depthData[y * width + x]);
                        aveDepth += depth;
                        count++;
                    }
                }
            }

            aveDepth /= count;
            var shiftedCenterX = Math.Max(0, shiftedBox.center.X);

            shiftedCenterX = Math.Min(shiftedCenterX, width);
            var shiftedCenterY = Math.Max(0, shiftedBox.center.Y);

            shiftedCenterY = Math.Min(shiftedCenterY, height);
            return(mapper.MapDepthPointToSkeletonPoint((int)shiftedCenterX,
                                                       (int)shiftedCenterY, (int)aveDepth));
        }