TouchDetector.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using Emgu.CV;
  8. using Emgu.CV.Structure;
  9. using bbiwarg.Images;
  10. using bbiwarg.Detectors.Fingers;
  11. namespace bbiwarg.Detectors.Touch
  12. {
  13. class TouchDetector
  14. {
  15. private DepthImage depthImage;
  16. private TouchImage touchImage;
  17. private List<Finger> fingers;
  18. private List<TouchEvent> touchEvents;
  19. public TouchDetector(List<Finger> fingers, DepthImage depthImage, TouchImage touchImage) {
  20. this.depthImage = depthImage;
  21. this.touchImage = touchImage;
  22. this.fingers = fingers;
  23. this.touchEvents = new List<TouchEvent>();
  24. float floodValueThreshold = 0.5f;
  25. foreach (Finger finger in fingers) {
  26. FingerPoint tipPoint = finger.getTipPoint();
  27. float floodValue = getFloodValue(tipPoint.getX(), tipPoint.getY());
  28. if (floodValue > floodValueThreshold)
  29. {
  30. PointF direction = finger.getDirection();
  31. float directionFactor = -10;
  32. PointF tep = new PointF(Math.Min(Math.Max(tipPoint.getX() + directionFactor*direction.X, 0), depthImage.getWidth()), Math.Min(Math.Max(tipPoint.getY() + directionFactor*direction.Y, 0), depthImage.getHeight()));
  33. touchImage.setTouchAt((int)tep.X, (int)tep.Y, TouchImageState.touchDetected);
  34. TouchEvent touchEvent = new TouchEvent((int)tep.X, (int)tep.Y, floodValue, finger);
  35. touchEvents.Add(touchEvent);
  36. }
  37. }
  38. }
  39. public List<TouchEvent> getTouchEvents() {
  40. return touchEvents;
  41. }
  42. private float getFloodValue(int touchX, int touchY) {
  43. int searchSize = 15;
  44. int maxDepthDifference = 20;
  45. Int16 fingerDiameter = 7;
  46. Int16 depthAtTouch = (Int16) (depthImage.getDepthAt(touchX, touchY) + fingerDiameter);
  47. int minX = Math.Max(touchX - searchSize, 0);
  48. int maxX = Math.Min(touchX + searchSize, depthImage.getWidth());
  49. int minY = Math.Max(touchY - searchSize, 0);
  50. int maxY = Math.Min(touchY + searchSize, depthImage.getHeight());
  51. int matchedPixels = 0;
  52. int countedPixels = 0;
  53. for (int x = minX; x < maxX; x++) {
  54. for (int y = minY; y < maxY; y++) {
  55. Int16 depth = depthImage.getDepthAt(x,y);
  56. touchImage.setTouchAt(x, y, TouchImageState.touchArea);
  57. if (Math.Abs(depthAtTouch - depth) < maxDepthDifference) {
  58. matchedPixels++;
  59. touchImage.setTouchAt(x, y, TouchImageState.touchAreaMatched);
  60. }
  61. countedPixels++;
  62. }
  63. }
  64. float rel = (float)matchedPixels / (float)countedPixels;
  65. //status bar (% of matched pixels) -> green
  66. for (int x = minX; x < minX + (maxX-minX)*rel; x++) {
  67. touchImage.setTouchAt(x, maxY - 1, TouchImageState.touchAreaStatusBar);
  68. }
  69. return rel;
  70. }
  71. }
  72. }