TouchDetector.cs 3.3 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. using bbiwarg.Detectors.Palm;
  12. using bbiwarg.Utility;
  13. namespace bbiwarg.Detectors.Touch
  14. {
  15. class TouchDetector
  16. {
  17. private DepthImage depthImage;
  18. private TouchImage touchImage;
  19. private List<Finger> fingers;
  20. public List<TouchEvent> TouchEvents {get; private set;}
  21. public TouchDetector(List<Finger> fingers, DepthImage depthImage, TouchImage touchImage) {
  22. this.depthImage = depthImage;
  23. this.touchImage = touchImage;
  24. this.fingers = fingers;
  25. this.TouchEvents = new List<TouchEvent>();
  26. float floodValueThreshold = 0.5f;
  27. foreach (Finger finger in fingers) {
  28. Vector2D tipPoint = finger.Tip;
  29. float floodValue = getFloodValue(tipPoint);
  30. if (floodValue > floodValueThreshold)
  31. {
  32. //correct touchEvent position
  33. Vector2D direction = finger.LineSegment.Line.Direction;
  34. float directionFactor = 10;
  35. float x = HelperFunctions.thresholdRange<float>(0, depthImage.Width - 1, tipPoint.X + directionFactor * direction.X);
  36. float y = HelperFunctions.thresholdRange<float>(0, depthImage.Height - 1, tipPoint.Y + directionFactor * direction.Y);
  37. Vector2D tep = new Vector2D(x,y);
  38. touchImage.setStateAt(tep, TouchImageState.touchDetected);
  39. TouchEvent touchEvent = new TouchEvent(tep, floodValue, finger);
  40. TouchEvents.Add(touchEvent);
  41. }
  42. }
  43. }
  44. private float getFloodValue(Point touchPoint) {
  45. int searchSize = 15;
  46. int maxDepthDifference = 20;
  47. Int16 fingerDiameter = 5;
  48. Int16 depthAtTouch = (Int16) (depthImage.getDepthAt(touchPoint) + fingerDiameter);
  49. int minX = Math.Max(touchPoint.X - searchSize, 0);
  50. int maxX = Math.Min(touchPoint.X + searchSize, depthImage.Width);
  51. int minY = Math.Max(touchPoint.Y - searchSize, 0);
  52. int maxY = Math.Min(touchPoint.Y + searchSize, depthImage.Height);
  53. int matchedPixels = 0;
  54. int countedPixels = 0;
  55. for (int x = minX; x < maxX; x++) {
  56. for (int y = minY; y < maxY; y++) {
  57. Int16 depth = depthImage.getDepthAt(x,y);
  58. touchImage.setStateAt(x, y, TouchImageState.touchArea);
  59. if (Math.Abs(depthAtTouch - depth) < maxDepthDifference) {
  60. matchedPixels++;
  61. touchImage.setStateAt(x, y, TouchImageState.touchAreaMatched);
  62. }
  63. countedPixels++;
  64. }
  65. }
  66. float rel = (float)matchedPixels / (float)countedPixels;
  67. //status bar (% of matched pixels) -> green
  68. for (int x = minX; x < minX + (maxX-minX)*rel; x++) {
  69. touchImage.setStateAt(x, maxY - 1, TouchImageState.touchAreaStatusBar);
  70. }
  71. return rel;
  72. }
  73. }
  74. }