Browse Source

Palm rect test.

Daniel Kauth 10 years ago
parent
commit
7db441d78c

+ 51 - 8
bbiwarg/Detectors/Palm/PalmDetector.cs

@@ -32,7 +32,7 @@ namespace bbiwarg.Detectors.Palm
         private List<MCvConvexityDefect> convexityDefects;
         private Vector2D wristPoint, wristDirection;
         private LineSegment2DF wristLine, thumbLine;
-        private MCvBox2D palmRect;
+        private Quad2D palmRect;
 
         public PalmDetector(DepthImage depthImage, EdgeImage edgeImage, FingerDetector fingerDetector, PalmImage palmImage)
         {
@@ -54,9 +54,9 @@ namespace bbiwarg.Detectors.Palm
                 findConvexityDefactsSortedByDepth();
                 removeConvexityDefectsNearFingerTips();
 
-                findWristLine();
                 findThumbLine();
-
+                findWristLine();
+                
                 removePointsFromContour(wristLine, 1);
                 removePointsFromContour(thumbLine, 1);
 
@@ -179,6 +179,7 @@ namespace bbiwarg.Detectors.Palm
             }
             PointF direction, tmp;
             PointCollection.Line2DFitting(points, Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2, out direction, out tmp);
+            //Vector2D direction = new Vector2D(thumbLine.Direction);
             wristDirection = new Vector2D(-direction.Y, direction.X);
         }
 
@@ -261,7 +262,45 @@ namespace bbiwarg.Detectors.Palm
 
         private void findPalmRect()
         {
-            palmRect = palmContour.GetMinAreaRect();
+            //palmRect = palmContour.GetMinAreaRect();
+
+            Line2D thumbLine2 = new Line2D(new Vector2D(thumbLine.P1), new Vector2D(thumbLine.P2));
+            Line2D wristLine2 = new Line2D(new Vector2D(wristLine.P1), new Vector2D(wristLine.P2));
+
+            Vector2D intersection = thumbLine2.intersection(wristLine2);
+            if (intersection != null)
+            {
+                Vector2D maxThumb = new Vector2D(0, 0), maxWrist = new Vector2D(0, 0);
+                float maxDistanceThumb = 0, maxDistanceWrist = 0;
+                foreach (Point p in palmContour)
+                {
+                    Vector2D v = new Vector2D(p);
+                    Vector2D projected = thumbLine2.projectToLine(v);
+
+                    float dist = projected.getDistanceTo(intersection);
+                    if (dist > maxDistanceThumb)
+                    {
+                        maxDistanceThumb = dist;
+                        maxThumb = projected;
+                    }
+
+                    projected = wristLine2.projectToLine(v);
+
+                    dist = projected.getDistanceTo(intersection);
+                    if (dist > maxDistanceWrist)
+                    {
+                        maxDistanceWrist = dist;
+                        maxWrist = projected;
+                    }
+                }
+
+                Vector2D origin = intersection;
+                palmRect = new Quad2D(origin, (maxThumb - origin), (maxWrist - origin));
+            }
+            else
+            {
+                palmRect = null;
+            }
         }
 
         private void draw()
@@ -271,11 +310,15 @@ namespace bbiwarg.Detectors.Palm
             palmImage.drawLine(wristLine, PalmImageState.wristLine);
             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]));
+            }
         }
     }
 }

+ 16 - 5
bbiwarg/Detectors/Palm/PalmRect.cs

@@ -16,14 +16,19 @@ namespace bbiwarg.Detectors.Palm
     {
         private Vector2D origin;
         private Matrix<float> transformationMatrix;
+        bool valid = true;
 
-        public PalmRect(MCvBox2D palmRect)
+        public PalmRect(Quad2D palmRect)
         {
-            PointF[] vertices = palmRect.GetVertices();
+            if (palmRect == null)
+            {
+                valid = false;
+                return;
+            }
 
-            origin = new Vector2D(vertices[1]);
-            PointF v0 = vertices[0];
-            PointF v2 = vertices[2];
+            origin = palmRect.Origin;
+            PointF v0 = palmRect.Origin + palmRect.DirWidth;
+            PointF v2 = palmRect.Origin + palmRect.DirLength;
 
             Matrix<float> tmp = new Matrix<float>(new float[,] { { v0.X - origin.X, v2.X - origin.X }, { v0.Y - origin.Y, v2.Y - origin.Y } });
             transformationMatrix = new Matrix<float>(2, 2);
@@ -32,11 +37,17 @@ namespace bbiwarg.Detectors.Palm
 
         public bool isWithinMargin(Vector2D position)
         {
+            if (!valid)
+                return false;
+            
             Vector2D relativePosition = getRelativePosition(position);
             return (relativePosition.X >= -0.1 && relativePosition.X <= 1.1 && relativePosition.Y >= -0.1 && relativePosition.Y <= 1.1);
         }
         public Vector2D getRelativePosition(Vector2D absolutePosition)
         {
+            if (!valid)
+                return null;
+            
             Vector2D v = absolutePosition - origin;
             Matrix<float> coordsMatrix = transformationMatrix.Mul(new Matrix<float>(new float[,] { { v.X }, { v.Y } }));
             return new Vector2D(coordsMatrix.Data[0, 0], coordsMatrix.Data[1, 0]);

+ 2 - 1
bbiwarg/Images/PalmImage.cs

@@ -40,7 +40,8 @@ namespace bbiwarg.Images
 
         public void drawContour(Contour<Point> contour)
         {
-            image.Draw(contour, new Gray((byte)PalmImageState.palmContour), 1);
+            image.Draw(contour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE), new Gray((byte)PalmImageState.palmContour), 1);
+            //image.Draw(contour, new Gray((byte)PalmImageState.palmContour), 1);
         }
 
         public void drawLine(LineSegment2DF line, PalmImageState state)

+ 1 - 1
bbiwarg/MainBBWIWARG.cs

@@ -12,7 +12,7 @@ namespace bbiwarg
     {
         static void Main(string[] args)
         {
-            IInputProvider inputProvider = new IisuInputProvider("..\\..\\videos\\touch\\4.skv");
+            IInputProvider inputProvider = new IisuInputProvider(""); //..\\..\\videos\\touch\\4.skv");
             VideoHandle videoHandle = new VideoHandle(inputProvider);
             videoHandle.start();
 

+ 44 - 0
bbiwarg/Preprocessing/BackgroundSubtractor.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using bbiwarg.Images;
+
+using Emgu.CV;
+using Emgu.CV.Structure;
+using Emgu.CV.VideoSurveillance;
+
+namespace bbiwarg.Preprocessing
+{
+    class BackgroundSubtractor
+    {
+        private BackgroundSubtractorMOG subtractor;
+
+        public BackgroundSubtractor()
+        {
+            subtractor = new BackgroundSubtractorMOG(0, 0, 0.0, 0.0); // defaults
+        }
+
+        public void update(Image<Bgr, byte> currentColorImage)
+        {
+            subtractor.Update(currentColorImage);
+        }
+
+        public Image<Gray, short> getForeground(Image<Gray, short> image)
+        {
+            Image<Gray, short> foreground = image.Clone();
+            foreground = foreground.And(subtractor.ForegroundMask.Convert<short>(delegate(byte b) { if (b == 0) return 0; else return short.MaxValue; }));
+
+            int numNonZero = 0;
+            for (int i = 0; i < image.Width; ++i)
+                for (int j = 0; j < image.Height; ++j)
+                    if (subtractor.ForegroundMask.Data[j, i, 0] != 0)
+                        ++numNonZero;
+            Console.WriteLine("non zero: " + numNonZero);
+
+            return subtractor.ForegroundMask.Convert<short>(delegate(byte b) { return (b == 0) ? (short) 0 : (short) 100; });
+        }
+    }
+}

+ 17 - 0
bbiwarg/Utility/Line2D.cs

@@ -136,6 +136,23 @@ namespace bbiwarg.Utility
             return new Vector2D(newX, newY);
         }
 
+        public Vector2D intersection(Line2D line)
+        {
+            Vector2D p = P1;
+            Vector2D r = P2 - P1;
+            Vector2D q = line.P1;
+            Vector2D s = line.P2 - line.P1;
+
+            float r_cross_s = r.cross(s);
+            float q_p_cross_s = (q - p).cross(s);
+
+            if (r_cross_s == 0.0)
+                return null;
+
+            float t = q_p_cross_s  / r_cross_s;
+            return p + t * r;
+        }
+
         public override string ToString()
         {
             return (int)P1.X + "|" + (int)P1.Y + " --- " + (int)P2.X + "|" + (int)P2.Y;

+ 29 - 0
bbiwarg/Utility/Quad2D.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.Drawing;
+
+namespace bbiwarg.Utility
+{
+    class Quad2D
+    {
+        public Vector2D Origin {private set; get;}
+        public Vector2D DirLength {private set; get;}
+        public Vector2D DirWidth {private set; get;}
+
+        public Quad2D(Vector2D origin, Vector2D dirLength, Vector2D dirWidth)
+        {
+            Origin = origin;
+            DirLength = dirLength;
+            DirWidth = dirWidth;
+        }
+
+        public PointF[] getVertices()
+        {
+            return new PointF[] {Origin, Origin + DirLength, Origin + 0.8f * DirLength + 0.8f * DirWidth, Origin + DirWidth};
+        }
+    }
+}

+ 5 - 0
bbiwarg/Utility/Vector2D.cs

@@ -94,6 +94,11 @@ namespace bbiwarg.Utility
             return new Vector2D(vector1.X - vector2.X, vector1.Y - vector2.Y);
         }
 
+        public float cross(Vector2D v)
+        {
+            return X * v.Y - Y * v.X;
+        }
+
         public static Vector2D mean(List<Vector2D> vectors) {
             Vector2D meanVector = new Vector2D(0,0);
             foreach (Vector2D vector in vectors) {

+ 1 - 0
bbiwarg/bbiwarg.csproj

@@ -91,6 +91,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Utility\HelperFunctions.cs" />
     <Compile Include="Utility\Line2D.cs" />
+    <Compile Include="Utility\Quad2D.cs" />
     <Compile Include="Utility\Vector.cs" />
     <Compile Include="Utility\Vector2D.cs" />
     <Compile Include="VideoHandle.cs" />