|
@@ -16,19 +16,20 @@ namespace bbiwarg.Images
|
|
class PalmImage
|
|
class PalmImage
|
|
{
|
|
{
|
|
private Image<Gray, Byte> image;
|
|
private Image<Gray, Byte> image;
|
|
|
|
+ private Image<Gray, Byte> fingerSliceMask;
|
|
private Image<Gray, Byte> output;
|
|
private Image<Gray, Byte> output;
|
|
private int width, height;
|
|
private int width, height;
|
|
|
|
|
|
- public PalmImage(EdgeImage edgeImage, FingerDetector fingerDetector)
|
|
|
|
|
|
+ public PalmImage(DepthImage depthImage, FingerDetector fingerDetector)
|
|
{
|
|
{
|
|
- image = edgeImage.getImage().Clone();
|
|
|
|
|
|
+ image = depthImage.getImage().Convert<Byte>(delegate(short s) { return (s == depthImage.getMaxDepth()) ? (byte) 0 : (byte) 1; });
|
|
width = image.Width;
|
|
width = image.Width;
|
|
height = image.Height;
|
|
height = image.Height;
|
|
|
|
|
|
- List<Finger> trackedFingers = fingerDetector.Fingers;
|
|
|
|
|
|
+ List<Finger> detectedFingers = fingerDetector.Fingers;
|
|
Finger leftMost = null;
|
|
Finger leftMost = null;
|
|
float minX = float.MaxValue;
|
|
float minX = float.MaxValue;
|
|
- foreach (Finger f in trackedFingers)
|
|
|
|
|
|
+ foreach (Finger f in detectedFingers)
|
|
{
|
|
{
|
|
float midX = ((f.Hand + f.Tip) / 2).X;
|
|
float midX = ((f.Hand + f.Tip) / 2).X;
|
|
if (midX < minX)
|
|
if (midX < minX)
|
|
@@ -38,8 +39,8 @@ namespace bbiwarg.Images
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- Image<Gray, Byte> fingerSliceMask = new Image<Gray, byte>(width, height, new Gray(1));
|
|
|
|
- foreach (Finger f in trackedFingers)
|
|
|
|
|
|
+ fingerSliceMask = new Image<Gray, byte>(width, height, new Gray(1));
|
|
|
|
+ foreach (Finger f in detectedFingers)
|
|
{
|
|
{
|
|
if (f != leftMost)
|
|
if (f != leftMost)
|
|
{
|
|
{
|
|
@@ -50,27 +51,27 @@ namespace bbiwarg.Images
|
|
{
|
|
{
|
|
int y = (int)start.Y;
|
|
int y = (int)start.Y;
|
|
for (int x = (int)start.X; x <= (int)end.X; ++x)
|
|
for (int x = (int)start.X; x <= (int)end.X; ++x)
|
|
- image.Data[y, x, 0] = 0;
|
|
|
|
|
|
+ fingerSliceMask.Data[y, x, 0] = 0;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
int x = (int)start.X;
|
|
int x = (int)start.X;
|
|
for (int y = (int)start.Y; y <= (int)end.Y; ++y)
|
|
for (int y = (int)start.Y; y <= (int)end.Y; ++y)
|
|
- image.Data[y, x, 0] = 0;
|
|
|
|
|
|
+ fingerSliceMask.Data[y, x, 0] = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- image = image.And(fingerSliceMask.Erode(3));
|
|
|
|
|
|
+ fingerSliceMask = fingerSliceMask.Erode(2);
|
|
|
|
+ image = image.And(fingerSliceMask);
|
|
|
|
|
|
findContour();
|
|
findContour();
|
|
}
|
|
}
|
|
|
|
|
|
private void findContour()
|
|
private void findContour()
|
|
{
|
|
{
|
|
- image.Dilate(1);
|
|
|
|
- Contour<Point> contour = image.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST);
|
|
|
|
|
|
+ Contour<Point> contour = image.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
|
|
|
|
|
|
Contour<Point> maxContour = contour;
|
|
Contour<Point> maxContour = contour;
|
|
double maxPerimeter = 0;
|
|
double maxPerimeter = 0;
|
|
@@ -83,10 +84,23 @@ namespace bbiwarg.Images
|
|
}
|
|
}
|
|
contour = contour.HNext;
|
|
contour = contour.HNext;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ Contour<Point> contourPoly = maxContour; //.ApproxPoly(0);
|
|
|
|
+ Seq<Point> hull = contourPoly.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
|
|
|
|
+ Seq<MCvConvexityDefect> defects = contourPoly.GetConvexityDefacts(new MemStorage(), Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
|
|
|
|
|
|
output = new Image<Gray, byte>(width, height, new Gray(0));
|
|
output = new Image<Gray, byte>(width, height, new Gray(0));
|
|
- output.Draw(maxContour, new Gray(1), 1);
|
|
|
|
- output.Draw(maxContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE), new Gray(1), 1);
|
|
|
|
|
|
+ output.Draw(contourPoly, new Gray(1), 1);
|
|
|
|
+ output.Draw(hull, new Gray(1), 1);
|
|
|
|
+
|
|
|
|
+ foreach (MCvConvexityDefect defect in defects)
|
|
|
|
+ {
|
|
|
|
+ Point s = defect.StartPoint;
|
|
|
|
+ Point e = defect.EndPoint;
|
|
|
|
+ Point d = defect.DepthPoint;
|
|
|
|
+
|
|
|
|
+ output.Draw(new LineSegment2DF(d, new Point((s.X + e.X) / 2, (s.Y + e.Y) / 2)), new Gray(1), 1);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
public bool belongsToPalm(int x, int y)
|
|
public bool belongsToPalm(int x, int y)
|