Browse Source

implemented touchDetection

Alexander Hendrich 10 years ago
parent
commit
4f45f3e6d6

+ 1 - 1
bbiwarg/Detectors/Finger/Finger.cs → bbiwarg/Detectors/Fingers/Finger.cs

@@ -8,7 +8,7 @@ using Emgu.CV;
 using Emgu.CV.Structure;
 using bbiwarg.Images;
 
-namespace bbiwarg.Detectors.Finger
+namespace bbiwarg.Detectors.Fingers
 {
     class Finger
     {

+ 5 - 1
bbiwarg/Detectors/Finger/FingerDetector.cs → bbiwarg/Detectors/Fingers/FingerDetector.cs

@@ -8,7 +8,7 @@ using Emgu.CV;
 using Emgu.CV.Structure;
 using bbiwarg.Images;
 
-namespace bbiwarg.Detectors.Finger
+namespace bbiwarg.Detectors.Fingers
 {
     class FingerDetector
     {
@@ -37,6 +37,10 @@ namespace bbiwarg.Detectors.Finger
             return fingerPoints[x, y];
         }
 
+        public List<Finger> getFingers() {
+            return fingers;
+        }
+
         private void findPossibleFingerPoints()
         {
             int width = depthImage.getWidth();

+ 1 - 1
bbiwarg/Detectors/Finger/FingerPoint.cs → bbiwarg/Detectors/Fingers/FingerPoint.cs

@@ -4,7 +4,7 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
-namespace bbiwarg.Detectors.Finger
+namespace bbiwarg.Detectors.Fingers
 {
     class FingerPoint
     {

+ 75 - 0
bbiwarg/Detectors/Touch/TouchDetector.cs

@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Emgu.CV;
+using Emgu.CV.Structure;
+using bbiwarg.Images;
+using bbiwarg.Detectors.Fingers;
+
+namespace bbiwarg.Detectors.Touch
+{
+    class TouchDetector
+    {
+        private DepthImage depthImage;
+        private List<Finger> fingers;
+
+        public TouchDetector(DepthImage depthImage, List<Finger> fingers) {
+            this.depthImage = depthImage;
+            this.fingers = fingers;
+
+            foreach (Finger finger in fingers) {
+                //farthest
+                FingerPoint fp1 = finger.getFarthest();
+                float touchFP1 = isTouchAt(fp1.getX(), fp1.getY());
+
+                //nearest
+                FingerPoint fp2 = finger.getNearest();
+                float touchFP2 = isTouchAt(fp2.getX(), fp2.getY());
+
+                int depthDifference = fp1.getDepth() - fp2.getDepth();
+
+
+                if(touchFP1 > 0.6f && touchFP2 > 0.6f && depthDifference > 20 && depthDifference < 50)
+                Console.WriteLine("TouchEvent bei x:" + fp1.getX() + " y:" + fp1.getY() + " [FP1:" + Math.Round(touchFP1, 1) + " FP2:" + Math.Round(touchFP2, 1) + "]");
+
+            }
+        }
+
+        private float isTouchAt(int touchX, int touchY) {
+            int searchSize = 15;
+            int maxDepthDifference = 20;
+            Int16 depthAtTouch = depthImage.getDepthAt(touchX, touchY);
+
+            int minX = Math.Max(touchX - searchSize, 0);
+            int maxX = Math.Min(touchX + searchSize, depthImage.getWidth());
+            int minY = Math.Max(touchY - searchSize, 0);
+            int maxY = Math.Min(touchY + searchSize, depthImage.getHeight());
+
+            int matchedPixels = 0;
+            int countedPixels = 0;
+            for (int x = minX; x < maxX; x++) {
+                for (int y = minY; y < maxY; y++) {
+                    Int16 depth = depthImage.getDepthAt(x,y);
+                    depthImage.setDepthAt(x, y, Int16.MaxValue - 1);//counted pixels -> red
+                    if (Math.Abs(depthAtTouch - depth) < maxDepthDifference) {
+                        matchedPixels++;
+                       depthImage.setDepthAt(x, y, Int16.MaxValue);//matched pixels -> blue
+                    }
+                    countedPixels++;
+                }
+            }
+
+            float rel = (float)matchedPixels / (float)countedPixels;
+
+            //status bar (% of matched pixels) -> green
+            for (int x = minX; x < minX + (maxX-minX)*rel; x++) {
+                depthImage.setDepthAt(x, maxY-1, Int16.MaxValue-2);
+            }
+
+                return rel;
+        }
+    }
+}

+ 20 - 7
bbiwarg/Graphics/OutputWindow.cs

@@ -79,16 +79,29 @@ namespace bbiwarg.Graphics
             {
                 for (int x = 0; x < videoHandle.getWidth(); ++x)
                 {
-                    //depthTexture
-                    Int16 scaledDepth = (Int16) ((1.0f - videoHandle.getRelativeDepth(x, y)) * Int16.MaxValue);
-                    depthTextureData[index] = scaledDepth;
-                    depthTextureData[index + 1] = scaledDepth;
-                    depthTextureData[index + 2] = scaledDepth;
-
-                    //edgeTexture
                     Int16 red = 0;
                     Int16 green = 0;
                     Int16 blue = 0;
+
+                    //depthTexture
+                    float relDepth = videoHandle.getRelativeDepth(x,y);
+                    if (relDepth <= 1 && relDepth >= 0)
+                    {
+                        red = green = blue = (Int16)((1.0f - videoHandle.getRelativeDepth(x, y)) * Int16.MaxValue);
+                    }
+                    else {
+                        Int16 depth = videoHandle.getDepthAt(x,y);
+                        if (depth == Int16.MaxValue - 1) red = Int16.MaxValue;
+                        if (depth == Int16.MaxValue) blue = Int16.MaxValue;
+                        if (depth == Int16.MaxValue-2) green = Int16.MaxValue;
+                    }
+
+                    depthTextureData[index] = red;
+                    depthTextureData[index + 1] = green;
+                    depthTextureData[index + 2] = blue;
+
+                    //edgeTexture
+                    red = green = blue = 0;
                     if (videoHandle.isEdgeAt(x, y)) blue = Int16.MaxValue;
                     if (videoHandle.isFingerPointAt(x, y)) red = green = Int16.MaxValue;
 

+ 4 - 0
bbiwarg/Images/DepthImage.cs

@@ -35,6 +35,10 @@ namespace bbiwarg.Images
             return image.Data[y, x, 0];
         }
 
+        public void setDepthAt(int x, int y, Int16 depth) {
+            image.Data[y, x, 0] = depth;
+        }
+
         public float getRelativeDepth(int x, int y) {
             float minMaxInterval = Math.Max(maxDepth - minDepth, 1);
             return (getDepthAt(x, y)-minDepth) / minMaxInterval;

+ 5 - 1
bbiwarg/VideoHandle.cs

@@ -4,7 +4,8 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Diagnostics;
-using bbiwarg.Detectors.Finger;
+using bbiwarg.Detectors.Fingers;
+using bbiwarg.Detectors.Touch;
 using bbiwarg.Images;
 using bbiwarg.InputProviders;
 using Emgu.CV;
@@ -23,6 +24,7 @@ namespace bbiwarg
         private EdgeImage edgeImage;
 
         private FingerDetector fingerDetector;
+        private TouchDetector touchDetector;
 
         public VideoHandle(IInputProvider inputProvider) {
             this.inputProvider = inputProvider;
@@ -105,6 +107,8 @@ namespace bbiwarg
             //detect fingers
             fingerDetector = new FingerDetector(depthImage, edgeImage);
 
+            //detect touch
+            touchDetector = new TouchDetector(depthImage, fingerDetector.getFingers());
         }
     }
 }

+ 4 - 3
bbiwarg/bbiwarg.csproj

@@ -66,9 +66,10 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Detectors\Finger\Finger.cs" />
-    <Compile Include="Detectors\Finger\FingerDetector.cs" />
-    <Compile Include="Detectors\Finger\FingerPoint.cs" />
+    <Compile Include="Detectors\Fingers\Finger.cs" />
+    <Compile Include="Detectors\Fingers\FingerDetector.cs" />
+    <Compile Include="Detectors\Fingers\FingerPoint.cs" />
+    <Compile Include="Detectors\Touch\TouchDetector.cs" />
     <Compile Include="Graphics\OutputWindow.cs" />
     <Compile Include="Images\DepthImage.cs" />
     <Compile Include="Images\EdgeImage.cs" />