|
@@ -30,11 +30,16 @@ namespace bbiwarg.Detectors.Palm
|
|
|
|
|
|
private Contour<Point> palmContour;
|
|
private Contour<Point> palmContour;
|
|
private List<MCvConvexityDefect> convexityDefects;
|
|
private List<MCvConvexityDefect> convexityDefects;
|
|
- private Vector2D wristPoint, wristDirection;
|
|
|
|
private LineSegment2DF wristLine, thumbLine;
|
|
private LineSegment2DF wristLine, thumbLine;
|
|
- private MCvBox2D palmRect;
|
|
|
|
|
|
+ private Quad2D palmRect;
|
|
|
|
|
|
- public PalmDetector(DepthImage depthImage, EdgeImage edgeImage, FingerDetector fingerDetector, PalmImage palmImage)
|
|
|
|
|
|
+ private bool valid = false;
|
|
|
|
+ private Vector2D topLeft;
|
|
|
|
+ private Vector2D topRight;
|
|
|
|
+ private Vector2D bottomLeft;
|
|
|
|
+ private Vector2D bottomRight;
|
|
|
|
+
|
|
|
|
+ public PalmDetector(DepthImage depthImage, EdgeImage edgeImage, List<Finger> detectedFingers, PalmImage palmImage)
|
|
{
|
|
{
|
|
width = depthImage.getWidth();
|
|
width = depthImage.getWidth();
|
|
height = depthImage.getHeight();
|
|
height = depthImage.getHeight();
|
|
@@ -44,7 +49,7 @@ namespace bbiwarg.Detectors.Palm
|
|
|
|
|
|
handImage = depthImage.getImage().Convert<Byte>(delegate(short s) { return (s == depthImage.getMaxDepth()) ? (byte)0 : (byte)1; });
|
|
handImage = depthImage.getImage().Convert<Byte>(delegate(short s) { return (s == depthImage.getMaxDepth()) ? (byte)0 : (byte)1; });
|
|
|
|
|
|
- fingers = getFingersWithoutThumb(fingerDetector);
|
|
|
|
|
|
+ fingers = getFingersWithoutThumb(detectedFingers);
|
|
buildPointingHandMask();
|
|
buildPointingHandMask();
|
|
handImage = handImage.And(pointingHandMask);
|
|
handImage = handImage.And(pointingHandMask);
|
|
|
|
|
|
@@ -54,15 +59,12 @@ namespace bbiwarg.Detectors.Palm
|
|
findConvexityDefactsSortedByDepth();
|
|
findConvexityDefactsSortedByDepth();
|
|
removeConvexityDefectsNearFingerTips();
|
|
removeConvexityDefectsNearFingerTips();
|
|
|
|
|
|
- findWristLine();
|
|
|
|
- findThumbLine();
|
|
|
|
-
|
|
|
|
- removePointsFromContour(wristLine, 1);
|
|
|
|
- removePointsFromContour(thumbLine, 1);
|
|
|
|
|
|
+ findHandPoints();
|
|
|
|
|
|
- if (palmContour.Count<Point>() != 0)
|
|
|
|
|
|
+ if (valid)
|
|
{
|
|
{
|
|
- findPalmRect();
|
|
|
|
|
|
+ removePointsFromContour(wristLine, 1);
|
|
|
|
+ removePointsFromContour(thumbLine, 1);
|
|
|
|
|
|
draw();
|
|
draw();
|
|
}
|
|
}
|
|
@@ -74,9 +76,8 @@ namespace bbiwarg.Detectors.Palm
|
|
return new PalmRect(palmRect);
|
|
return new PalmRect(palmRect);
|
|
}
|
|
}
|
|
|
|
|
|
- private List<Finger> getFingersWithoutThumb(FingerDetector fingerDetector)
|
|
|
|
|
|
+ private List<Finger> getFingersWithoutThumb(List<Finger> detectedFingers)
|
|
{
|
|
{
|
|
- List<Finger> detectedFingers = fingerDetector.Fingers;
|
|
|
|
Finger leftMost = null;
|
|
Finger leftMost = null;
|
|
float minX = float.MaxValue;
|
|
float minX = float.MaxValue;
|
|
foreach (Finger f in detectedFingers)
|
|
foreach (Finger f in detectedFingers)
|
|
@@ -168,20 +169,6 @@ namespace bbiwarg.Detectors.Palm
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private void findWristDirection()
|
|
|
|
- {
|
|
|
|
- PointF[] points = new PointF[palmContour.Count<Point>()];
|
|
|
|
- int index = 0;
|
|
|
|
- foreach (Point p in palmContour)
|
|
|
|
- {
|
|
|
|
- points[index] = new PointF(p.X, p.Y);
|
|
|
|
- ++index;
|
|
|
|
- }
|
|
|
|
- PointF direction, tmp;
|
|
|
|
- PointCollection.Line2DFitting(points, Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2, out direction, out tmp);
|
|
|
|
- wristDirection = new Vector2D(-direction.Y, direction.X);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private void findConvexityDefactsSortedByDepth()
|
|
private void findConvexityDefactsSortedByDepth()
|
|
{
|
|
{
|
|
convexityDefects = new List<MCvConvexityDefect>(palmContour.GetConvexityDefacts(new MemStorage(), Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE));
|
|
convexityDefects = new List<MCvConvexityDefect>(palmContour.GetConvexityDefacts(new MemStorage(), Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE));
|
|
@@ -213,34 +200,31 @@ namespace bbiwarg.Detectors.Palm
|
|
convexityDefects = newDefects;
|
|
convexityDefects = newDefects;
|
|
}
|
|
}
|
|
|
|
|
|
- private void findWristPoint()
|
|
|
|
- {
|
|
|
|
- if (convexityDefects.Count > 1)
|
|
|
|
- wristPoint = new Vector2D(convexityDefects[1].DepthPoint);
|
|
|
|
- else
|
|
|
|
- wristPoint = new Vector2D(-1, -1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void findWristLine()
|
|
|
|
- {
|
|
|
|
- findWristPoint();
|
|
|
|
- findWristDirection();
|
|
|
|
- wristLine = new LineSegment2DF(wristPoint - 1000 * wristDirection, wristPoint + 1000 * wristDirection);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void findThumbLine()
|
|
|
|
- {
|
|
|
|
|
|
+ private void findHandPoints() {
|
|
if (convexityDefects.Count > 0)
|
|
if (convexityDefects.Count > 0)
|
|
{
|
|
{
|
|
MCvConvexityDefect thumbDefect = convexityDefects[0];
|
|
MCvConvexityDefect thumbDefect = convexityDefects[0];
|
|
- Vector2D p1 = new Vector2D(thumbDefect.DepthPoint);
|
|
|
|
- Vector2D p2 = new Vector2D(thumbDefect.StartPoint);
|
|
|
|
- Vector2D direction = (p1 - p2).normalize();
|
|
|
|
- thumbLine = new LineSegment2DF(p1 - 1000 * direction, p1 + 1000 * direction);
|
|
|
|
|
|
+ Vector2D thumb = new Vector2D(thumbDefect.DepthPoint);
|
|
|
|
+ Vector2D thumbDefectStart = new Vector2D(thumbDefect.StartPoint);
|
|
|
|
+
|
|
|
|
+ Vector2D handLength = thumbDefectStart - thumb;
|
|
|
|
+ Vector2D handWidth = 0.8f * new Vector2D(handLength.Y, -handLength.X);
|
|
|
|
+
|
|
|
|
+ topLeft = thumbDefectStart;
|
|
|
|
+ bottomLeft = thumb - 0.3f * handLength;
|
|
|
|
+ bottomRight = bottomLeft + handWidth;
|
|
|
|
+ topRight = bottomRight + 1.5f * handLength;
|
|
|
|
+
|
|
|
|
+ wristLine = new LineSegment2DF(bottomLeft - 1000 * handWidth, bottomRight + 1000 * handWidth);
|
|
|
|
+ thumbLine = new LineSegment2DF(topLeft + 1000 * handLength, bottomLeft - 1000 * handLength);
|
|
|
|
+
|
|
|
|
+ palmRect = new Quad2D(bottomLeft, topLeft, topRight, bottomRight);
|
|
|
|
+
|
|
|
|
+ valid = true;
|
|
}
|
|
}
|
|
- else
|
|
|
|
- {
|
|
|
|
- thumbLine = new LineSegment2DF(new PointF(-1, -1), new PointF(-1, -1));
|
|
|
|
|
|
+ else {
|
|
|
|
+ palmRect = null;
|
|
|
|
+ valid = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -259,11 +243,6 @@ namespace bbiwarg.Detectors.Palm
|
|
palmContour = newContour;
|
|
palmContour = newContour;
|
|
}
|
|
}
|
|
|
|
|
|
- private void findPalmRect()
|
|
|
|
- {
|
|
|
|
- palmRect = palmContour.GetMinAreaRect();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private void draw()
|
|
private void draw()
|
|
{
|
|
{
|
|
palmImage.drawContour(palmContour);
|
|
palmImage.drawContour(palmContour);
|
|
@@ -271,11 +250,15 @@ namespace bbiwarg.Detectors.Palm
|
|
palmImage.drawLine(wristLine, PalmImageState.wristLine);
|
|
palmImage.drawLine(wristLine, PalmImageState.wristLine);
|
|
palmImage.drawLine(thumbLine, PalmImageState.thumbLine);
|
|
palmImage.drawLine(thumbLine, PalmImageState.thumbLine);
|
|
|
|
|
|
- PointF[] vertices = palmRect.GetVertices();
|
|
|
|
- for (int i = 0; i < 4; ++i)
|
|
|
|
- palmImage.drawLine(new LineSegment2DF(vertices[i], vertices[(i + 1) % 4]), PalmImageState.palmRect);
|
|
|
|
|
|
+ if (palmRect != null)
|
|
|
|
+ {
|
|
|
|
+ PointF[] vertices = palmRect.getVertices();
|
|
|
|
+ for (int i = 0; i < 4; ++i)
|
|
|
|
+ palmImage.drawLine(new LineSegment2DF(vertices[i], vertices[(i + 1) % 4]), PalmImageState.palmRect);
|
|
|
|
+
|
|
|
|
|
|
- palmImage.drawGrid(new Vector2D(vertices[0]),new Vector2D(vertices[1]),new Vector2D(vertices[2]),new Vector2D(vertices[3]));
|
|
|
|
|
|
+ palmImage.drawGrid(new Vector2D(vertices[0]), new Vector2D(vertices[1]), new Vector2D(vertices[2]), new Vector2D(vertices[3]));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|