public void InitializeFingers(HandPoint h) { for (int i = 0; i < fingers.Length; i++) { fingers[i] = new FingerPoint(h); } }
private static bool ParticleGradient(HandFrame handFrame, HandPoint handObj) { int radius = DetectionParameters.radiusFromHandPixel; int imageWidth = handFrame.width; int imageHeight = handFrame.height; int templateWidth = DetectionParameters.dxTemplate.GetLength(1); int templateHeight = DetectionParameters.dxTemplate.GetLength(0); short x = 0; short y = 0; short dx = 6; short dy = (short)(Math.Sqrt(3) * dx / 2); int distanceBetweenParticles = (int)(templateWidth * (0.4)); // Half the width of a "finger" // TO DO: center the particles int numParticles = (imageWidth / dx) * (imageHeight / dy); particle[] particles = new particle[numParticles]; // Initialize particles for (int i = 0; i < particles.Length; i++) { // Set initial x and y //short x = (short)((i * distanceBetweenParticles) % imageWidth); //short y = (short)(distanceBetweenParticles * ((i * distanceBetweenParticles) / imageWidth)); // If the particle is within the depth range, initialize it. if (((handFrame.abs[y, x] > (handObj.Depth - 100)) && (handFrame.abs[y, x] < (handObj.Depth + 100))) && (Math.Sqrt((x - radius) * (x - radius) + (y - radius) * (y - radius)) < (radius - 1))) { particles[i] = new particle((short)(x), (short)(y)); } x += dx; if (x >= imageWidth) { x = 0; y += dy; if (y % 2 == 1) { x += (short)(dx / 2); } } } // run for cycles up to the template width. int iterations = (int)(templateWidth / 2); for (int t = 0; t < iterations; t++) { particle.runTrace(particles, DetectionParameters.dxTemplate, DetectionParameters.dyTemplate, handFrame); } DetectFingers.Detect(particles, handObj, handFrame); return(true); }
public FingerPoint(HandPoint h) { _containging_hand = h; }
public static void Detect(particle[] particles, HandPoint h, HandFrame hf) { int radius = hf.radius; // Initialize an array of particles matching fingers particle[] f = new particle[5]; for (int i = 0; i < f.Length; i++) { f[i] = new particle((short)(radius - 1), (short)(radius - 1)); } if (particles != null) { // for each finger for (int i = 0; i < f.Length; i++) { //h.fingers[i].position_Pixels += 0.1 * h.fingers[i].elapsedMillis * h.fingers[i].velocity_Pixels; //double a = .25; // get the best value for (int j = 0; j < particles.Length; j++) { if (particles[j] != null && particles[j].match_coefficient > f[i].match_coefficient) { f[i].x = particles[j].x; f[i].y = particles[j].y; f[i].z = hf.abs[particles[j].y, particles[j].x]; f[i].match_coefficient = particles[j].match_coefficient; //f[i].matchCoefficient /= (hf.abs[f[i].y, f[i].x] - h.Depth + 100); //f[i].matchCoefficient /= ((1 - a) + a * DetectionParameters.gaussian(Math.Sqrt( // (particles[j].x - (h.fingers[i].X - h.X + radius)) // * (particles[j].x - (h.fingers[i].X - h.X + radius)) // + (particles[j].y - (h.fingers[i].Y - h.Y + radius)) // * (particles[j].y - (h.fingers[i].Y - h.Y + radius))), 10)); } } // remove all particles within the finger area for (int j = 0; j < particles.Length; j++) { // Remove particles within the radius of a finger if (particles[j] != null && Math.Sqrt( (particles[j].x - f[i].x) * (particles[j].x - f[i].x) + (particles[j].y - f[i].y) * (particles[j].y - f[i].y)) <= SIZE_OF_FINGER_PIXELS) //if (particles[j] != null && particles[j].x == f[i].x && particles[j].y == f[i].y) { particles[j] = null; } } // Calculate rotations for the finger SetFingerRotations(f[i], hf.abs[f[i].y, f[i].x], h.angle_from_elbow_degrees, radius); } } Array.Sort(f, Compare); // Sort the 5 fingers clockwise around the hand for (int i = 0; i < h.fingers.Length; i++) { h.fingers[i].updateKalman(new Point3D { X = f[i].x - radius, Y = f[i].y - radius, Z = hf.abs[f[i].y, f[i].x] - h.position_pixels_absolute.Z }); h.fingers[i].angle_from_hand_degrees.X = f[i].angle_from_hand_degrees.X; } }