using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using MathNet.Numerics.LinearAlgebra.Single; using bbiwarg.Graphics; namespace bbiwarg.DataSource { class VideoHandle : IVideoHandle { private IInputProvider inputProvider; private DepthImage depthImage; private ConfidenceImage confidenceImage; private UVImage uvImage; private ColorImage colorImage; private float maxU; private float maxV; public VideoHandle(IInputProvider inputProvider) { this.inputProvider = inputProvider; inputProvider.init(); inputProvider.start(); inputProvider.updateFrame(); createImageData(); maxU = (float)(Math.Tan(inputProvider.getHFOV() / 2f)); maxV = (float)(Math.Tan(inputProvider.getVFOV() / 2f)); } ~VideoHandle() { inputProvider.stop(); } public void nextFrame() { inputProvider.releaseFrame(); inputProvider.updateFrame(); createImageData(); } private void createImageData() { depthImage = inputProvider.getDepthImage(); confidenceImage = inputProvider.getConfidenceImage(); uvImage = inputProvider.getUVImage(); colorImage = inputProvider.getColorImage(); } public short getDepth(int x, int y) { return depthImage.getDepth(x, y); } public short getConfidence(int x, int y) { return confidenceImage.getConfidence(x, y); } public Color getColor(int x, int y) { float u = uvImage.getU(x, y); float v = uvImage.getV(x, y); if (u < 0 || v < 0) return Color.Black; int colorImageWidth = colorImage.getWidth(); int colorImageHeight = colorImage.getHeight(); int xInColorImage = (int)(u * colorImageWidth) % colorImageWidth; int yInColorImage = (int)(v * colorImageHeight) % colorImageHeight; return colorImage.getColor(xInColorImage, yInColorImage); } public Vector getPalmPosition2D(uint handIndex) { //improved palm recognition or just return the value provided by inputprovider return inputProvider.getPalmPosition2D(handIndex); } public Vector getPalmPosition3D(uint handIndex) { //improved palm recognition or just return the value provided by inputprovider return inputProvider.getPalmPosition3D(handIndex); } // TODO public void createVertexArray(IntPtr vertexBuffer) { int width = depthImage.getWidth(); int height = depthImage.getHeight(); int index = 0; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int depth = depthImage.getDepth(x, y); Color c = getColor(x, y); create3DVertexFrom2D(x, y, depth, c, index, vertexBuffer); index++; } } } private void create3DVertexFrom2D(float pixelX, float pixelY, int depth, Color c, int index, IntPtr vertexBuffer) { int width = depthImage.getWidth(); int height = depthImage.getHeight(); float convertedDepth = depth / 1000f; // mm into m float u = (pixelX / (float)width - 0.5f) * 2f; float v = ((1 - pixelY / (float)height) - 0.5f) * 2f; float relX = (u * maxU); float relY = (v * maxV); float z = convertedDepth / (float)Math.Sqrt(1 + relX * relX + relY * relY); float x = relX * z; float y = relY * z; int i4 = (3 * sizeof(float) + 4 * sizeof(byte)) / sizeof(float) * index; int i16 = (3 * sizeof(float) + 4 * sizeof(byte)) * index; unsafe { byte* vertexArrayB = (byte*)vertexBuffer.ToPointer(); float* vertexArrayF = (float*)vertexBuffer.ToPointer(); vertexArrayF[i4 + 0] = x; vertexArrayF[i4 + 1] = y; vertexArrayF[i4 + 2] = -z; vertexArrayB[i16 + 12] = c.R; vertexArrayB[i16 + 13] = c.G; vertexArrayB[i16 + 14] = c.B; vertexArrayB[i16 + 15] = c.A; } } public int getWidth() { return depthImage.getWidth(); } public int getHeight() { return depthImage.getHeight(); } } }