using System; using System.Drawing; using System.Diagnostics; using System.Runtime.InteropServices; using Iisu; using MathNet.Numerics.LinearAlgebra.Single; namespace bbiwarg.InputProviders { class IisuInputProvider : IInputProvider { private IHandle handle; private IDevice device; private string moviePath; private bool active; private bool sourceIsMovie; //parameters private IParameterHandle frameRate; private IParameterHandle hfov; private IParameterHandle vfov; //data private IDataHandle[] handStatus = new IDataHandle[2]; private IDataHandle[] handOpen = new IDataHandle[2]; private IDataHandle[] handSides = new IDataHandle[2]; private IDataHandle[] fingerStatus = new IDataHandle[2]; private IDataHandle[] palmPositions3D = new IDataHandle[2]; private IDataHandle[] palmPositions2D = new IDataHandle[2]; private IDataHandle[] tipPositions3D = new IDataHandle[2]; private IDataHandle[] forearmPositions3D = new IDataHandle[2]; private IDataHandle[] palmNormals3D = new IDataHandle[2]; private IDataHandle[] fingerTipPositions3D = new IDataHandle[2]; private IDataHandle[] fingerTipPositions2D = new IDataHandle[2]; private IDataHandle depthImage; private IDataHandle confidenceImage; private IDataHandle uvImage; private IDataHandle colorImage; public IisuInputProvider(String moviePath = "") { if (moviePath.Length != 0) { this.moviePath = moviePath; sourceIsMovie = true; } else { sourceIsMovie = false; } active = false; } // control-methodes public void init() { handle = Iisu.Iisu.Context.CreateHandle(); IDeviceConfiguration conf = handle.CreateDeviceConfiguration(); if (sourceIsMovie) conf.MoviePath = moviePath; device = handle.InitializeDevice(conf); // parameters if (sourceIsMovie) { //device.RegisterParameterHandle("SOURCE.MOVIE.PlayMode").Value = 0; // playMode = once device.RegisterParameterHandle("SOURCE.MOVIE.PlayMode").Value = 1; // playMode = loop //device.RegisterParameterHandle("SOURCE.MOVIE.PlayMode").Value = 2; // playMode = ping-pong } else { device.RegisterParameterHandle("SOURCE.DEPTHSENSE.AmplitudeThreshold").Value = 100; // confidence-threshhold } frameRate = device.RegisterParameterHandle("SOURCE.FrameRate"); hfov = device.RegisterParameterHandle("SOURCE.CAMERA.DEPTH.HFOV"); vfov = device.RegisterParameterHandle("SOURCE.CAMERA.DEPTH.VFOV"); // events device.EventManager.RegisterEventListener("DEVICE.Status", new Iisu.EventDelegates.Device.Status(onDeviceStatusChanged)); // data handStatus[0] = device.RegisterDataHandle("CI.HAND1.Status"); handStatus[1] = device.RegisterDataHandle("CI.HAND2.Status"); handOpen[0] = device.RegisterDataHandle("CI.HAND1.IsOpen"); handOpen[1] = device.RegisterDataHandle("CI.HAND2.IsOpen"); handSides[0] = device.RegisterDataHandle("CI.HAND1.Side"); handSides[1] = device.RegisterDataHandle("CI.HAND1.Side"); fingerStatus[0] = device.RegisterDataHandle("CI.HAND1.FingerStatus"); fingerStatus[1] = device.RegisterDataHandle("CI.HAND2.FingerStatus"); palmPositions3D[0] = device.RegisterDataHandle("CI.HAND1.PalmPosition3D"); palmPositions3D[1] = device.RegisterDataHandle("CI.HAND2.PalmPosition3D"); palmPositions2D[0] = device.RegisterDataHandle("CI.HAND1.PalmPosition2D"); palmPositions2D[1] = device.RegisterDataHandle("CI.HAND2.PalmPosition2D"); tipPositions3D[0] = device.RegisterDataHandle("CI.HAND1.TipPosition3D"); tipPositions3D[1] = device.RegisterDataHandle("CI.HAND2.TipPosition3D"); forearmPositions3D[0] = device.RegisterDataHandle("CI.HAND1.ForearmPosition3D"); forearmPositions3D[1] = device.RegisterDataHandle("CI.HAND2.ForearmPosition3D"); palmNormals3D[0] = device.RegisterDataHandle("CI.HAND1.PalmNormal3D"); palmNormals3D[1] = device.RegisterDataHandle("CI.HAND2.PalmNormal3D"); fingerTipPositions3D[0] = device.RegisterDataHandle("CI.HAND1.FingerTipPositions3D"); fingerTipPositions3D[1] = device.RegisterDataHandle("CI.HAND2.FingerTipPositions3D"); fingerTipPositions2D[0] = device.RegisterDataHandle("CI.HAND1.FingerTipPositions2D"); fingerTipPositions2D[1] = device.RegisterDataHandle("CI.HAND2.FingerTipPositions2D"); depthImage = device.RegisterDataHandle("SOURCE.CAMERA.DEPTH.Image"); colorImage = device.RegisterDataHandle("SOURCE.CAMERA.COLOR.Image"); confidenceImage = device.RegisterDataHandle("SOURCE.CAMERA.CONFIDENCE.Image"); uvImage = device.RegisterDataHandle("SOURCE.CAMERA.COLOR.REGISTRATION.UV.Image"); } private void onDeviceStatusChanged(string eventName, DeviceStatus status) { active = status.HasFlag(Iisu.DeviceStatus.Playing); } public void start() { device.Start(); } public void stop() { device.Stop(true); } public void updateFrame() { device.UpdateFrame(true); } public void releaseFrame() { device.ReleaseFrame(); } // Parameter-methodes public float getFrameRate() { return frameRate.Value; } public float getHFOV() { return hfov.Value; } public float getVFOV() { return vfov.Value; } public bool isActive() { return active; } // Data-methodes public DetectionStatus getHandStatus(uint handIndex) { checkHandIndex(handIndex); int status = handStatus[handIndex - 1].Value; DetectionStatus result = new DetectionStatus(); switch (status) { case 0: result = DetectionStatus.Inactive; break; case 1: result = DetectionStatus.Detected; break; case 2: result = DetectionStatus.Tracked; break; } return result; } public bool isHandOpen(uint handIndex) { checkHandIndex(handIndex); return handOpen[handIndex - 1].Value; } public HandSide getHandSide(uint handIndex) { checkHandIndex(handIndex); int side = handSides[handIndex - 1].Value; switch (side) { case 1: return HandSide.Left; case 2: return HandSide.Right; default: return HandSide.Unknown; } } public DetectionStatus[] getFingerStatus(uint handIndex) { checkHandIndex(handIndex); int[] status = fingerStatus[handIndex - 1].Value; DetectionStatus[] result = new DetectionStatus[status.Length]; for (int i = 0; i < status.Length; ++i) { switch (status[i]) { case 0: result[i] = DetectionStatus.Inactive; break; case 1: result[i] = DetectionStatus.Detected; break; case 2: result[i] = DetectionStatus.Tracked; break; } } return result; } public Vector getPalmPosition3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(swapXZYtoXYZ(palmPositions3D[handIndex - 1].Value.ToArray())); } public Vector getPalmPosition2D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(palmPositions2D[handIndex - 1].Value.ToArray()); } public Vector getTipPosition3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(swapXZYtoXYZ(tipPositions3D[handIndex - 1].Value.ToArray())); } public Vector getForearmPosition3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(swapXZYtoXYZ(forearmPositions3D[handIndex - 1].Value.ToArray())); } public Vector getPalmNormal3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(swapXZYtoXYZ(palmNormals3D[handIndex - 1].Value.ToArray())); } public Vector[] getFingerTipPositions3D(uint handIndex) { checkHandIndex(handIndex); Iisu.Data.Vector3[] positions = fingerTipPositions3D[handIndex - 1].Value; Vector[] results = new DenseVector[positions.Length]; for (int i = 0; i < positions.Length; ++i) results[i] = new DenseVector(swapXZYtoXYZ(positions[i].ToArray())); return results; } public Vector[] getFingerTipPositions2D(uint handIndex) { checkHandIndex(handIndex); Iisu.Data.Vector2[] positions = fingerTipPositions2D[handIndex - 1].Value; Vector[] results = new DenseVector[positions.Length]; for (int i = 0; i < positions.Length; ++i) results[i] = new DenseVector(positions[i].ToArray()); return results; } public InputFrame getInputFrame() { //depthData Iisu.Data.IImageInfos imageInfos = depthImage.Value.ImageInfos; int width = (int)imageInfos.Width; int height = (int)imageInfos.Height; int numBytes = (int)imageInfos.BytesRaw; IntPtr imageData = depthImage.Value.Raw; short[] depthData = new short[width * height]; Marshal.Copy(imageData, depthData, 0, width * height); //confidenceData imageInfos = confidenceImage.Value.ImageInfos; numBytes = (int)imageInfos.BytesRaw; imageData = confidenceImage.Value.Raw; short[] confidenceData = new short[width * height]; Marshal.Copy(imageData, confidenceData, 0, width * height); //uvData imageInfos = uvImage.Value.ImageInfos; numBytes = (int)imageInfos.BytesRaw; imageData = uvImage.Value.Raw; float[] uvData = new float[2 * width * height]; Marshal.Copy(imageData, uvData, 0, 2 * width * height); //colorData imageInfos = colorImage.Value.ImageInfos; int widthRawColor = (int)imageInfos.Width; int heightRawColor = (int)imageInfos.Height; numBytes = (int)imageInfos.BytesRaw; imageData = colorImage.Value.Raw; byte[] colorData = new byte[numBytes]; Marshal.Copy(imageData, colorData, 0, numBytes); return new InputFrame(width, height, widthRawColor, heightRawColor, depthData, confidenceData, uvData, colorData); } // other private void checkHandIndex(uint handIndex) { if (handIndex < 1 || handIndex > 2) throw new ArgumentOutOfRangeException("handIndex is out of range [0,1]"); } private float[] swapXZYtoXYZ(float[] vector) { float dummy = vector[1]; vector[1] = vector[2]; vector[2] = dummy; return vector; } } }