Преглед изворни кода

Added opencv to DepthImage.
Added OutputDepthImage to draw DepthImage as texture.

Daniel Kauth пре 10 година
родитељ
комит
e749ddf01e

+ 18 - 0
bbiwarg/DataSource/CollisionDetection.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using MathNet.Numerics.LinearAlgebra.Single;
+
+namespace bbiwarg.DataSource
+{
+    class CollisionDetection
+    {
+        public static float getDistance(Vector origin, Vector normal, Vector fingerPoint)
+        {
+            return Math.Abs((fingerPoint - origin).DotProduct(normal));
+        }
+    }
+}

+ 56 - 3
bbiwarg/DataSource/DepthImage.cs

@@ -4,6 +4,12 @@ using System.Linq;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 
 
+using MathNet.Numerics.LinearAlgebra.Single;
+
+using System.Drawing;
+using Emgu.CV;
+using Emgu.CV.Structure;
+
 namespace bbiwarg.DataSource
 namespace bbiwarg.DataSource
 {
 {
     /**
     /**
@@ -12,13 +18,16 @@ namespace bbiwarg.DataSource
     class DepthImage
     class DepthImage
     {
     {
         private int width, height;
         private int width, height;
-        private short[] data;
+        private Image<Gray, Int16> image;
 
 
         public DepthImage(int width, int height, short[] data)
         public DepthImage(int width, int height, short[] data)
         {
         {
             this.width = width;
             this.width = width;
             this.height = height;
             this.height = height;
-            this.data = data;
+            
+            image = new Image<Gray, Int16>(width, height);
+            for (int i = 0; i < data.Length; ++i)
+                setDepth(i % width, i / width, data[i]);
         }
         }
 
 
         public int getWidth()
         public int getWidth()
@@ -33,7 +42,51 @@ namespace bbiwarg.DataSource
 
 
         public short getDepth(int x, int y)
         public short getDepth(int x, int y)
         {
         {
-            return data[y * width + x];
+            return image.Data[y, x, 0];
+        }
+
+        private void setDepth(int x, int y, short depth)
+        {
+            image.Data[y, x, 0] = depth;
+        }
+
+        public void filterMedian(int filterSize)
+        {
+            image = image.SmoothMedian(3);
+        }
+
+        public void thresholdDepth(int min, int max)
+        {
+            image = image.ThresholdToZero(new Gray(min));
+            image = image.ThresholdBinaryInv(new Gray(max), new Gray(2000));
+         }
+
+        public void thresholdPosition(int minX, int maxX, int minY, int maxY)
+        {
+            for (int x = 0; x < width; ++x)
+            {
+                for (int y = 0; y < height; ++y)
+                {
+                    if (x < minX || x > maxX || y < minY || y > maxY)
+                        setDepth(x, y, 0);
+                }
+            }
+        }
+
+        public List<Vector> getRectPoints()
+        {
+            Image<Gray, Byte> tmp = image.Convert<Byte>(delegate(short s) { return (s == 2000) ? (byte) 1 : (byte) 0; });
+
+            Contour<Point> contours = tmp.FindContours();
+            MCvBox2D box = contours.GetMinAreaRect();
+            Seq<Point> points = contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
+
+            List<Vector> result = new List<Vector>();
+            foreach (Point p in points)
+            {
+                result.Add(new DenseVector(new float[]{p.X, p.Y}));
+            }
+            return result;
         }
         }
     }
     }
 }
 }

+ 1 - 0
bbiwarg/DataSource/IVideoHandle.cs

@@ -34,6 +34,7 @@ namespace bbiwarg.DataSource
         DetectionStatus[] getFingerStatus(uint handIndex);
         DetectionStatus[] getFingerStatus(uint handIndex);
         Vector[] getFingerTipPositions3D(uint handIndex);
         Vector[] getFingerTipPositions3D(uint handIndex);
         Vector getPalmPosition3D(uint handIndex);
         Vector getPalmPosition3D(uint handIndex);
+        Vector getPalmNormal3D(uint handIndex);
         Vector getForearmPosition3D(uint handIndex);
         Vector getForearmPosition3D(uint handIndex);
         Vector getForeFingerPosition3D(uint handIndex);
         Vector getForeFingerPosition3D(uint handIndex);
         List<Vector> getHandPoints();
         List<Vector> getHandPoints();

+ 5 - 0
bbiwarg/DataSource/VideoHandle.cs

@@ -113,6 +113,11 @@ namespace bbiwarg.DataSource
             return inputProvider.getPalmPosition3D(handIndex);
             return inputProvider.getPalmPosition3D(handIndex);
         }
         }
 
 
+        public Vector getPalmNormal3D(uint handIndex)
+        {
+            return inputProvider.getPalmNormal3D(handIndex);
+        }
+
         public Vector getForearmPosition3D(uint handIndex)
         public Vector getForearmPosition3D(uint handIndex)
         {
         {
             return inputProvider.getForearmPosition3D(handIndex);
             return inputProvider.getForearmPosition3D(handIndex);

+ 145 - 0
bbiwarg/Graphics/OutputDepthImage.cs

@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using System.Drawing;
+using System.Diagnostics;
+
+using MathNet.Numerics.LinearAlgebra.Single;
+using bbiwarg.DataSource;
+
+namespace bbiwarg.Graphics
+{
+    class OutputDepthImage: GameWindow
+    {
+        private IInputProvider input;
+        private uint textureId;
+
+        public OutputDepthImage(IInputProvider input): base(3 * 320, 3 * 240)
+        {
+            this.input = input;
+        }
+
+        protected override void OnLoad(EventArgs e)
+        {
+            base.OnLoad(e);
+            Title = "OutputTest";
+            GL.ClearColor(Color.Black);
+
+            // transparency
+            GL.Enable(EnableCap.Blend);
+            GL.BlendEquation(BlendEquationMode.Max);
+
+            //Depth Test 
+            GL.Enable(EnableCap.DepthTest);
+
+            // Textures
+            GL.Enable(EnableCap.Texture2D);
+
+            GL.GenTextures(1, out textureId);
+            GL.BindTexture(TextureTarget.Texture2D, textureId);
+            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+        }
+
+        protected override void OnRenderFrame(FrameEventArgs e)
+        {
+            base.OnRenderFrame(e);
+            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
+            Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, -Vector3.UnitZ, Vector3.UnitY);
+            GL.MatrixMode(MatrixMode.Modelview);
+            GL.LoadMatrix(ref modelview);
+
+            input.releaseFrame();
+            input.updateFrame();
+
+            Stopwatch sw = new Stopwatch();
+            sw.Start();
+
+            DepthImage depthImage = input.getDepthImage();
+            depthImage.filterMedian(3);
+
+            Vector palmOrigin = input.getPalmPosition2D(1);
+            int palmX = (int) palmOrigin.x();
+            int palmY = (int) palmOrigin.y();
+            int palmDepth = depthImage.getDepth(palmX, palmY);
+
+            int maxHandSize = 150; // mm Wieviel Pixel sind das?
+            List<Vector> points = new List<Vector>();
+            if (palmX != 0 && palmY != 0)
+            {
+                depthImage.thresholdDepth(palmDepth - 10, palmDepth + 30);
+                depthImage.thresholdPosition(palmX - maxHandSize / 2, palmX + maxHandSize / 2, palmY - maxHandSize / 2, palmY + maxHandSize / 2);
+                points = depthImage.getRectPoints();
+            }
+
+            short[] textureData = new short[3 * depthImage.getWidth() * depthImage.getHeight()];
+            int index = 0;
+            for (int y = 0; y < depthImage.getHeight(); ++y) {
+                for (int x = 0; x < depthImage.getWidth(); ++x) {
+                    // 0 --> 0 / 2000 -> Int16.MaxValue
+                    int d = depthImage.getDepth(x, y);
+                    short depth = (short) (d * Int16.MaxValue / 2000);
+                    textureData[index] = textureData[index + 1] = textureData[index + 2] = depth;
+                    index += 3;
+                }
+            }
+
+            // draw palm origin
+            index = 3 * ((int) palmOrigin.y() * depthImage.getWidth() + (int) palmOrigin.x());
+            textureData[index + 0] = Int16.MaxValue;
+            textureData[index + 1] = 0;
+            textureData[index + 2] = 0;
+
+            // draw rect points
+            foreach (Vector v in points)
+            {
+                int x = (int)v.x() % depthImage.getWidth();
+                int y = (int)v.y() % depthImage.getHeight();
+
+                for (int i = -1; i < 2; ++i)
+                {
+                    for (int j = -1; j < 2; ++j)
+                    {
+                        int px = Math.Min(depthImage.getWidth() - 1, Math.Max(0, x + i));
+                        int py = Math.Min(depthImage.getHeight() - 1, Math.Max(0, y + j));
+                        index = 3 * (py * depthImage.getWidth() + px);
+                        textureData[index + 0] = 0;
+                        textureData[index + 1] = 0;
+                        textureData[index + 2] = Int16.MaxValue;
+            
+                    }
+                }
+            }
+
+            GL.BindTexture(TextureTarget.Texture2D, textureId);
+            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb, depthImage.getWidth(), depthImage.getHeight(), 0,
+                          PixelFormat.Rgb, PixelType.Short, textureData);
+
+            float size_2 = 0.5f / 2.0f;
+            GL.Begin(PrimitiveType.Quads);
+            GL.TexCoord2(0.0, 0.0); GL.Vertex3(-size_2,  size_2, -0.5);
+            GL.TexCoord2(1.0, 0.0); GL.Vertex3( size_2,  size_2, -0.5);
+            GL.TexCoord2(1.0, 1.0); GL.Vertex3( size_2, -size_2, -0.5);
+            GL.TexCoord2(0.0, 1.0); GL.Vertex3(-size_2, -size_2, -0.5);
+            GL.End();
+
+            sw.Stop();
+            Console.WriteLine(sw.ElapsedMilliseconds);
+
+            SwapBuffers();
+        }
+
+        protected override void OnResize(EventArgs e)
+        {
+            base.OnResize(e);
+            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
+            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 3, Width / (float)Height, 0.01f, 3.0f);
+            GL.MatrixMode(MatrixMode.Projection);
+            GL.LoadMatrix(ref projection);
+        }
+    }
+}

+ 1 - 1
bbiwarg/Main/OutputTest.cs

@@ -15,7 +15,7 @@ namespace bbiwarg.Main
             IInputProvider inputProvider = new IisuInputProvider("..\\..\\videos\\1.skv");
             IInputProvider inputProvider = new IisuInputProvider("..\\..\\videos\\1.skv");
             IVideoHandle videoHandle = new VideoHandle(inputProvider);
             IVideoHandle videoHandle = new VideoHandle(inputProvider);
 
 
-            Output output = new Output(videoHandle);
+            OutputDepthImage output = new OutputDepthImage(inputProvider);
             output.Run(30);
             output.Run(30);
         }
         }
     }
     }

+ 19 - 1
bbiwarg/bbiwarg.csproj

@@ -13,7 +13,7 @@
     <FileAlignment>512</FileAlignment>
     <FileAlignment>512</FileAlignment>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <PlatformTarget>x86</PlatformTarget>
     <DebugSymbols>true</DebugSymbols>
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <Optimize>false</Optimize>
@@ -37,6 +37,14 @@
     <StartupObject>bbiwarg.Main.OutputTest</StartupObject>
     <StartupObject>bbiwarg.Main.OutputTest</StartupObject>
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
+    <Reference Include="Emgu.CV, Version=2.4.2.1777, Culture=neutral, PublicKeyToken=7281126722ab4438, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>lib\Emgu.CV.dll</HintPath>
+    </Reference>
+    <Reference Include="Emgu.Util, Version=2.4.2.1777, Culture=neutral, PublicKeyToken=7281126722ab4438, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>lib\Emgu.Util.dll</HintPath>
+    </Reference>
     <Reference Include="iisuNet, Version=3.0.0.0, Culture=neutral, processorArchitecture=x86">
     <Reference Include="iisuNet, Version=3.0.0.0, Culture=neutral, processorArchitecture=x86">
       <SpecificVersion>False</SpecificVersion>
       <SpecificVersion>False</SpecificVersion>
       <HintPath>lib\iisuNet.dll</HintPath>
       <HintPath>lib\iisuNet.dll</HintPath>
@@ -58,6 +66,7 @@
     <Reference Include="System.Xml" />
     <Reference Include="System.Xml" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
+    <Compile Include="DataSource\CollisionDetection.cs" />
     <Compile Include="DataSource\ForeFingerDetection.cs" />
     <Compile Include="DataSource\ForeFingerDetection.cs" />
     <Compile Include="DataSource\IInputProvider.cs" />
     <Compile Include="DataSource\IInputProvider.cs" />
     <Compile Include="DataSource\Palm.cs" />
     <Compile Include="DataSource\Palm.cs" />
@@ -71,6 +80,7 @@
     <Compile Include="DataSource\VectorExtender.cs" />
     <Compile Include="DataSource\VectorExtender.cs" />
     <Compile Include="DataSource\VertexArray.cs" />
     <Compile Include="DataSource\VertexArray.cs" />
     <Compile Include="DataSource\VideoHandle.cs" />
     <Compile Include="DataSource\VideoHandle.cs" />
+    <Compile Include="Graphics\OutputDepthImage.cs" />
     <Compile Include="Graphics\Rectangle.cs" />
     <Compile Include="Graphics\Rectangle.cs" />
     <Compile Include="Graphics\IGraphicElement.cs" />
     <Compile Include="Graphics\IGraphicElement.cs" />
     <Compile Include="Graphics\Point.cs" />
     <Compile Include="Graphics\Point.cs" />
@@ -81,6 +91,14 @@
   <ItemGroup>
   <ItemGroup>
     <None Include="App.config" />
     <None Include="App.config" />
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <Content Include="opencv_core290.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+    <Content Include="opencv_imgproc290.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
        Other similar extension points exist, see Microsoft.Common.targets.

BIN
bbiwarg/lib/Emgu.CV.dll


BIN
bbiwarg/lib/Emgu.Util.dll


BIN
bbiwarg/lib/opencv_core290.dll


BIN
bbiwarg/lib/opencv_imgproc290.dll