TouchDetector.cs 2.9 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 List<Finger> fingers;
  17. private List<TouchEvent> touchEvents;
  18. public TouchDetector(DepthImage depthImage, List<Finger> fingers) {
  19. this.depthImage = depthImage;
  20. this.fingers = fingers;
  21. this.touchEvents = new List<TouchEvent>();
  22. float touchValueThreshold = 0.5f;
  23. foreach (Finger finger in fingers) {
  24. FingerPoint fp1 = finger.getFarthest();
  25. FingerPoint fp2 = finger.getNearest();
  26. FingerPoint fp;
  27. if (fp1.getY() < fp2.getY())
  28. fp = fp1;
  29. else
  30. fp = fp2;
  31. float touchValue = getTouchValueAt(fp.getX(), fp.getY());
  32. if (touchValue > touchValueThreshold)
  33. {
  34. TouchEvent touchEvent = new TouchEvent(fp.getX(), fp.getY(), touchValue);
  35. touchEvents.Add(touchEvent);
  36. }
  37. }
  38. }
  39. public List<TouchEvent> getTouchEvents() {
  40. return touchEvents;
  41. }
  42. private float getTouchValueAt(int touchX, int touchY) {
  43. int searchSize = 15;
  44. int maxDepthDifference = 20;
  45. Int16 fingerDiameter = 10;
  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. depthImage.setDepthAt(x, y, Int16.MaxValue - 1);//counted pixels -> red
  57. if (Math.Abs(depthAtTouch - depth) < maxDepthDifference) {
  58. matchedPixels++;
  59. depthImage.setDepthAt(x, y, Int16.MaxValue);//matched pixels -> blue
  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. depthImage.setDepthAt(x, maxY-1, Int16.MaxValue-2);
  68. }
  69. return rel;
  70. }
  71. }
  72. }