FingerDetector.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Drawing;
  7. using Emgu.CV;
  8. using Emgu.CV.Structure;
  9. using bbiwarg.Images;
  10. namespace bbiwarg.Detectors.Fingers
  11. {
  12. class FingerDetector
  13. {
  14. private DepthImage depthImage;
  15. private EdgeImage edgeImage;
  16. private FingerImage fingerImage;
  17. private List<Finger> possibleFingers;
  18. private List<Finger> fingers;
  19. public FingerDetector(DepthImage depthImage, EdgeImage edgeImage, FingerImage fingerImage) {
  20. this.depthImage = depthImage;
  21. this.edgeImage = edgeImage;
  22. this.fingerImage = fingerImage;
  23. findPossibleFingerPoints();
  24. findPossibleFingers();
  25. setFingers();
  26. setFingerPoints();
  27. }
  28. public List<Finger> getFingers() {
  29. return fingers;
  30. }
  31. private void findPossibleFingerPoints()
  32. {
  33. int width = depthImage.getWidth();
  34. int height = depthImage.getHeight();
  35. int maxFingerSize = 30;
  36. int minFingerSize = 10;
  37. for (int y = 0; y < height; y++) {
  38. for (int x = 0; x < width; x++) {
  39. if (edgeImage.isEdgeAt(x,y)) {
  40. //search horizontal
  41. bool edgeRightFound = false;
  42. int edgeRightX = x + minFingerSize;
  43. while (!edgeRightFound && edgeRightX < width) {
  44. if (edgeImage.isEdgeAt(edgeRightX,y))
  45. edgeRightFound = true;
  46. else
  47. edgeRightX++;
  48. }
  49. if (edgeRightFound){
  50. int midX = (edgeRightX + x) / 2;
  51. Int16 depthLeft = depthImage.getDepthAt(x, y);
  52. Int16 depthMid = depthImage.getDepthAt(midX, y);
  53. Int16 depthRight = depthImage.getDepthAt(edgeRightX, y);
  54. if ((edgeRightX - x) < maxFingerSize && depthLeft > depthMid && depthMid < depthRight) {
  55. fingerImage.setFingerAt(midX, y, FingerImageState.possibleFinger);
  56. }
  57. }
  58. //search vertical
  59. bool edgeBottomFound = false;
  60. int edgeBottomY = y + minFingerSize;
  61. while (!edgeBottomFound && edgeBottomY < height) {
  62. if (edgeImage.isEdgeAt(x, edgeBottomY))
  63. edgeBottomFound = true;
  64. else
  65. edgeBottomY++;
  66. }
  67. if (edgeBottomFound) {
  68. int midY = (edgeBottomY + y) / 2;
  69. Int16 depthTop = depthImage.getDepthAt(x, y);
  70. Int16 depthMid = depthImage.getDepthAt(x, midY);
  71. Int16 depthBottom = depthImage.getDepthAt(x, edgeBottomY);
  72. if ((edgeBottomY - y) < maxFingerSize && depthTop > depthMid && depthMid < depthBottom) {
  73. fingerImage.setFingerAt(x, midY, FingerImageState.possibleFinger);
  74. }
  75. }
  76. }
  77. }
  78. }
  79. }
  80. private void findPossibleFingers()
  81. {
  82. int width = depthImage.getWidth();
  83. int height = depthImage.getHeight();
  84. float maxDistanceTogether = 5.0f;
  85. possibleFingers = new List<Finger>();
  86. for (int y = 0; y < height; y++)
  87. {
  88. for (int x = 0; x < width; x++)
  89. {
  90. if (fingerImage.getStateAt(x,y) == FingerImageState.possibleFinger)
  91. {
  92. Int16 depth = depthImage.getDepthAt(x, y);
  93. FingerPoint fingerPoint = new FingerPoint(x,y,depth);
  94. float minDistanceValue = float.MaxValue;
  95. int minDistanceIndex = 0;
  96. for (int i = 0; i < possibleFingers.Count; i++)
  97. {
  98. float distance = possibleFingers[i].getMinDistance(fingerPoint);
  99. if (distance < minDistanceValue)
  100. {
  101. minDistanceValue = distance;
  102. minDistanceIndex = i;
  103. }
  104. }
  105. if (minDistanceValue < maxDistanceTogether)
  106. {
  107. possibleFingers[minDistanceIndex].addFingerPoint(fingerPoint);
  108. }
  109. else
  110. {
  111. possibleFingers.Add(new Finger(fingerPoint));
  112. }
  113. }
  114. }
  115. }
  116. }
  117. private void setFingers()
  118. {
  119. int width = depthImage.getWidth();
  120. int height = depthImage.getHeight();
  121. float minFingerLength = 20.0f;
  122. fingers = new List<Finger>();
  123. foreach (Finger finger in possibleFingers)
  124. {
  125. float length = finger.getLength();
  126. if (length > minFingerLength)
  127. {
  128. fingers.Add(finger);
  129. }
  130. }
  131. }
  132. private void setFingerPoints() {
  133. int width = depthImage.getWidth();
  134. int height = depthImage.getHeight();
  135. foreach (Finger finger in fingers) {
  136. PointF lineEndPoint1 = finger.getLineEndPoint1();
  137. PointF lineEndPoint2 = finger.getLineEndPoint2();
  138. fingerImage.drawLine(lineEndPoint1, lineEndPoint2, FingerImageState.fingerDetected);
  139. }
  140. }
  141. }
  142. }