kersten
kersten

Reputation: 41

detecting contact of a hand and an object in Kinec pictures C++

First of all: I am quite new in programming Kinec via MS Visual Studio ... so sorry if my question is a little bit stupid.

I want to detect if my hand contacts the upper part of a quadrant; for that I programm:

Image<Gray, Byte> HandImage = GetThresholdedImage(ref bgrImage, (int)hueHand);
Image<Gray, Byte> depthImageBin = depthImage.ThresholdBinary(new Gray(30), new Gray(255));

List<MCvBox2D> DangerAreas = new List<MCvBox2D>();
List<MCvBox2D> HandAreas = new List<MCvBox2D>();

// build list of object rectangles
DangerAreas = ProcessObjectContours(bgrImage, contoursDepthObjects, contoursHand, objectSize);
// build list of hand rectangles
HandAreas = ProcessHandContours(bgrImage, contoursHand, contoursDepthObjects, handSize);      

whereby the values objectSize and handSize define the minimum-limit of the objects.

so far all works well, I see the shapes on the display. If the two contures match, they merging.

But I want that the software annouce when my hand (HandAreas) touch the object (DangerAreas) at a defined region.

I tried to solve the problem with MatchShapes:

contoursDepthObjects.MatchShapes(contoursDepthObjects[0], contoursHand[0], Emgu.CV.CvEnum.MATCH_CONTOUR_TREE_METHOD.CONTOUR_TREES_MATCH_I1, 2);

but in this form MatchShapes is not accepted, because of errors. So two questions: is this the right way to detect when my hand touch the danger area, and if yes how is it correct handling of method MatchShapes?

Upvotes: 1

Views: 1432

Answers (1)

Michal Strzalkowski
Michal Strzalkowski

Reputation: 164

The way I would do this is to look into collision detection algorithms. You can quite easily get the position of the hand and translate it to a 2D Point relative to the container your rectangles are in, then get the 2D Point for the danger area rectangle. Then it's just a matter of determining whether the hand point is on top (or in the radius of) the rectangle point.

To get the skeleton position relative to the grid all elements are in:

private static Point GetPosition2DLocation(SkeletonPoint position, Grid skeletonCanvas, DepthImageFrame depthFrame)
        {
            DepthImagePoint depthPoint = depthFrame.MapFromSkeletonPoint(position);
            return new Point(
                (int)(skeletonCanvas.ActualWidth * depthPoint.X / depthFrame.Width),
                (int)(skeletonCanvas.ActualHeight * depthPoint.Y / depthFrame.Height)
            );
        }

To check if two points are intersecting (within a radius of 70):

private static bool PointsIntersecting(Point item1, Point item2)
        {
            //Give the center a radius so that collision does not have to be exact.
            //TODO configurable
            const int radius = 70;

            //compare the distance to combined radii
            double dx = item2.X - item1.X;
            double dy = item2.Y - item1.Y;
            const int radii = radius + radius;
            if ((dx * dx) + (dy * dy) < radii * radii)
            {
                return true;
            }
            return false;
        }

Hope this makes sense.

Upvotes: 1

Related Questions